Interfaces

UpstreamManifestRequest

Methods

(static) directPlayStreamFormat(mediaSource, isLive) → {string}

The Video content StreamFormat for a direct play of this source: the manifest's own format, so the player never has to guess it from the URL. A live source whose format cannot be read keeps "hls", which every live direct play was given before formats were told apart; none has been seen.

Parameters:
NameTypeDescription
mediaSourcedynamic

the played PlaybackInfo MediaSource

isLiveboolean

the source is a live channel

Returns:

"hls", "dash", or "" to leave StreamFormat unset

Type: 
string

(static) getUpstreamManifestBlocker(mediaSource, request) → {string}

What keeps a source off its own HLS or DASH manifest URL, or UpstreamManifestBlocker.NONE when nothing does: the device then checks it can load that URL (LoadVideoContentTask .upstreamManifestAnswers) and plays it directly.

Jellyfin 12.0 stopped offering direct play for any source whose container is a manifest (StreamBuilder.ManifestContainers: hls, applehttp, dash; and M3UTunerHost for a channel URL with a manifest extension, jellyfin/jellyfin#17768). It had been relaying the manifest through its own /Videos/{id}/ URL, where the manifest's relative URIs 404. JellyRock never used that relay. It plays the absolute upstream Path (setupVideoContentWithAuth), where relative URIs resolve against the origin, which is how Live TV channels and .strm items played before 12.0. The server's replacement is a remux or a full transcode: it drops audio that arrives as a separate HLS rendition, and loads the server for a stream the device can play itself. If the device cannot play the upstream stream after all, the transcode retry (isTranscodeAvailable) asks the server.

The server's "no" does not say whether 12.0 is its only reason, so this rebuilds the answer the server would have given before 12.0 from what the client can see. A source qualifies when the server answered at all, its Protocol is HTTP, its Path is an absolute http(s) manifest URL that does not go through Jellyfin (not a loopback host, not the server's own host and port, not the LiveStreamFiles relay), and none of the server's older reasons applies: the tuner's "Auto-loop live streams", the user's remote-source transcoding policy, or the server's internet streaming bitrate limit. The tuner's "Simultaneous stream limit" is the one reason the client cannot see; the server still enforces it when the live stream opens.

A server "yes" qualifies too, so the device checks a URL the server allowed as well: a Roku handed a URL it cannot reach buffers rather than failing, which ends in an error where the server's own stream would have played.

Parameters:
NameTypeDescription
mediaSourcedynamic

the source's PlaybackInfo MediaSource

requestUpstreamManifestRequest

what this load asked for, and of whom

Returns:

an UpstreamManifestBlocker value

Type: 
string

(static) isHlsPlaylistResponse(responseCode, body) → {boolean}

Whether a response is HTTP 200 with an HLS playlist body. The body check turns away a captive portal or an HTML error page served with 200; RFC 8216 requires #EXTM3U as the first line, so only leading whitespace is tolerated before it.

Parameters:
NameTypeDescription
responseCodeinteger

roUrlEvent.GetResponseCode() (negative for a transport failure)

bodydynamic

roUrlEvent.GetString()

Returns:
Type: 
boolean

(static) isMpdResponse(responseCode, body) → {boolean}

Whether a response is HTTP 200 with a DASH manifest body: well-formed XML whose root element is MPD (ISO/IEC 23009-1). Parsing rather than matching a prefix lets an XML declaration, comments or a namespace prefix come first, and still turns away a captive portal's HTML.

Parameters:
NameTypeDescription
responseCodeinteger

roUrlEvent.GetResponseCode() (negative for a transport failure)

bodydynamic

roUrlEvent.GetString()

Returns:
Type: 
boolean

(static) isUpstreamManifestResponse(format, responseCode, body) → {boolean}

Whether a response to the device check of an upstream manifest URL shows the device can play it, for the manifest format the source declared (upstreamManifestFormat).

Parameters:
NameTypeDescription
formatstring

"hls" or "dash"

responseCodeinteger

roUrlEvent.GetResponseCode() (negative for a transport failure)

bodydynamic

roUrlEvent.GetString()

Returns:
Type: 
boolean

(static) upstreamManifestFormat(mediaSource) → {string}

The manifest format of a source, from the container the server reports or, when that names no manifest, the extension of its URL path (a query string cannot hide it).

Parameters:
NameTypeDescription
mediaSourcedynamic

a PlaybackInfo MediaSource

Returns:

"hls", "dash", or "" for anything else

Type: 
string