Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logo and season/episode numbers to OSD #1672

Merged
merged 4 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions components/ItemGrid/LoadVideoContentTask.bs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,27 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s
end if
end if

video.chapters = meta.json.Chapters
video.content.title = meta.title
video.showID = meta.showID

logoLookupID = video.id

if videotype = "episode" or videotype = "series"
video.content.contenttype = "episode"
video.seasonNumber = meta.json.ParentIndexNumber
video.episodeNumber = meta.json.IndexNumber
video.episodeNumberEnd = meta.json.IndexNumberEnd

if isValid(meta.showID)
logoLookupID = meta.showID
end if
end if

video.chapters = meta.json.Chapters
video.content.title = meta.title
video.showID = meta.showID
logoImageExists = api.items.HeadImageURLByName(logoLookupID, "logo")
if logoImageExists
video.logoImage = api.items.GetImageURL(logoLookupID, "logo", 0, { "maxHeight": 65, "maxWidth": 300, "quality": "90" })
end if

user = AboutMe()
if user.Configuration.EnableNextEpisodeAutoPlay
Expand Down
96 changes: 96 additions & 0 deletions components/video/OSD.bs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import "pkg:/source/utils/misc.bs"

const LOGO_RIGHT_PADDING = 30
const OPTIONCONTROLS_TOP_PADDING = 50

sub init()
m.videoControls = m.top.findNode("videoControls")
m.optionControls = m.top.findNode("optionControls")

m.inactivityTimer = m.top.findNode("inactivityTimer")
m.videoInfo = m.top.findNode("videoInfo")
m.itemTitle = m.top.findNode("itemTitle")
m.videoPlayPause = m.top.findNode("videoPlayPause")
m.videoPositionTime = m.top.findNode("videoPositionTime")
Expand All @@ -16,10 +20,16 @@ sub init()
m.top.observeField("hasFocus", "onFocusChanged")
m.top.observeField("progressPercentage", "onProgressPercentageChanged")
m.top.observeField("playbackState", "onPlaybackStateChanged")

m.top.observeField("itemTitleText", "onItemTitleTextChanged")
m.top.observeField("seasonNumber", "onSeasonNumberChanged")
m.top.observeField("episodeNumber", "onEpisodeNumberChanged")
m.top.observeField("episodeNumberEnd", "onEpisodeNumberEndChanged")
m.top.observeField("logoImage", "onLogoImageChanged")

m.defaultButtonIndex = 2
m.focusedButtonIndex = 2
m.optionControlsMoved = false

m.videoControls.buttonFocused = m.defaultButtonIndex
m.optionControls.buttonFocused = m.optionControls.getChildCount() - 1
Expand Down Expand Up @@ -53,6 +63,92 @@ sub onItemTitleTextChanged()
m.itemTitle.text = m.top.itemTitleText
end sub

' onSeasonNumberChanged: Handler for changes to m.top.seasonNumber param.
'
sub onSeasonNumberChanged()
m.top.unobserveField("seasonNumber")
itemSeason = m.top.findNode("itemSeason")
itemSeason.font.size = 32
itemSeason.text = `S${m.top.seasonNumber}`

' Move the option controls down to give room for season number
if not m.optionControlsMoved
moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING)
m.optionControlsMoved = true
end if
end sub

' onEpisodeNumberChanged: Handler for changes to m.top.episodeNumber param.
'
sub onEpisodeNumberChanged()
m.top.unobserveField("episodeNumber")
itemEpisode = m.top.findNode("itemEpisode")
itemEpisode.font.size = 32
itemEpisode.text = `E${m.top.episodeNumber}`

' Move the option controls down to give room for episode number
if not m.optionControlsMoved
moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING)
m.optionControlsMoved = true
end if
end sub

' onEpisodeNumberEndChanged: Handler for changes to m.top.episodeNumberEnd param.
'
sub onEpisodeNumberEndChanged()
m.top.unobserveField("episodeNumberEnd")
itemEpisodeEnd = m.top.findNode("itemEpisodeEnd")
itemEpisodeEnd.font.size = 32
itemEpisodeEnd.text = `-${m.top.episodeNumberEnd}`

' Move the option controls down to give room for episode number
if not m.optionControlsMoved
moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING)
m.optionControlsMoved = true
end if
end sub

