appflinger

package module
v0.0.0-...-c7c4871 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2021 License: AGPL-3.0 Imports: 18 Imported by: 0

README

appflinger-go

This is the official Go client SDK for AppFlinger (www.appflinger.com). A full reference documentation of the SDK is available at: https://godoc.org/github.com/tversity/appflinger-go.

There is also a C client SDK (available in binary form), a Javascript client SDK, and a C# client SDK, as well as a full client implementation for the Raspberry Pi (please contact TVersity for more information).

The server side code is closed source and is available for licensing from TVersity.

What is AppFlinger?

AppFlinger (www.appflinger.com) is a cloud browser, i.e. it is an HTML5 browser (based on Chromium) running in the cloud and delivered to client devices as a video or image stream.

AppFlinger is a server side technology that can be deployed in the cloud or on-premise and be utilized for delivering a consistent HTML5 content experience to any device, in a hardware agnostic manner.

AppFlinger physically isolates edge devices and edge networks from the content they are rendering, thus enabling next generation security while delivering on the promise of any content on any device.

AppFlinger Uniqueness

AppFlinger is unique in its ability to deliver desktop grade HTML5 browser experience to any networked device with a video player, while requiring very low bandwidth and CPU on the server.

Documentation

Overview

This package implements the AppFlinger client SDK.

It supports the following:

  • Start/stop a session
  • Inject input to a session
  • Control channel implementation using HTTP long polling
  • UI video streaming and demuxing

The client needs to implement the AppFlingerListener interface in order to process the control channel commands. An example is available under examples/stub.go which is just a stub implementation of the AppFlingerListener interface. This stub is used by examples/main.go, which illustrates how to use the client SDK. It starts a session, and injects input in a loop until interrupted by the user, at which point the session is stopped.

The full code for the SDK along with the examples is available under: https://github.com/tversity/appflinger-go.

Index

Constants

View Source
const (
	// Network state constants (used by the getNetworkState() control channel command)
	NETWORK_STATE_EMPTY         = 0
	NETWORK_STATE_IDLE          = 1
	NETWORK_STATE_LOADING       = 2
	NETWORK_STATE_LOADED        = 3
	NETWORK_STATE_FORMAT_ERROR  = 4
	NETWORK_STATE_NETWORK_ERROR = 5
	NETWORK_STATE_DECODE_ERROR  = 6

	// Ready state constants  (used by the getReadykState() control channel command)
	READY_STATE_HAVE_NOTHING      = 0
	READY_STATE_HAVE_METADATA     = 1
	READY_STATE_HAVE_CURRENT_DATA = 2
	READY_STATE_HAVE_FUTURE_DATA  = 3
	READY_STATE_HAVE_ENOUGH_DATA  = 4

	// Keyboard codes for injecting events
	KEY_UP        = 0x26
	KEY_DOWN      = 0x28
	KEY_LEFT      = 0x25
	KEY_RIGHT     = 0x27
	KEY_ENTER     = 0xd
	KEY_BACKSPACE = 0x8
	KEY_ESCAPE    = 0x1b

	// Media formats supported for UI stream
	UI_FMT_TS_H264  = "mp2t;h264"
	UI_FMT_MP4_H264 = "mp4;h264"
	UI_FMT_MP4_AV1  = "mp4;av1"
	UI_FMT_WEBM_VP8 = "webm;vp8"
	UI_FMT_WEBM_VP9 = "webm;vp9"
	UI_FMT_MPD_TS   = "mpd;mp2"
	UI_FMT_MPD_MP4  = "mpd;mp4"
	UI_FMT_MPD_WEBM = "mpd;webm"
	UI_FMT_JPEG     = "jpeg"
	UI_FMT_PNG      = "png"

	// MSE AppendMode enum
	MSE_APPEND_MODE_SEGMENTS = 0
	MSE_APPEND_MODE_SEQUENCE = 1

	// EME MediaKeysRequirement enum
	EME_MEDIA_KEYS_REQUIRED    = "required"
	EME_MEDIA_KEYS_OPTIONAL    = "optional"
	EME_MEDIA_KEYS_NOT_ALLOWED = "not-allowed"

	// EME MediaKeySessionType enum
	EME_MEDIA_KEYS_SESSION_TEMPORARY          = "temporary"
	EME_MEDIA_KEYS_SESSION_PERSISTENT_LICENSE = "persistent-license"
)

Variables

View Source
var (
	ErrInterrupted = errors.New("Aborting due to interrupt")
)

Functions

func NotificationCreateCdmSessionKeyStatusesChange

func NotificationCreateCdmSessionKeyStatusesChange(payload []byte) []byte

func NotificationCreateCdmSessionMessage

func NotificationCreateCdmSessionMessage(messageType string, payload []byte) []byte

func NotificationCreateEncrypted

func NotificationCreateEncrypted(initDataType string, payload []byte) []byte

func NotificationCreateVideoStateChange

func NotificationCreateVideoStateChange(readyState int, networkState int, paused bool, seeking bool,
	duration float64, time float64, videoWidth int, videoHeight int) ([]byte, error)

func SessionGetSessionId

func SessionGetSessionId(ctx *SessionContext) (sessionId string, err error)

func SessionGetUIURL

func SessionGetUIURL(ctx *SessionContext, fmt string, tsDiscon bool, bitrate int) (uri string, err error)

SessionGetUIURL is used to obtain the HTTP URL from which the browser UI can be streamed. Note that one should also consider the cookies for that URL before making the HTTP request.

func SessionGetURLCookies

func SessionGetURLCookies(ctx *SessionContext, uri string) (cookies []*http.Cookie, err error)

SessionGetURLCookies is used to obtain the required cookies for a given URL, this can be important for load balancing

func SessionSendEvent

func SessionSendEvent(ctx *SessionContext, eventType string, code int, char rune, mod int, x int, y int) (err error)

SessionSendEvent is used to inject input into a session.

func SessionSendNotification

func SessionSendNotification(ctx *SessionContext, instanceId string, payload []byte) (err error)

func SessionSendNotificationVideoStateChange

func SessionSendNotificationVideoStateChange(ctx *SessionContext, instanceId string, readyState int,
	networkState int, paused bool, seeking bool, duration float64, time float64, videoWidth int, videoHeight int) (err error)

func SessionStop

func SessionStop(ctx *SessionContext) (err error)

SessionStop is used to stop a session.

func SessionUIStreamStart

func SessionUIStreamStart(ctx *SessionContext, format string, tsDiscon bool, bitrate int) (err error)

SessionUIStreamStart is used to start streaming the UI, frames will be passed to OnUIFrame() in the AppFlinger listener

func SessionUIStreamStop

func SessionUIStreamStop(ctx *SessionContext) (err error)

SessionUIStreamStop is used to stop streaming the UI

Types

type AppflingerListener

type AppflingerListener interface {
	Load(sessionId string, instanceId string, url string) (err error)
	CancelLoad(sessionId string, instanceId string) (err error)
	Pause(sessionId string, instanceId string) (err error)
	Play(sessionId string, instanceId string) (err error)
	Seek(sessionId string, instanceId string, time float64) (err error)
	GetPaused(sessionId string, instanceId string) (paused bool, err error)
	GetSeeking(sessionId string, instanceId string) (seeking bool, err error)
	GetDuration(sessionId string, instanceId string) (duration float64, err error)
	GetCurrentTime(sessionId string, instanceId string) (time float64, err error)
	GetNetworkState(sessionId string, instanceId string) (networkState int, err error)
	GetReadyState(sessionId string, instanceId string) (readyState int, err error)
	GetSeekable(sessionId string, instanceId string, result *GetSeekableResult) (err error)
	GetBuffered(sessionId string, instanceId string, result *GetBufferedResult) (err error)
	SetRect(sessionId string, instanceId string, x int, y int, width int, height int) (err error)
	SetVisible(sessionId string, instanceId string, visible bool) (err error)
	SetRate(sessionId string, instanceId string, rate float64) (err error)
	SetVolume(sessionId string, instanceId string, volume float64) (err error)

	AddSourceBuffer(sessionId string, instanceId string, sourceId string, mimeType string) (err error)
	RemoveSourceBuffer(sessionId string, instanceId string, sourceId string) (err error)
	AbortSourceBuffer(sessionId string, instanceId string, sourceId string) (err error)
	AppendBuffer(sessionId string, instanceId string, sourceId string, appendWindowStart float64, appendWindowEnd float64, bufferId string, bufferOffset int,
		bufferLength int, payload []byte, result *GetBufferedResult) (err error)
	SetAppendMode(sessionId string, instanceId string, sourceId string, mode int) (err error)
	SetAppendTimestampOffset(sessionId string, instanceId string, sourceId string, timestampOffset float64) (err error)
	RemoveBufferRange(sessionId string, instanceId string, sourceId string, start float64, end float64) (err error)
	ChangeSourceBufferType(sessionId string, instanceId string, sourceId string, mimeType string) (err error)

	// TODO what about cancelLoadResource()? We need to make LoadResource cancellable
	LoadResource(sessionId string, url string, method string, headers string, resourceId string, byteRangeStart int, byteRangeEnd int,
		sequenceNumber int, payload []byte, result *LoadResourceResult) (err error)
	DeleteResource(sessionId string, BufferId string) (err error)

	// Control Channel functions - EME related
	// Note that eventInstanceId is for sending events which are associated with a given CDM session. It is serves
	// the same purpose as cdmSessionId but is needed before cdmSessionId exists.
	// TODO maybe get rid of cdmSessionId and just rename eventInstanceId to cdmSessionId
	// The instanceId used above and in SetCdm() is different, it is the instance of the media player (more than one may exist)
	RequestKeySystem(sessionId string, keySystem string, supportedConfigurations []EMEMediaKeySystemConfiguration, result *RequestKeySystemResult) (err error)
	CdmCreate(sessionId string, keySystem string, securityOrigin string, allowDistinctiveIdentifier bool, allowPersistentState bool) (cdmId string, err error)
	CdmSetServerCertificate(sessionId string, cdmId string, payload []byte) (err error)
	CdmSessionCreate(sessionId string, eventInstanceId string, cdmId string, sessionType string, initDataType string, payload []byte) (cdmSessionId string, expiration float64, err error)
	CdmSessionUpdate(sessionId string, eventInstanceId string, cdmId string, cdmSessionId string, payload []byte) (err error)
	CdmSessionLoad(sessionId string, eventInstanceId string, cdmId string, cdmSessionId string) (loaded bool, expiration float64, err error)
	CdmSessionRemove(sessionId string, eventInstanceId string, cdmId string, cdmSessionId string) (err error)
	CdmSessionClose(sessionId string, eventInstanceId string, cdmId string, cdmSessionId string) (err error)
	SetCdm(sessionId string, instanceId string, cdmId string) (err error)

	SendMessage(sessionId string, message string) (result string, err error)
	OnPageLoad(sessionId string) (err error)
	OnAddressBarChanged(sessionId string, url string) (err error)
	OnTitleChanged(sessionId string, title string) (err error)
	OnPageClose(sessionId string) (err error)

	OnUIFrame(sessionId string, isCodecConfig bool, isKeyFrame bool, idx int, pts int, dts int, data []byte) (err error)
}

AppflingerListener is the interface a client needs to implement in order to process the control channel commands. An example is available under examples/stub.go. The "AppFlinger API and Client Integration Guide" describes the control channel operation and its various commands in detail.

type EMEMediaKeySystemConfiguration

type EMEMediaKeySystemConfiguration struct {
	Label                 string                             `json:"label"`
	InitDataTypes         []string                           `json:"initDataTypes"`
	AudioCapabilities     []EMEMediaKeySystemMediaCapability `json:"audioCapabilities"`
	VideoCapabilities     []EMEMediaKeySystemMediaCapability `json:"videoCapabilities"`
	DistinctiveIdentifier string                             `json:"distinctiveIdentifier"` // One of EME_MEDIA_KEYS_REQUIRED, EME_MEDIA_KEYS_OPTIONAL, EME_MEDIA_KEYS_NOT_ALLOWED
	PersistentState       string                             `json:"persistentState"`       // One of EME_MEDIA_KEYS_REQUIRED, EME_MEDIA_KEYS_OPTIONAL, EME_MEDIA_KEYS_NOT_ALLOWED
	SessionTypes          []string                           `json:"sessionTypes"`          // Array values are one of EME_MEDIA_KEYS_SESSION_TEMPORARY, EME_MEDIA_KEYS_SESSION_PERSISTENT_LICENSE
}

MediaKeySystemConfiguration as per EME spec

type EMEMediaKeySystemMediaCapability

type EMEMediaKeySystemMediaCapability struct {
	ContentType string `json:"contentType"`
	Robustness  string `json:"robustness"`
}

MediaKeySystemMediaCapability as per EME spec

type GetBufferedResult

type GetBufferedResult TimeIntervalArrays

type GetSeekableResult

type GetSeekableResult TimeIntervalArrays

type LoadResourceResult

type LoadResourceResult struct {
	Code         string
	Headers      string
	BufferId     string
	BufferLength int
	Payload      []byte
}

LoadResourceResult is the returned result by LoadResource() in the AppflingerListener interface

type RequestKeySystemResult

type RequestKeySystemResult EMEMediaKeySystemConfiguration

RequestKeySystemResult is the returned result by RequestKeySystem()

type SessionContext

type SessionContext struct {
	SessionId string

	CookieJar          *cookiejar.Jar
	ServerProtocolHost string
	// contains filtered or unexported fields
}

SessionContext is returned when starting a session and needs to be passed to subsequent operations on the session.

func SessionGetSessionContext

func SessionGetSessionContext(sessionId string) (ctx *SessionContext, err error)

func SessionStart

func SessionStart(serverProtocolHost string, sessionId string, browserURL string, pullMode bool, isVideoPassthru bool, browserUIOutputURL string,
	videoStreamURL string, width int, height int, appf AppflingerListener) (ctx *SessionContext, err error)

SessionStart is used to start a new session or navigate an existing one to a new address. The arguments to this function are as per the description of the /osb/session/start API in the "AppFlinger API and Client Integration Guide".

type TimeIntervalArrays

type TimeIntervalArrays struct {
	Start []float64
	End   []float64
}

TimeIntervalArrays is the returned result by GetBuffered() and GetSeekable() in the AppflingerListener interface

func (*TimeIntervalArrays) GetEnd

func (result *TimeIntervalArrays) GetEnd(index int) float64

func (*TimeIntervalArrays) GetLength

func (result *TimeIntervalArrays) GetLength() int

func (*TimeIntervalArrays) GetStart

func (result *TimeIntervalArrays) GetStart(index int) float64

func (*TimeIntervalArrays) SetEnd

func (result *TimeIntervalArrays) SetEnd(index int, value float64)

func (*TimeIntervalArrays) SetLength

func (result *TimeIntervalArrays) SetLength(length int)

func (*TimeIntervalArrays) SetStart

func (result *TimeIntervalArrays) SetStart(index int, value float64)

type VideoStateChangeNotifcation

type VideoStateChangeNotifcation struct {
	Type         string  `json:"type"` // "videostatechange"
	ReadyState   int     `json:"readyState"`
	NetworkState int     `json:"networkState"`
	Paused       string  `json:"paused"`
	Seeking      string  `json:"seeking"`
	Duration     float64 `json:"duration"`
	Time         float64 `json:"time"`
	VideoWidth   int     `json:"videoWidth"`
	VideoHeight  int     `json:"videoHeight"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL