mirror of
https://github.com/jellyfin/jellyfin-roku.git
synced 2024-11-23 14:19:40 +00:00
Add preroll video support (#644)
This commit is contained in:
parent
72eff657db
commit
f5412fd192
@ -9,6 +9,7 @@ end sub
|
||||
' Push a new group onto the stack, replacing the existing group on the screen
|
||||
sub pushScene(newGroup)
|
||||
currentGroup = m.groups.peek()
|
||||
|
||||
if currentGroup <> invalid
|
||||
'Search through group and store off last focused item
|
||||
if currentGroup.focusedChild <> invalid
|
||||
@ -16,10 +17,10 @@ sub pushScene(newGroup)
|
||||
while focused.hasFocus() = false
|
||||
focused = focused.focusedChild
|
||||
end while
|
||||
|
||||
currentGroup.lastFocus = focused
|
||||
currentGroup.setFocus(false)
|
||||
else
|
||||
currentGroup.lastFocus = invalid
|
||||
currentGroup.setFocus(false)
|
||||
end if
|
||||
|
||||
@ -104,12 +105,15 @@ sub popScene()
|
||||
if group.isSubType("JFScreen")
|
||||
group.callFunc("OnScreenShown")
|
||||
else
|
||||
|
||||
' Restore focus
|
||||
if group.lastFocus <> invalid
|
||||
group.lastFocus.setFocus(true)
|
||||
else
|
||||
group.setFocus(true)
|
||||
if group.focusedChild <> invalid
|
||||
group.focusedChild.setFocus(true)
|
||||
else
|
||||
group.setFocus(true)
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
else
|
||||
@ -134,6 +138,12 @@ sub clearScenes()
|
||||
m.groups = []
|
||||
end sub
|
||||
|
||||
'
|
||||
' Clear previous scene from group stack
|
||||
sub clearPreviousScene()
|
||||
m.groups.pop()
|
||||
end sub
|
||||
|
||||
'
|
||||
' Display user/device settings screen
|
||||
sub settings()
|
||||
|
@ -6,6 +6,7 @@
|
||||
<function name="settings" />
|
||||
<function name="getActiveScene" />
|
||||
<function name="clearScenes" />
|
||||
<function name="clearPreviousScene" />
|
||||
<function name="resetTime" />
|
||||
<function name="userMessage" />
|
||||
<field id="currentUser" type="string" onChange="updateUser" />
|
||||
|
@ -656,5 +656,15 @@
|
||||
<translation>Use generated splashscreen image as Jellyfin home background. Jellyfin will need to be closed and reopened for change to take effect.</translation>
|
||||
<extracomment>Description for option in Setting Screen</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema mode</source>
|
||||
<translation>Cinema mode</translation>
|
||||
<extracomment>Settings Menu - Title for option</extracomment>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</source>
|
||||
<translation>Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.</translation>
|
||||
<extracomment>Settings Menu - Description for option</extracomment>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -9,6 +9,13 @@
|
||||
"settingName": "playback.mpeg2",
|
||||
"type": "bool",
|
||||
"default": "false"
|
||||
},
|
||||
{
|
||||
"title": "Cinema mode",
|
||||
"description": "Cinema mode brings the theater experience straight to your living room with the ability to play custom intros before the main feature.",
|
||||
"settingName": "playback.cinemamode",
|
||||
"type": "bool",
|
||||
"default": "false"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -63,7 +63,7 @@ sub Main (args as dynamic) as void
|
||||
if (args.mediaType <> invalid) and (args.contentId <> invalid)
|
||||
video = CreateVideoPlayerGroup(args.contentId)
|
||||
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
else
|
||||
dialog = createObject("roSGNode", "Dialog")
|
||||
@ -104,7 +104,7 @@ sub Main (args as dynamic) as void
|
||||
else
|
||||
video = CreateVideoPlayerGroup(itemNode.id)
|
||||
end if
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
end if
|
||||
end if
|
||||
@ -123,7 +123,7 @@ sub Main (args as dynamic) as void
|
||||
else
|
||||
video = CreateVideoPlayerGroup(video_id)
|
||||
end if
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
end if
|
||||
else if selectedItem.type = "Series"
|
||||
@ -145,7 +145,7 @@ sub Main (args as dynamic) as void
|
||||
video = CreateVideoPlayerGroup(video_id)
|
||||
dialog.close = true
|
||||
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
else
|
||||
dialog = createObject("roSGNode", "Dialog")
|
||||
@ -217,7 +217,7 @@ sub Main (args as dynamic) as void
|
||||
else
|
||||
video = CreateVideoPlayerGroup(video_id)
|
||||
end if
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
end if
|
||||
else if isNodeEvent(msg, "search_value")
|
||||
@ -263,7 +263,7 @@ sub Main (args as dynamic) as void
|
||||
video_id = group.id
|
||||
|
||||
video = CreateVideoPlayerGroup(video_id, mediaSourceId, audio_stream_idx)
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
end if
|
||||
|
||||
@ -375,7 +375,7 @@ sub Main (args as dynamic) as void
|
||||
info = msg.GetInfo()
|
||||
if info.DoesExist("mediatype") and info.DoesExist("contentid")
|
||||
video = CreateVideoPlayerGroup(info.contentId)
|
||||
if video <> invalid
|
||||
if video <> invalid and video.errorMsg <> "introaborted"
|
||||
sceneManager.callFunc("pushScene", video)
|
||||
else
|
||||
dialog = createObject("roSGNode", "Dialog")
|
||||
|
@ -455,10 +455,12 @@ 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, showIntro = true)
|
||||
|
||||
' 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), showIntro)
|
||||
if video = invalid then return invalid
|
||||
if video.errorMsg = "introaborted" then return video
|
||||
video.observeField("selectSubtitlePressed", m.port)
|
||||
video.observeField("state", m.port)
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1)
|
||||
|
||||
function VideoPlayer(id, mediaSourceId = invalid, audio_stream_idx = 1, subtitle_idx = -1, showIntro = true)
|
||||
' 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, showIntro)
|
||||
|
||||
if video.errorMsg = "introaborted"
|
||||
return video
|
||||
end if
|
||||
|
||||
if video.content = invalid
|
||||
return invalid
|
||||
@ -16,7 +19,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, showIntro = true)
|
||||
|
||||
video.content = createObject("RoSGNode", "ContentNode")
|
||||
meta = ItemMetaData(video.id)
|
||||
@ -140,6 +143,16 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
||||
end if
|
||||
end if
|
||||
|
||||
' Don't attempt to play an intro for an intro video
|
||||
if showIntro
|
||||
' Do not play intros when resuming playback
|
||||
if playbackPosition = 0
|
||||
if not PlayIntroVideo(video.id, audio_stream_idx)
|
||||
video.errorMsg = "introaborted"
|
||||
return
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
video.content.PlayStart = int(playbackPosition / 10000000)
|
||||
|
||||
@ -170,6 +183,10 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
||||
|
||||
video.container = getContainerType(meta)
|
||||
|
||||
if playbackInfo.MediaSources[0] = invalid
|
||||
playbackInfo = meta.json
|
||||
end if
|
||||
|
||||
subtitles = sortSubtitles(meta.id, playbackInfo.MediaSources[0].MediaStreams)
|
||||
video.Subtitles = subtitles["all"]
|
||||
|
||||
@ -244,6 +261,43 @@ sub AddVideoContent(video, mediaSourceId, audio_stream_idx = 1, subtitle_idx = -
|
||||
|
||||
end sub
|
||||
|
||||
function PlayIntroVideo(video_id, audio_stream_idx) as boolean
|
||||
' Intro videos only play if user has cinema mode setting enabled
|
||||
if get_user_setting("playback.cinemamode") = "true"
|
||||
|
||||
' Check if server has intro videos setup and available
|
||||
introVideos = GetIntroVideos(video_id)
|
||||
|
||||
if introVideos = invalid then return true
|
||||
|
||||
if introVideos.TotalRecordCount > 0
|
||||
' Bypass joke pre-roll
|
||||
if lcase(introVideos.items[0].name) = "rick roll'd" then return true
|
||||
|
||||
introVideo = VideoPlayer(introVideos.items[0].id, introVideos.items[0].id, audio_stream_idx, defaultSubtitleTrackFromVid(video_id), false)
|
||||
|
||||
port = CreateObject("roMessagePort")
|
||||
introVideo.observeField("state", port)
|
||||
m.global.sceneManager.callFunc("pushScene", introVideo)
|
||||
introPlaying = true
|
||||
|
||||
while introPlaying
|
||||
msg = wait(0, port)
|
||||
if type(msg) = "roSGNodeEvent"
|
||||
if msg.GetData() = "finished"
|
||||
m.global.sceneManager.callFunc("clearPreviousScene")
|
||||
introPlaying = false
|
||||
else if msg.GetData() = "stopped"
|
||||
introPlaying = false
|
||||
return false
|
||||
end if
|
||||
end if
|
||||
end while
|
||||
end if
|
||||
end if
|
||||
return true
|
||||
end function
|
||||
|
||||
'
|
||||
' Extract array of Transcode Reasons from the content URL
|
||||
' @returns Array of Strings
|
||||
@ -345,7 +399,7 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
|
||||
' remove finished video node
|
||||
m.global.sceneManager.callFunc("popScene")
|
||||
' setup new video node
|
||||
nextVideo = CreateVideoPlayerGroup(data.Items[1].Id)
|
||||
nextVideo = CreateVideoPlayerGroup(data.Items[1].Id, invalid, 1, false)
|
||||
if nextVideo <> invalid
|
||||
m.global.sceneManager.callFunc("pushScene", nextVideo)
|
||||
else
|
||||
|
@ -220,6 +220,16 @@ function CreateInstantMix(id as string)
|
||||
return getJson(resp)
|
||||
end function
|
||||
|
||||
' Get Intro Videos for an item
|
||||
function GetIntroVideos(id as string)
|
||||
url = Substitute("Users/{0}/Items/{1}/Intros", get_setting("active_user"), id)
|
||||
resp = APIRequest(url, {
|
||||
"UserId": get_setting("active_user")
|
||||
})
|
||||
|
||||
return getJson(resp)
|
||||
end function
|
||||
|
||||
function AudioStream(id as string)
|
||||
songData = AudioItem(id)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user