' moveOptionControls: Moves option controls node based on passed pixel values
'
' @param {integer} horizontalPixels - Number of horizontal pixels to move option controls
' @param {integer} verticalPixels - Number of vertical pixels to move option controls
sub moveOptionControls(horizontalPixels as integer, verticalPixels as integer)
m.optionControls.translation = `[${m.optionControls.translation[0] + horizontalPixels}, ${m.optionControls.translation[1] + verticalPixels}]`
end sub

' onLogoLoadStatusChanged: Handler for changes to logo image's status.
'
' @param {dynamic} event - field change event
sub onLogoLoadStatusChanged(event)
if LCase(event.GetData()) = "ready"
logoImage = event.getRoSGNode()
logoImage.unobserveField("loadStatus")

' Move video info to the right based on the logo width
m.videoInfo.translation = `[${m.videoInfo.translation[0] + logoImage.bitmapWidth + LOGO_RIGHT_PADDING}, ${m.videoInfo.translation[1]}]`
m.itemTitle.maxWidth = m.itemTitle.maxWidth - (logoImage.bitmapWidth + LOGO_RIGHT_PADDING)

' Move the option controls down based on the logo height
if not m.optionControlsMoved
moveOptionControls(0, OPTIONCONTROLS_TOP_PADDING)
m.optionControlsMoved = true
end if
end if
end sub

' onLogoImageChanged: Handler for changes to m.top.logoImage param.
'
sub onLogoImageChanged()
if isValidAndNotEmpty(m.top.logoImage)
logoImage = createObject("roSGNode", "Poster")
logoImage.Id = "logoImage"
logoImage.observeField("loadStatus", "onLogoLoadStatusChanged")
logoImage.uri = m.top.logoImage
logoImage.translation = [103, 61]
m.top.appendChild(logoImage)
end if
end sub

' resetFocusToDefaultButton: Reset focus back to the default button
'
sub resetFocusToDefaultButton()
Expand Down
16 changes: 15 additions & 1 deletion components/video/OSD.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<component name="OSD" extends="Group" initialFocus="chapterNext">
<children>
<ScrollingLabel id="itemTitle" font="font:LargeBoldSystemFont" translation="[103,61]" maxWidth="1400" />
<Poster uri="pkg:/images/osdBackground.png" width="1920" height="279" />

<LayoutGroup id="videoInfo" layoutDirection="vert" translation="[103,61]">
<ScrollingLabel id="itemTitle" font="font:LargeBoldSystemFont" maxWidth="1400" />
<LayoutGroup id="videoInfo" layoutDirection="horiz" translation="[103,61]">
<Label id="itemSeason" font="font:MediumSystemFont" color="0xffffffFF" />
<Label id="itemEpisode" font="font:MediumSystemFont" color="0xffffffFF" />
<Label id="itemEpisodeEnd" font="font:MediumSystemFont" color="0xffffffFF" />
</LayoutGroup>
</LayoutGroup>

<Clock id="clock" translation="[1618, 46]" />

<ButtonGroup id="optionControls" itemSpacings="[20]" layoutDirection="horiz" horizAlignment="left" translation="[103,120]">
Expand Down Expand Up @@ -30,6 +40,10 @@
</children>
<interface>
<field id="itemTitleText" type="string" />
<field id="seasonNumber" type="integer" />
<field id="episodeNumber" type="integer" />
<field id="episodeNumberEnd" type="integer" />
<field id="logoImage" type="string" />
<field id="inactiveTimeout" type="integer" />
<field id="progressPercentage" type="float" />
<field id="positionTime" type="float" />
Expand Down
25 changes: 25 additions & 0 deletions components/video/VideoPlayerView.bs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,31 @@ sub onVideoContentLoaded()

m.osd.itemTitleText = m.top.content.title

' If video is an episode, attempt to add season and episode numbers to OSD
if m.top.content.contenttype = 4
if isValid(videoContent[0].seasonNumber)
m.osd.seasonNumber = videoContent[0].seasonNumber
end if

if isValid(videoContent[0].episodeNumber)
m.osd.episodeNumber = videoContent[0].episodeNumber
end if

if isValid(videoContent[0].episodeNumberEnd)
m.osd.episodeNumberEnd = videoContent[0].episodeNumberEnd
end if
end if

' Attempt to add logo to OSD
if isValidAndNotEmpty(videoContent[0].logoImage)
m.osd.logoImage = videoContent[0].logoImage

' Don't show both the logo and the video title if this isn't an episode
if m.top.content.contenttype <> 4
m.osd.itemTitleText = ""
end if
end if

populateChapterMenu()

if m.LoadMetaDataTask.isIntro
Expand Down
Binary file added images/osdBackground.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading