Allow attempting to direct play video with invalid profile level

This commit is contained in:
Neil Burrows 2022-07-04 10:09:16 +01:00
parent c6e294afff
commit 055c4e5021
7 changed files with 51 additions and 14 deletions

View File

@ -21,14 +21,18 @@ sub onState(msg)
m.bufferCheckTimer.control = "start"
m.bufferCheckTimer.ObserveField("fire", "bufferCheck")
else if m.top.state = "error"
' If an error was encountered, Display dialog
dialog = createObject("roSGNode", "Dialog")
dialog.title = tr("Error During Playback")
dialog.buttons = [tr("OK")]
dialog.message = tr("An error was encountered while playing this item.")
dialog.observeField("buttonSelected", "dialogClosed")
m.top.getScene().dialog = dialog
if m.playReported or NOT m.top.retryWithTranscoding
m.top.retryWithTranscoding = false ' If playback was reported, don't retry with transcoding
' If an error was encountered, Display dialog
dialog = createObject("roSGNode", "Dialog")
dialog.title = tr("Error During Playback")
dialog.buttons = [tr("OK")]
dialog.message = tr("An error was encountered while playing this item.")
dialog.observeField("buttonSelected", "dialogClosed")
m.top.getScene().dialog = dialog
end if
' Stop playback and exit player
m.top.control = "stop"
m.top.backPressed = true

View File

@ -13,6 +13,7 @@
<field id="showID" type="string" />
<field id="transcodeParams" type="assocarray" />
<field id="retryWithTranscoding" type="boolean" value="false" />
<field id="isTranscoded" type="boolean" />
<field id="transcodeReasons" type="array" />

View File

@ -9,6 +9,13 @@
"settingName": "playback.mpeg2",
"type": "bool",
"default": "false"
},
{
"title": "Attempt Direct Play (Profile Lvl)",
"description": "Attempt Direct Play for h264 media with unsupported profile levels (> 4.2) before falling back to trancoding if it fails.",
"settingName": "playback.tryDirect.h264ProfileLevel",
"type": "bool",
"default": "true"
}
]
},

View File

@ -343,7 +343,15 @@ sub Main (args as dynamic) as void
node = msg.getRoSGNode()
if node.state = "finished"
node.control = "stop"
if node.showID = invalid
' If node allows retrying using Transcode Url, give that shot
if node.retryWithTranscoding
retryVideo = CreateVideoPlayerGroup(node.Id, invalid, node.audioIndex, true)
m.global.sceneManager.callFunc("popScene")
if retryVideo <> invalid
m.global.sceneManager.callFunc("pushScene", retryVideo)
end if
else if node.showID = invalid
sceneManager.callFunc("popScene")
else
autoPlayNextEpisode(node.id, node.showID)

View File

@ -455,9 +455,9 @@ sub CreateSidePanel(buttons, options)
group.options = options
end sub
function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1)
function CreateVideoPlayerGroup(video_id, mediaSourceId = invalid, audio_stream_idx = 1, forceTranscoding = false)
' Video is Playing
video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id))
video = VideoPlayer(video_id, mediaSourceId, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), forceTranscoding)
if video = invalid then return invalid
video.observeField("selectSubtitlePressed", m.port)
video.observeField("state", m.port)

View File

@ -1,9 +1,9 @@
function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1)
function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1, forceTranscoding = false)
' Get video controls and UI
video = CreateObject("roSGNode", "JFVideo")
video.id = id
AddVideoContent(video, mediaSourceId, audio_stream_idx, subtitle_idx)
AddVideoContent(video, mediaSourceId, audio_stream_idx, subtitle_idx, -1, forceTranscoding)
if video.content = invalid
return invalid
@ -16,7 +16,7 @@ function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle
return video
end function
sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -1, playbackPosition = -1)
sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -1, playbackPosition = -1, forceTranscoding = false)
video.content = createObject("RoSGNode", "ContentNode")
meta = ItemMetaData(video.id)
@ -187,6 +187,22 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
video.directPlaySupported = playbackInfo.MediaSources[0].SupportsDirectPlay
fully_external = false
' For h264 video, Roku spec states that it supports and Encoding level 4.1 and 4.2.
' The device can decode content with a Higher Encoding level but may play it back with certain
' artifacts. If the user preference is set, and the only reason the server says we need to
' transcode is that the Envoding Level is not supported, then try to direct play but silently
' fall back to the transcode if that fails.
video.retryWithTranscoding = false
if get_user_setting("playback.tryDirect.h264ProfileLevel") = "true" and playbackInfo.MediaSources[0].TranscodingUrl <> invalid and forceTranscoding = false and playbackInfo.MediaSources[0].MediaStreams[0].codec = "h264"
transcodingReasons = getTranscodeReasons(playbackInfo.MediaSources[0].TranscodingUrl)
if transcodingReasons.Count() = 1 and transcodingReasons[0] = "VideoLevelNotSupported"
video.directPlaySupported = true
video.retryWithTranscoding = true
end if
end if
if video.directPlaySupported
protocol = LCase(playbackInfo.MediaSources[0].Protocol)
if protocol <> "file"

View File

@ -91,7 +91,8 @@ function getDeviceProfile() as object
"Protocol": "hls",
"MaxAudioChannels": StrI(maxAudioChannels), ' Currently Jellyfin server expects this as a string
"MinSegments": "1",
"BreakOnNonKeyFrames": true
"BreakOnNonKeyFrames": true,
' "VideoLevel": "42"
},
{
"Container": "mp4",