import "pkg:/source/utils/misc.bs"
sub init()
m.inactivityTimer = m.top.findNode("inactivityTimer")
m.endsAtTimer = m.top.findNode("endsAtTimer")
m.endsAt = m.top.findNode("endsAt")
m.videoLogo = m.top.findNode("videoLogo")
m.videoOfficialRating = m.top.findNode("videoOfficialRating")
m.videoTitle = m.top.findNode("videoTitle")
m.videoSubtitleGroup = m.top.findNode("videoSubtitleGroup")
m.videoPlayPause = m.top.findNode("videoPlayPause")
m.videoPositionTime = m.top.findNode("videoPositionTime")
m.videoRemainingTime = m.top.findNode("videoRemainingTime")
m.progressBar = m.top.findNode("progressBar")
m.progressBarBackground = m.top.findNode("progressBarBackground")
m.top.observeField("json", "setFields")
m.top.observeField("visible", "onVisibleChanged")
m.top.observeField("hasFocus", "onFocusChanged")
m.top.observeField("progressPercentage", "onProgressPercentageChanged")
m.top.observeField("playbackState", "onPlaybackStateChanged")
m.defaultButtonIndex = 1
m.focusedButtonIndex = 1
m.subtitleDividerCount = 0
m.buttonMenuRight = m.top.findNode("buttonMenuRight")
m.buttonMenuLeft = m.top.findNode("buttonMenuLeft")
m.buttonMenuLeft.buttonFocused = m.defaultButtonIndex
m.buttonMenuLeft.getChild(m.defaultButtonIndex).focus = true
end sub
' setFields: Grab data from json metadata and save it to local fields
sub setFields()
if not isValid(m.top.json) or m.top.json = "" then return
videoData = parseJson(m.top.json)
mediaStreams = videoData.MediaStreams
m.top.json = ""
if videoData.Type <> invalid
m.top.type = videoData.Type
end if
if videoData.logoImage <> invalid and videoData.logoImage <> ""
m.top.videoLogo = videoData.logoImage
end if
if videoData.Name <> invalid
m.top.videoTitle = videoData.Name
end if
if videoData.Overview <> invalid
m.top.overview = videoData.Overview
end if
if videoData.SeriesStudio <> invalid
m.top.seriesStudio = videoData.SeriesStudio
end if
if videoData.HasSubtitles <> invalid
m.top.hasSubtitles = videoData.HasSubtitles
end if
if videoData.Chapters <> invalid and videoData.Chapters.Count() > 0
m.top.hasChapters = true
end if
if videoData.SeriesName <> invalid
m.top.seriesName = videoData.SeriesName
end if
if videoData.ParentIndexNumber <> invalid
m.top.seasonNumber = videoData.ParentIndexNumber
end if
if videoData.IndexNumber <> invalid
m.top.episodeNumber = videoData.IndexNumber
end if
if videoData.IndexNumberEnd <> invalid
m.top.episodeNumberEnd = videoData.IndexNumberEnd
end if
if videoData.CommunityRating <> invalid
m.top.communityRating = videoData.CommunityRating
end if
if videoData.OfficialRating <> invalid
m.top.officialRating = videoData.OfficialRating
end if
if videoData.PremiereDate <> invalid
m.top.premiereDate = videoData.PremiereDate
end if
if videoData.RunTimeTicks <> invalid
m.top.runTimeTicks = videoData.RunTimeTicks
m.top.runTimeMinutes = ticksToMinutes(m.top.runTimeTicks)
end if
if videoData.ProductionYear <> invalid
m.top.productionYear = videoData.ProductionYear
end if
numVideoStreams = 0
numAudioStreams = 0
for each stream in mediaStreams
if stream.Type = "Video"
numVideoStreams++
else if stream.Type = "Audio"
numAudioStreams++
end if
end for
m.top.numVideoStreams = numVideoStreams
m.top.numAudioStreams = numAudioStreams
setButtonStates()
populateData()
end sub
sub populateData()
setVideoLogoGroup()
setVideoTitle()
setVideoSubTitle()
end sub
' setButtonStates: Disable previous/next buttons if needed and remove any other unneeded buttons
sub setButtonStates()
queueCount = m.global.QueueManager.callFunc("getCount")
queueIndex = m.global.QueueManager.callFunc("getPosition")
' Disable these buttons as needed
' Item Previous
if queueCount = 1 or queueIndex = 0
itemPrevious = m.buttonMenuLeft.findNode("itemBack")
itemPrevious.enabled = false
end if
' Item Next
if queueIndex + 1 >= queueCount
itemNext = m.buttonMenuLeft.findNode("itemNext")
itemNext.enabled = false
end if
' Remove these buttons as needed
' Audio Track
if m.top.numAudioStreams < 2
m.buttonMenuLeft.removeChild(m.buttonMenuLeft.findNode("showAudioMenu"))
end if
' Subtitles
if not m.top.hasSubtitles
m.buttonMenuLeft.removeChild(m.buttonMenuLeft.findNode("showSubtitleMenu"))
end if
' Chapters
if not m.top.hasChapters
m.buttonMenuLeft.removeChild(m.buttonMenuLeft.findNode("chapterList"))
end if
end sub
sub setEndsAtText()
date = CreateObject("roDateTime")
endTime = int(m.top.remainingPositionTime)
date.fromSeconds(date.asSeconds() + endTime)
date.toLocalTime()
m.endsAt.text = tr("Ends at") + " " + formatTime(date)
end sub
sub setVideoLogoGroup()
m.videoLogo.uri = m.top.videoLogo
' if m.top.officialRating <> invalid and m.top.officialRating <> ""
' m.videoOfficialRating.text = m.top.officialRating
' end if
end sub
sub setVideoTitle()
m.videoTitle.text = m.top.videoTitle
end sub
sub setVideoSubTitle()
' start fresh by removing all subtitle nodes
m.videoSubtitleGroup.removeChildrenIndex(m.videoSubtitleGroup.getChildCount(), 0)
airDateNodeCreated = false
' EPISODE
if m.top.type <> invalid
if m.top.Type = "Episode" or m.top.Type = "Recording"
' Title
if m.top.seriesName <> ""
m.videoTitle.text = m.top.seriesName
end if
' episodeInfo
episodeInfoText = ""
'
' Season number
if m.top.seasonNumber <> invalid
episodeInfoText = episodeInfoText + `${tr("S")}${m.top.seasonNumber}`
else
episodeInfoText = episodeInfoText + `${tr("S")}?`
end if
' Episode number
if m.top.episodeNumber <> invalid
episodeInfoText = episodeInfoText + `:${tr("E")}${m.top.episodeNumber}`
else
episodeInfoText = episodeInfoText + `:${tr("E")}??`
end if
' Episode number end
if m.top.episodeNumberEnd <> invalid and m.top.episodeNumberEnd <> 0 and m.top.episodeNumberEnd > m.top.episodeNumber
' add entry for every episode eg. S6:E1E2
for i = m.top.episodeNumber + 1 to m.top.episodeNumberEnd
episodeInfoText = episodeInfoText + `${tr("E")}${m.top.episodeNumberEnd}`
end for
end if
' Episode name
if m.top.videoTitle <> invalid and m.top.videoTitle <> ""
episodeInfoText = episodeInfoText + ` - ${m.top.videoTitle}`
end if
if episodeInfoText <> ""
episodeInfoNode = createSubtitleLabelNode("episodeInfo")
episodeInfoNode.text = episodeInfoText
displaySubtitleNode(episodeInfoNode)
end if
else if m.top.type = "Movie"
' videoAirDate
if m.top.premiereDate <> invalid and m.top.premiereDate <> ""
airDateNodeCreated = true
premiereDateNode = createSubtitleLabelNode("videoAirDate")
premiereDateNode.text = formatIsoDateVideo(m.top.premiereDate)
displaySubtitleNode(premiereDateNode)
end if
end if
end if
' append these to all video types
'
' videoAirDate if needed
if not airDateNodeCreated and m.top.premiereDate <> invalid and m.top.premiereDate <> ""
premiereDateNode = createSubtitleLabelNode("videoAirDate")
premiereDateNode.text = formatIsoDateVideo(m.top.premiereDate)
displaySubtitleNode(premiereDateNode)
end if
' videoRunTime
if m.top.runTimeMinutes <> invalid and m.top.runTimeMinutes <> 0
runTimeNode = createSubtitleLabelNode("videoRunTime")
if m.top.runTimeMinutes < 2
runTimeText = `${m.top.runTimeMinutes} ` + tr("min")
else
runTimeText = `${m.top.runTimeMinutes} ` + tr("mins")
end if
runTimeNode.text = runTimeText
displaySubtitleNode(runTimeNode)
end if
end sub
sub onProgressPercentageChanged()
m.videoPositionTime.text = secondsToTimestamp(m.top.positionTime, true)
m.videoRemainingTime.text = "-" + secondsToTimestamp(m.top.remainingPositionTime, true)
m.progressBar.width = m.progressBarBackground.width * m.top.progressPercentage
setEndsAtText()
end sub
sub onPlaybackStateChanged()
if LCase(m.top.playbackState) = "playing"
m.videoPlayPause.icon = "pkg:/images/icons/pause.png"
return
end if
m.videoPlayPause.icon = "pkg:/images/icons/play.png"
end sub
sub resetFocusToDefaultButton()
' Remove focus from previously selected button
for each child in m.buttonMenuLeft.getChildren(-1, 0)
if isValid(child.focus)
child.focus = false
end if
end for
for each child in m.buttonMenuRight.getChildren(-1, 0)
if isValid(child.focus)
child.focus = false
end if
end for
' Set focus back to the default button
m.buttonMenuLeft.setFocus(true)
m.focusedButtonIndex = m.defaultButtonIndex
m.buttonMenuLeft.getChild(m.defaultButtonIndex).focus = true
m.buttonMenuLeft.buttonFocused = m.defaultButtonIndex
end sub
sub onVisibleChanged()
if m.top.visible
resetFocusToDefaultButton()
m.endsAtTimer.observeField("fire", "setEndsAtText")
m.endsAtTimer.control = "start"
if m.top.playbackState <> "paused"
m.inactivityTimer.observeField("fire", "inactiveCheck")
m.inactivityTimer.control = "start"
end if
else
m.inactivityTimer.control = "stop"
m.endsAtTimer.control = "stop"
m.inactivityTimer.unobserveField("fire")
m.endsAtTimer.unobserveField("fire")
end if
end sub
sub onFocusChanged()
if m.top.hasfocus
m.buttonMenuLeft.setFocus(true)
end if
end sub
' inactiveCheck: Checks if the time since last keypress is greater than or equal to the allowed inactive time of the menu.
sub inactiveCheck()
' If user is currently seeing a dialog box, ignore inactive check
if m.global.sceneManager.callFunc("isDialogOpen")
return
end if
deviceInfo = CreateObject("roDeviceInfo")
if deviceInfo.timeSinceLastKeypress() >= m.top.inactiveTimeout
m.top.action = "hide"
end if
end sub
sub onButtonSelected()
if m.buttonMenuLeft.isInFocusChain()
selectedButton = m.buttonMenuLeft.getChild(m.buttonMenuLeft.buttonFocused)
else if m.buttonMenuRight.isInFocusChain()
selectedButton = m.buttonMenuRight.getChild(m.buttonMenuRight.buttonFocused)
else
return
end if
if LCase(selectedButton.id) = "chapterlist"
m.top.showChapterList = not m.top.showChapterList
end if
m.top.action = selectedButton.id
end sub
function createSubtitleLabelNode(labelId as string) as object
labelNode = CreateObject("roSGNode", "LabelPrimaryMedium")
labelNode.id = labelId
labelNode.horizAlign = "left"
labelNode.vertAlign = "center"
labelNode.width = 0
labelNode.height = 0
labelNode.bold = true
return labelNode
end function
function createSubtitleDividerNode() as object
m.subtitleDividerCount++
labelNode = CreateObject("roSGNode", "LabelPrimarySmall")
labelNode.id = "divider" + m.subtitleDividerCount.toStr()
labelNode.horizAlign = "left"
labelNode.vertAlign = "center"
labelNode.width = 0
labelNode.height = 40
labelNode.text = "•"
labelNode.bold = true
return labelNode
end function
sub displaySubtitleNode(node as object)
if not isValid(node) then return
subtitleChildrenCount = m.videoSubtitleGroup.getChildCount()
if subtitleChildrenCount > 0
' add a divider
dividerNode = createSubtitleDividerNode()
m.videoSubtitleGroup.appendChild(dividerNode)
end if
m.videoSubtitleGroup.appendChild(node)
end sub
function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if key = "play"
m.top.action = "videoplaypause"
return true
end if
if key = "OK"
onButtonSelected()
return true
end if
if key = "back" and m.top.visible
m.top.action = "hide"
return true
end if
return false
end function