Skip to content

Commit b259704

Browse files
committed
Update code docs
1 parent 6f9b71f commit b259704

9 files changed

Lines changed: 82 additions & 47 deletions

docs/components_ItemGrid_LoadVideoContentTask.bs.html

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
id = m.top.itemId
4848
mediaSourceId = invalid
4949
audio_stream_idx = m.top.selectedAudioStreamIndex
50-
forceTranscoding = false
50+
forceTranscoding = m.top.forceTranscoding
5151
bypassDoviPreservation = m.top.bypassDoviPreservation
5252

5353
m.top.content = [LoadItems_VideoPlayer(id, mediaSourceId, audio_stream_idx, forceTranscoding, bypassDoviPreservation)]
@@ -221,7 +221,7 @@
221221
if meta.live then mediaSourceId = ""
222222

223223
' Call ItemPostPlaybackInfo ONCE with final subtitle_idx
224-
m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition, meta, bypassDoviPreservation)
224+
m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition, meta, bypassDoviPreservation, forceTranscoding)
225225
if not isValid(m.playbackInfo)
226226
video.errorMsg = "Error loading playback info"
227227
video.content = invalid
@@ -301,6 +301,7 @@
301301
if video.directPlaySupported
302302
video.isTranscoded = false
303303
setupVideoContentWithAuth(video, mediaSourceId, audio_stream_idx)
304+
applyLiveDirectPlayFallback(video, meta)
304305
else
305306
if not isValid(m.playbackInfo.MediaSources[0].TranscodingUrl)
306307
' If server does not provide a transcode URL, display a message to the user
@@ -425,20 +426,6 @@
425426
video.fullSubtitleData = safesubs
426427
end sub
427428

428-
'
429-
' Extract array of Transcode Reasons from the content URL
430-
' @returns Array of Strings
431-
function getTranscodeReasons(url as string) as object
432-
433-
regex = CreateObject("roRegex", "&TranscodeReasons=([^&]*)", "")
434-
match = regex.Match(url)
435-
436-
if match.count() > 1
437-
return match[1].Split(",")
438-
end if
439-
440-
return []
441-
end function
442429

443430
function directPlaySupported(meta as object) as boolean
444431
devinfo = CreateObject("roDeviceInfo")

docs/components_video_VideoPlayerView.bs.html

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,11 @@
542542
m.top.showID = videoContent[0].showID
543543
m.top.cachedPlaybackInfo = videoContent[0].playbackInfo
544544
m.top.doviDirectPlayFallbackAvailable = isValid(videoContent[0].doviDirectPlayFallbackAvailable) and videoContent[0].doviDirectPlayFallbackAvailable
545+
m.top.transcodeAvailable = isValid(videoContent[0].transcodeAvailable) and videoContent[0].transcodeAvailable
545546

546-
' Reset bypass flag so subsequent reloads (audio/subtitle changes) re-evaluate DoVi naturally.
547-
' It will be set back to true by the error handler if another buffer overflow occurs.
547+
' Reset retry flags so subsequent reloads (audio/subtitle changes) use fresh evaluation.
548548
m.LoadMetaDataTask.bypassDoviPreservation = false
549+
m.LoadMetaDataTask.forceTranscoding = false
549550

550551
if isValidAndNotEmpty(videoContent[0].json)
551552
m.osd.json = formatJson(videoContent[0].json)
@@ -879,6 +880,24 @@
879880
end if
880881
end sub
881882

883+
' retryPlayback: Re-runs the content loader from the current position with updated task flags.
884+
' Used by error handlers to retry without exiting the player.
885+
' @param {boolean} bypassDovi - skips DoVi container profile so the server can grant direct play
886+
' @param {boolean} forceTranscode - disables direct play so the server returns a transcode URL
887+
sub retryPlayback(bypassDovi as boolean, forceTranscode as boolean)
888+
m.global.queueManager.callFunc("setTopStartingPoint", int(m.top.position) * 10000000&)
889+
' Prevents ViewCreator popping the scene when stop causes Roku to fire "finished".
890+
m.top.isRetrying = true
891+
m.top.control = "stop"
892+
m.LoadMetaDataTask.bypassDoviPreservation = bypassDovi
893+
m.LoadMetaDataTask.forceTranscoding = forceTranscode
894+
m.LoadMetaDataTask.selectedSubtitleIndex = m.top.SelectedSubtitle
895+
m.LoadMetaDataTask.selectedAudioStreamIndex = m.top.audioIndex
896+
m.LoadMetaDataTask.itemId = m.currentItem.id
897+
m.LoadMetaDataTask.observeField("content", "onVideoContentLoaded")
898+
m.LoadMetaDataTask.control = "RUN"
899+
end sub
900+
882901
'
883902
' When Video Player state changes
884903
sub onState()
@@ -909,19 +928,11 @@
909928
if isBufferLoopError and m.top.doviDirectPlayFallbackAvailable
910929
m.log.warn("Buffer overflow in DoVi transcode; falling back to direct play", m.currentItem.id)
911930
m.top.doviDirectPlayFallbackAvailable = false ' prevent retry loop if direct play also fails
912-
m.global.queueManager.callFunc("setTopStartingPoint", int(m.top.position) * 10000000&)
913-
' Prevents ViewCreator popping the scene when stop causes Roku to fire "finished".
914-
m.top.isRetrying = true
915-
m.top.control = "stop"
916-
m.LoadMetaDataTask.bypassDoviPreservation = true
917-
m.LoadMetaDataTask.selectedSubtitleIndex = m.top.SelectedSubtitle
918-
m.LoadMetaDataTask.selectedAudioStreamIndex = m.top.audioIndex
919-
m.LoadMetaDataTask.itemId = m.currentItem.id
920-
m.LoadMetaDataTask.observeField("content", "onVideoContentLoaded")
921-
m.LoadMetaDataTask.control = "RUN"
931+
retryPlayback(true, false)
922932
else if not m.playReported and m.top.transcodeAvailable
923-
m.log.info("retrying with transcoding", m.currentItem.id, m.top.SelectedSubtitle, m.top.audioIndex)
924-
m.top.retryWithTranscoding = true ' If playback was not reported, retry with transcoding
933+
m.log.warn("Direct play failed; falling back to transcode", m.currentItem.id)
934+
m.top.transcodeAvailable = false ' prevent retry loop if transcode also fails
935+
retryPlayback(false, true)
925936
else
926937
' If an error was encountered, stop timers and display dialog
927938
m.top.unobserveField("state")

docs/data/search.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/module-Items.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/module-LoadVideoContentTask.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/module-VideoPlayerView.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/module-streamSelection.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/source_api_Items.bs.html

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import "pkg:/source/utils/deviceCapabilities.bs"
77
import "pkg:/source/utils/misc.bs"
88

9-
function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = SubtitleSelection.none as integer, startTimeTicks = 0& as longinteger, videoMetadata = invalid as dynamic, bypassDoviPreservation = false as boolean)
9+
function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = SubtitleSelection.none as integer, startTimeTicks = 0& as longinteger, videoMetadata = invalid as dynamic, bypassDoviPreservation = false as boolean, forceTranscoding = false as boolean)
1010
globalUser = m.global.user
1111
postData = {
1212
"UserId": globalUser.id,
@@ -61,17 +61,7 @@
6161
postData.SubtitleStreamIndex = subtitleTrackIndex
6262
end if
6363

64-
' Note: Jellyfin v10.9+ now remuxs LiveTV and does not allow DirectPlay anymore.
65-
' Because of this, we need to tell the server "EnableDirectPlay = false" so that we receive the
66-
' transcoding URL (which is just a remux and not a transcode; unless it is)
67-
' The web handles this by disabling EnableDirectPlay on a Retry, but we don't currently Retry a Live
68-
' TV stream, thus we just turn it off on the first try here.
69-
if mediaSourceId <> ""
70-
postData.MediaSourceId = mediaSourceId
71-
else
72-
' No mediaSourceId? Must be LiveTV...
73-
postData.EnableDirectPlay = false
74-
end if
64+
applyMediaSourceToPostData(postData, mediaSourceId, forceTranscoding)
7565

7666
mediaStreams = invalid
7767
if isValid(videoMetadata) and isValid(videoMetadata.json) and isValid(videoMetadata.json.MediaStreams)
@@ -694,6 +684,24 @@
694684
return { Items: results }
695685
end function
696686

687+
' applyMediaSourceToPostData: Applies the media source ID or live TV retry flags to a postData object.
688+
' Live TV is detected by an empty mediaSourceId. On the first attempt, direct play is not disabled
689+
' so the server can evaluate compatibility (matching web client behaviour). On retry,
690+
' forceTranscoding=true sets EnableDirectPlay=false so the server provides a transcode URL instead.
691+
'
692+
' @param {object} postData - The request body assoc array to modify
693+
' @param {string} mediaSourceId - Media source ID, or "" for live TV
694+
' @param {boolean} forceTranscoding - True when retrying with forced transcoding
695+
sub applyMediaSourceToPostData(postData as object, mediaSourceId as string, forceTranscoding as boolean)
696+
if mediaSourceId <> ""
697+
postData.MediaSourceId = mediaSourceId
698+
else
699+
if forceTranscoding
700+
postData.EnableDirectPlay = false
701+
end if
702+
end if
703+
end sub
704+
697705
' Removes AAC from the device profile codec list to prevent stereo downmix of multichannel audio.
698706
' Also handles unsupported AAC profiles (Main, HE-AAC).
699707
' For stereo sources (≤2ch), also removes surround passthrough codecs (eac3, ac3, dts)

docs/source_utils_streamSelection.bs.html

Lines changed: 29 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)