From 41cead3959f8979e000f04a44ea657adc8ef7a1d Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Wed, 31 Jul 2024 23:38:13 -0400 Subject: [PATCH 01/29] expand home rows to take up full width of the screen --- components/home/HomeRows.bs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs index 598a08961..febe66274 100644 --- a/components/home/HomeRows.bs +++ b/components/home/HomeRows.bs @@ -51,11 +51,14 @@ sub loadLibraries() end sub sub updateSize() - m.top.translation = [111, 180] - itemHeight = 330 + m.top.translation = [0, 180] - 'Set width of Rows to cut off at edge of Safe Zone - m.top.itemSize = [1703, itemHeight] + ' rows take up full width of the screen + m.top.itemSize = [1920, 330] + + ' align with edge of "action" safe zone + m.top.focusXOffset = [96] + m.top.rowLabelOffset = [96, 20] ' spacing between rows m.top.itemSpacing = [0, 105] From e37cedc0ce4352425da041d86402a5f483b0dc19 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Mon, 5 Aug 2024 15:23:04 -0400 Subject: [PATCH 02/29] Increase spacing between row items --- components/home/HomeRows.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs index febe66274..a36b68ef5 100644 --- a/components/home/HomeRows.bs +++ b/components/home/HomeRows.bs @@ -64,7 +64,7 @@ sub updateSize() m.top.itemSpacing = [0, 105] ' spacing between items in a row - m.top.rowItemSpacing = [20, 0] + m.top.rowItemSpacing = [33, 0] ' Default size to wide poster, the most used size m.top.rowItemSize = homeRowItemSizes.WIDE_POSTER From 72845c86ed3b9f3966532a2c9b69fa9cee58cb59 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Fri, 8 Nov 2024 02:58:30 +0000 Subject: [PATCH 03/29] Bump build version --- Makefile | 2 +- manifest | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index e036d4121..ac5cf59b9 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # If you want to get_images, you'll also need convert from ImageMagick ########################################################################## -VERSION := 2.2.2 +VERSION := 2.2.3 ## usage diff --git a/manifest b/manifest index 8f46b09a4..f8ee154eb 100644 --- a/manifest +++ b/manifest @@ -3,7 +3,7 @@ title=Jellyfin major_version=2 minor_version=2 -build_version=2 +build_version=3 ### Main Menu Icons / Channel Poster Artwork diff --git a/package-lock.json b/package-lock.json index 0e16e4ae4..e4b1aac7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jellyfin-roku", - "version": "2.2.2", + "version": "2.2.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jellyfin-roku", - "version": "2.2.2", + "version": "2.2.3", "hasInstallScript": true, "license": "GPL-2.0", "dependencies": { diff --git a/package.json b/package.json index e00d7e38d..ddf5a74d3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jellyfin-roku", "type": "module", - "version": "2.2.2", + "version": "2.2.3", "description": "Roku app for Jellyfin media server", "dependencies": { "@rokucommunity/bslib": "0.1.1", From 78ffb70be84a13703496da2ae21d1c3645cdecfd Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Fri, 8 Nov 2024 09:44:40 -0500 Subject: [PATCH 04/29] validate global data before using to prevent crash --- components/home/HomeItem.bs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/components/home/HomeItem.bs b/components/home/HomeItem.bs index 70a5918e4..046ee081e 100644 --- a/components/home/HomeItem.bs +++ b/components/home/HomeItem.bs @@ -62,10 +62,15 @@ sub itemContentChanged() if isValid(m.unplayedCount) then m.unplayedCount.visible = false itemData = m.top.itemContent if itemData = invalid then return - userSettings = m.global.session.user.settings itemData.Title = itemData.name ' Temporarily required while we move from "HomeItem" to "JFContentItem" + ' validate to prevent crash + userSettings = invalid + if isValid(m.global) and isValid(m.global.session) and isValid(m.global.session.user) and isValid(m.global.session.user.settings) + userSettings = m.global.session.user.settings + end if + ' validate to prevent crash if not isValid(m.itemPoster) then initItemPoster() if not isValid(m.itemText) then initItemText() @@ -164,17 +169,22 @@ sub itemContentChanged() drawProgressBar(itemData) end if - if userSettings["ui.general.episodeimagesnextup"] = "webclient" - tmpSetting = m.global.session.user.Configuration.useEpisodeImagesInNextUpAndResume - if isValid(tmpSetting) and tmpSetting - m.itemPoster.uri = itemData.thumbnailURL - else + if isValid(userSettings) + if userSettings["ui.general.episodeimagesnextup"] = "webclient" + tmpSetting = m.global.session.user.Configuration.useEpisodeImagesInNextUpAndResume + if isValid(tmpSetting) and tmpSetting + m.itemPoster.uri = itemData.thumbnailURL + else + m.itemPoster.uri = itemData.widePosterURL + end if + else if userSettings["ui.general.episodeimagesnextup"] = "show" m.itemPoster.uri = itemData.widePosterURL + else if userSettings["ui.general.episodeimagesnextup"] = "episode" + m.itemPoster.uri = itemData.thumbnailURL end if - else if userSettings["ui.general.episodeimagesnextup"] = "show" + else + ' use show image if user settings are invalid for some reason m.itemPoster.uri = itemData.widePosterURL - else if userSettings["ui.general.episodeimagesnextup"] = "episode" - m.itemPoster.uri = itemData.thumbnailURL end if ' Set Series and Episode Number for Extra Text From 786981fddc3960b83687da420adfe2af5a08a884 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Fri, 8 Nov 2024 11:26:53 -0500 Subject: [PATCH 05/29] create a user setting to allow users to disable the new look --- components/home/HomeRows.bs | 21 ++++++++++++--------- locale/en_US/translations.ts | 12 +++++++++++- settings/settings.json | 7 +++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs index a36b68ef5..4b0b0f484 100644 --- a/components/home/HomeRows.bs +++ b/components/home/HomeRows.bs @@ -51,18 +51,21 @@ sub loadLibraries() end sub sub updateSize() - m.top.translation = [0, 180] - - ' rows take up full width of the screen - m.top.itemSize = [1920, 330] - - ' align with edge of "action" safe zone - m.top.focusXOffset = [96] - m.top.rowLabelOffset = [96, 20] + isHomeLayoutv2 = m.global.session.user.settings["ui.home.layoutv2"] + if isValid(isHomeLayoutv2) and isHomeLayoutv2 + m.top.translation = [0, 180] + ' rows take up full width of the screen + m.top.itemSize = [1920, 330] + ' align with edge of "action" safe zone + m.top.focusXOffset = [96] + m.top.rowLabelOffset = [96, 20] + else + m.top.translation = [111, 180] + m.top.itemSize = [1703, 330] + end if ' spacing between rows m.top.itemSpacing = [0, 105] - ' spacing between items in a row m.top.rowItemSpacing = [33, 0] diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts index 7ba3844b8..66334de34 100644 --- a/locale/en_US/translations.ts +++ b/locale/en_US/translations.ts @@ -1311,5 +1311,15 @@ Use Show Image User Setting - Setting option title + + Home Screen Layout v2 + Home Screen Layout v2 + User Setting - Setting title + + + Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. + Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. + User Setting - Setting description + - + \ No newline at end of file diff --git a/settings/settings.json b/settings/settings.json index 99e053715..13af3293c 100644 --- a/settings/settings.json +++ b/settings/settings.json @@ -248,6 +248,13 @@ "type": "bool", "default": "false" }, + { + "title": "Home Screen Layout v2", + "description": "Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect.", + "settingName": "ui.home.layoutv2", + "type": "bool", + "default": "true" + }, { "title": "Max Days Next Up", "description": "Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.", From df3eb1ebb4ae860755dc69b22896d0117aacbfc9 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Fri, 8 Nov 2024 11:32:46 -0500 Subject: [PATCH 06/29] fix bad merge --- locale/en_US/translations.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts index 574b263fa..0a8a219b5 100644 --- a/locale/en_US/translations.ts +++ b/locale/en_US/translations.ts @@ -1331,6 +1331,7 @@ Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. User Setting - Setting description + Episode Next Up Behavior Episode Next Up Behavior User Setting - Setting option title From 3baeeb62bbe1f4eba9bb36772b637045147720a4 Mon Sep 17 00:00:00 2001 From: Michael Cresswell Date: Fri, 8 Nov 2024 16:07:14 -0500 Subject: [PATCH 07/29] Add Live TV series title, season number, and episode number to OSD, when available --- components/ItemGrid/LoadVideoContentTask.bs | 15 +++++++++++++++ components/video/VideoPlayerView.bs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/components/ItemGrid/LoadVideoContentTask.bs b/components/ItemGrid/LoadVideoContentTask.bs index 69a5cce0c..6dc5d7b01 100644 --- a/components/ItemGrid/LoadVideoContentTask.bs +++ b/components/ItemGrid/LoadVideoContentTask.bs @@ -115,6 +115,21 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s end if end if + if videotype = "tvchannel" and isValid(meta.json) and isValid(meta.json.CurrentProgram) + if isValid(meta.json.CurrentProgram.Name) + meta.title = `${meta.title}: ${meta.json.CurrentProgram.Name}` + end if + if isValid(meta.json.CurrentProgram.ParentIndexNumber) + video.seasonNumber = meta.json.CurrentProgram.ParentIndexNumber + end if + if isValid(meta.json.CurrentProgram.IndexNumber) + video.episodeNumber = meta.json.CurrentProgram.IndexNumber + end if + if isValid(meta.json.CurrentProgram.IndexNumberEnd) + video.episodeNumberEnd = meta.json.CurrentProgram.IndexNumberEnd + end if + end if + video.chapters = meta.json.Chapters video.content.title = meta.title video.showID = meta.showID diff --git a/components/video/VideoPlayerView.bs b/components/video/VideoPlayerView.bs index 109a5569c..7fd76714b 100644 --- a/components/video/VideoPlayerView.bs +++ b/components/video/VideoPlayerView.bs @@ -412,7 +412,7 @@ 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 m.top.content.contenttype = 4 or m.top.content.live if isValid(videoContent[0].seasonNumber) m.osd.seasonNumber = videoContent[0].seasonNumber end if From 77b92f0081de03d69772a817c7bfe0d6b4777d74 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Fri, 8 Nov 2024 18:14:08 -0500 Subject: [PATCH 08/29] fix crash on episode list when video codec is invalid. when invalid use "N/A" --- components/tvshows/TVListDetails.bs | 7 ++++++- locale/en_US/translations.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/components/tvshows/TVListDetails.bs b/components/tvshows/TVListDetails.bs index 38e27702f..9d17dbe08 100644 --- a/components/tvshows/TVListDetails.bs +++ b/components/tvshows/TVListDetails.bs @@ -108,7 +108,12 @@ sub itemContentChanged() if isValid(itemData.MediaSources) for i = 0 to itemData.MediaSources.Count() - 1 if item.selectedVideoStreamId = itemData.MediaSources[i].id and isValid(itemData.MediaSources[i].MediaStreams[0]) - m.videoCodec.text = tr("Video") + ": " + itemData.MediaSources[i].MediaStreams[0].DisplayTitle + m.videoCodec.text = tr("Video") + ": " + if isValid(itemData.MediaSources[i].MediaStreams[0].DisplayTitle) + m.videoCodec.text = m.videoCodec.text + itemData.MediaSources[i].MediaStreams[0].DisplayTitle + else + m.videoCodec.text = m.videoCodec.text + tr("N/A") + end if SetupAudioDisplay(itemData.MediaSources[i].MediaStreams, item.selectedAudioStreamIndex) exit for end if diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts index 50aad734f..7b41ca55b 100644 --- a/locale/en_US/translations.ts +++ b/locale/en_US/translations.ts @@ -1326,5 +1326,10 @@ Special Special episode of a TV Show + + N/A + N/A + Abbreviation for not available + - + \ No newline at end of file From d1b4cf21e5d3a7ef95baad4391f96af54eb0640a Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Fri, 8 Nov 2024 22:59:20 -0500 Subject: [PATCH 09/29] remove unnecessary code. wait until we have data before we create the row --- components/home/HomeRows.bs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs index d691cb154..c0ab55657 100644 --- a/components/home/HomeRows.bs +++ b/components/home/HomeRows.bs @@ -411,15 +411,6 @@ end sub ' createContinueWatchingRow: Creates a row displaying items the user can continue watching ' sub createContinueWatchingRow() - sectionName = tr("Continue Watching") - - if not sectionExists(sectionName) - nextUpRow = m.top.content.CreateChild("HomeRow") - nextUpRow.title = sectionName - nextUpRow.imageWidth = homeRowItemSizes.WIDE_POSTER[0] - nextUpRow.cursorSize = homeRowItemSizes.WIDE_POSTER - end if - ' Load the Continue Watching Data m.LoadContinueWatchingTask.observeField("content", "updateContinueWatchingItems") m.LoadContinueWatchingTask.control = "RUN" From 587e9425aa2fb913811487033df5a7292fede882 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 9 Nov 2024 11:04:46 -0500 Subject: [PATCH 10/29] rename user setting --- components/home/HomeRows.bs | 28 ++++++++++++++++------------ locale/en_US/translations.ts | 18 ++++++++++++++---- settings/settings.json | 24 +++++++++++++++++------- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs index 00eef009c..443ab2841 100644 --- a/components/home/HomeRows.bs +++ b/components/home/HomeRows.bs @@ -51,23 +51,27 @@ sub loadLibraries() end sub sub updateSize() - isHomeLayoutv2 = m.global.session.user.settings["ui.home.layoutv2"] - if isValid(isHomeLayoutv2) and isHomeLayoutv2 - m.top.translation = [0, 180] - ' rows take up full width of the screen - m.top.itemSize = [1920, 330] - ' align with edge of "action" safe zone - m.top.focusXOffset = [96] - m.top.rowLabelOffset = [96, 20] - else - m.top.translation = [111, 180] - m.top.itemSize = [1703, 330] + uiRowLayout = m.global.session.user.settings["ui.row.layout"] + + if isValid(uiRowLayout) + if uiRowLayout = "fullwidth" + m.top.translation = [0, 180] + ' rows take up full width of the screen + m.top.itemSize = [1920, 330] + ' align with edge of "action" safe zone + m.top.focusXOffset = [96] + m.top.rowLabelOffset = [96, 20] + else + ' original layout + m.top.translation = [111, 180] + m.top.itemSize = [1703, 330] + end if end if ' spacing between rows m.top.itemSpacing = [0, 105] ' spacing between items in a row - m.top.rowItemSpacing = [33, 0] + m.top.rowItemSpacing = [21, 0] ' Default size to wide poster, the most used size m.top.rowItemSize = homeRowItemSizes.WIDE_POSTER diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts index 0a8a219b5..8d77d9674 100644 --- a/locale/en_US/translations.ts +++ b/locale/en_US/translations.ts @@ -1322,15 +1322,25 @@ User Setting - Setting option title - Home Screen Layout v2 - Home Screen Layout v2 + Row Layout + Row Layout User Setting - Setting title - Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. - Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. + Choose how rows are displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. + Choose how rows are displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. User Setting - Setting description + + Original + Original + User Setting - Setting option title + + + Full Width + Full Width + User Setting - Setting option title + Episode Next Up Behavior Episode Next Up Behavior diff --git a/settings/settings.json b/settings/settings.json index 8519af637..d0897389d 100644 --- a/settings/settings.json +++ b/settings/settings.json @@ -286,13 +286,6 @@ "type": "bool", "default": "false" }, - { - "title": "Home Screen Layout v2", - "description": "Use the full display width for all rows displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect.", - "settingName": "ui.home.layoutv2", - "type": "bool", - "default": "true" - }, { "title": "Max Days Next Up", "description": "Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.", @@ -328,6 +321,23 @@ "type": "bool", "default": "false" }, + { + "title": "Row Layout", + "description": "Choose how rows are displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect.", + "settingName": "ui.row.layout", + "type": "radio", + "default": "fullwidth", + "options": [ + { + "title": "Original", + "id": "original" + }, + { + "title": "Full Width", + "id": "fullwidth" + } + ] + }, { "title": "Show What's New Popup", "description": "Show What's New popup when Jellyfin is updated to a new version.", From 5a97f2bdd4ec39f4a2c98353a532ef05df0f55d0 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 9 Nov 2024 11:32:03 -0500 Subject: [PATCH 11/29] update home row layout on refresh so we don't need to restart the app after updating setting --- components/home/HomeRows.bs | 8 +++++--- locale/en_US/translations.ts | 4 ++-- settings/settings.json | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/components/home/HomeRows.bs b/components/home/HomeRows.bs index 443ab2841..2497e3f77 100644 --- a/components/home/HomeRows.bs +++ b/components/home/HomeRows.bs @@ -65,6 +65,9 @@ sub updateSize() ' original layout m.top.translation = [111, 180] m.top.itemSize = [1703, 330] + ' reset to defaults + m.top.focusXOffset = [] + m.top.rowLabelOffset = [0, 20] end if end if @@ -73,9 +76,6 @@ sub updateSize() ' spacing between items in a row m.top.rowItemSpacing = [21, 0] - ' Default size to wide poster, the most used size - m.top.rowItemSize = homeRowItemSizes.WIDE_POSTER - m.top.visible = true end sub @@ -465,6 +465,8 @@ end sub sub updateHomeRows() ' Hide the row counter to prevent flicker. We'll show it once loading timer fires m.top.showRowCounter = [false] + m.top.visible = false + updateSize() processUserSections() end sub diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts index 8d77d9674..d4d06dec0 100644 --- a/locale/en_US/translations.ts +++ b/locale/en_US/translations.ts @@ -1327,8 +1327,8 @@ User Setting - Setting title - Choose how rows are displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. - Choose how rows are displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect. + Choose how rows are displayed on the home screen. + Choose how rows are displayed on the home screen. User Setting - Setting description diff --git a/settings/settings.json b/settings/settings.json index d0897389d..828a329ae 100644 --- a/settings/settings.json +++ b/settings/settings.json @@ -323,7 +323,7 @@ }, { "title": "Row Layout", - "description": "Choose how rows are displayed on the home screen. Jellyfin will need to be closed and reopened for changes to take effect.", + "description": "Choose how rows are displayed on the home screen.", "settingName": "ui.row.layout", "type": "radio", "default": "fullwidth", From f70708b72c0445e81e7b9416b665f571ffea620d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 9 Nov 2024 23:35:07 +0000 Subject: [PATCH 12/29] Update dependency markdownlint-cli2 to v0.15.0 --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index d94b071ac..d7c8fbed8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "clean-jsdoc-theme": "4.3.0", "jsdoc": "4.0.4", "jshint": "2.13.6", - "markdownlint-cli2": "0.14.0", + "markdownlint-cli2": "0.15.0", "rimraf": "6.0.1", "roku-deploy": "3.12.2", "roku-log-bsc-plugin": "0.8.1", @@ -3489,14 +3489,14 @@ "dev": true }, "node_modules/markdownlint": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.35.0.tgz", - "integrity": "sha512-wgp8yesWjFBL7bycA3hxwHRdsZGJhjhyP1dSxKVKrza0EPFYtn+mHtkVy6dvP1kGSjovyG5B8yNP6Frj0UFUJg==", + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.36.1.tgz", + "integrity": "sha512-s73fU2CQN7WCgjhaQUQ8wYESQNzGRNOKDd+3xgVqu8kuTEhmwepd/mxOv1LR2oV046ONrTLBFsM7IoKWNvmy5g==", "dev": true, "license": "MIT", "dependencies": { "markdown-it": "14.1.0", - "markdownlint-micromark": "0.1.10" + "markdownlint-micromark": "0.1.12" }, "engines": { "node": ">=18" @@ -3506,16 +3506,16 @@ } }, "node_modules/markdownlint-cli2": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.14.0.tgz", - "integrity": "sha512-2cqdWy56frU2FTpbuGb83mEWWYuUIYv6xS8RVEoUAuKNw/hXPar2UYGpuzUhlFMngE8Omaz4RBH52MzfRbGshw==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.15.0.tgz", + "integrity": "sha512-4P/lnxQxU2R5lywRJs4b2ajm8z65CW8qqR1bTIcdQ5EG+nZpC6HJlJUnmIR5ee+uecUkoMroazxWcLB7etSmrg==", "dev": true, "license": "MIT", "dependencies": { "globby": "14.0.2", "js-yaml": "4.1.0", "jsonc-parser": "3.3.1", - "markdownlint": "0.35.0", + "markdownlint": "0.36.1", "markdownlint-cli2-formatter-default": "0.0.5", "micromatch": "4.0.8" }, @@ -3597,9 +3597,9 @@ } }, "node_modules/markdownlint-micromark": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.10.tgz", - "integrity": "sha512-no5ZfdqAdWGxftCLlySHSgddEjyW4kui4z7amQcGsSKfYC5v/ou+8mIQVyg9KQMeEZLNtz9OPDTj7nnTnoR4FQ==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.12.tgz", + "integrity": "sha512-RlB6EwMGgc0sxcIhOQ2+aq7Zw1V2fBnzbXKGgYK/mVWdT7cz34fteKSwfYeo4rL6+L/q2tyC9QtD/PgZbkdyJQ==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 7dfacdd97..5c59d1a07 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "clean-jsdoc-theme": "4.3.0", "jsdoc": "4.0.4", "jshint": "2.13.6", - "markdownlint-cli2": "0.14.0", + "markdownlint-cli2": "0.15.0", "rimraf": "6.0.1", "roku-deploy": "3.12.2", "roku-log-bsc-plugin": "0.8.1", From 2ec8bdb1b3d7852e65df5ee80ea3e921f5d33aea Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Sat, 9 Nov 2024 23:35:24 +0000 Subject: [PATCH 13/29] Update API docs --- ...mponents_ItemGrid_LoadVideoContentTask.bs.html | 15 +++++++++++++++ docs/api/components_video_VideoPlayerView.bs.html | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html b/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html index 001b828b4..ebfac1cd9 100644 --- a/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html +++ b/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html @@ -117,6 +117,21 @@ end if end if + if videotype = "tvchannel" and isValid(meta.json) and isValid(meta.json.CurrentProgram) + if isValid(meta.json.CurrentProgram.Name) + meta.title = `${meta.title}: ${meta.json.CurrentProgram.Name}` + end if + if isValid(meta.json.CurrentProgram.ParentIndexNumber) + video.seasonNumber = meta.json.CurrentProgram.ParentIndexNumber + end if + if isValid(meta.json.CurrentProgram.IndexNumber) + video.episodeNumber = meta.json.CurrentProgram.IndexNumber + end if + if isValid(meta.json.CurrentProgram.IndexNumberEnd) + video.episodeNumberEnd = meta.json.CurrentProgram.IndexNumberEnd + end if + end if + video.chapters = meta.json.Chapters video.content.title = meta.title video.showID = meta.showID diff --git a/docs/api/components_video_VideoPlayerView.bs.html b/docs/api/components_video_VideoPlayerView.bs.html index ac764c940..4753c3c6a 100644 --- a/docs/api/components_video_VideoPlayerView.bs.html +++ b/docs/api/components_video_VideoPlayerView.bs.html @@ -414,7 +414,7 @@ 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 m.top.content.contenttype = 4 or m.top.content.live if isValid(videoContent[0].seasonNumber) m.osd.seasonNumber = videoContent[0].seasonNumber end if From 51a6a335396fee9c551ed44142002cce2afc8611 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Sun, 10 Nov 2024 00:18:25 +0000 Subject: [PATCH 14/29] Update API docs --- docs/api/components_home_HomeRows.bs.html | 32 ++++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/docs/api/components_home_HomeRows.bs.html b/docs/api/components_home_HomeRows.bs.html index abae358e9..c3b5f3b0a 100644 --- a/docs/api/components_home_HomeRows.bs.html +++ b/docs/api/components_home_HomeRows.bs.html @@ -53,20 +53,30 @@ end sub sub updateSize() - m.top.translation = [111, 180] - itemHeight = 330 - - 'Set width of Rows to cut off at edge of Safe Zone - m.top.itemSize = [1703, itemHeight] + uiRowLayout = m.global.session.user.settings["ui.row.layout"] + + if isValid(uiRowLayout) + if uiRowLayout = "fullwidth" + m.top.translation = [0, 180] + ' rows take up full width of the screen + m.top.itemSize = [1920, 330] + ' align with edge of "action" safe zone + m.top.focusXOffset = [96] + m.top.rowLabelOffset = [96, 20] + else + ' original layout + m.top.translation = [111, 180] + m.top.itemSize = [1703, 330] + ' reset to defaults + m.top.focusXOffset = [] + m.top.rowLabelOffset = [0, 20] + end if + end if ' spacing between rows m.top.itemSpacing = [0, 105] - ' spacing between items in a row - m.top.rowItemSpacing = [20, 0] - - ' Default size to wide poster, the most used size - m.top.rowItemSize = homeRowItemSizes.WIDE_POSTER + m.top.rowItemSpacing = [21, 0] m.top.visible = true end sub @@ -457,6 +467,8 @@ sub updateHomeRows() ' Hide the row counter to prevent flicker. We'll show it once loading timer fires m.top.showRowCounter = [false] + m.top.visible = false + updateSize() processUserSections() end sub From 1e49d3fd1cd3bd24b5d175818daff4fe1c4d1e8c Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 9 Nov 2024 19:20:17 -0500 Subject: [PATCH 15/29] alphabetize all user settings --- settings/settings.json | 122 ++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/settings/settings.json b/settings/settings.json index 828a329ae..29668c4c6 100644 --- a/settings/settings.json +++ b/settings/settings.json @@ -36,6 +36,13 @@ } ] }, + { + "title": "Cinema Mode", + "description": "Bring 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" + }, { "title": "Compatibility", "description": "Attempt to prevent playback failures.", @@ -49,6 +56,13 @@ } ] }, + { + "title": "Custom Subtitles", + "description": "Replace Roku's default subtitle functions with custom functions that support CJK fonts. Fallback fonts must be configured and enabled on the server for CJK rendering to work.", + "settingName": "playback.subs.custom", + "type": "bool", + "default": "false" + }, { "title": "Maximum Resolution", "description": "Configure the maximum resolution when playing video files on this device.", @@ -113,60 +127,6 @@ } ] }, - { - "title": "Video Codec Support", - "description": "Enable or disable Direct Play support for certain codecs.", - "children": [ - { - "title": "MPEG-2", - "description": "Support Direct Play of MPEG-2 content (e.g., Live TV). This will prevent transcoding of MPEG-2 content, but uses significantly more bandwidth.", - "settingName": "playback.mpeg2", - "type": "bool", - "default": "false" - }, - { - "title": "MPEG-4", - "description": "Support Direct Play of MPEG-4 content. This may need to be disabled for playback of DIVX encoded video files.", - "settingName": "playback.mpeg4", - "type": "bool", - "default": "true" - } - ] - }, - { - "title": "Video Profile Level Support", - "description": "Attempt Direct Play of potentially unsupported profile levels", - "children": [ - { - "title": "H.264", - "description": "Attempt Direct Play for H.264 media with unsupported profile levels before falling back to transcoding if it fails.", - "settingName": "playback.tryDirect.h264ProfileLevel", - "type": "bool", - "default": "false" - }, - { - "title": "HEVC", - "description": "Attempt Direct Play for HEVC media with unsupported profile levels before falling back to transcoding if it fails.", - "settingName": "playback.tryDirect.hevcProfileLevel", - "type": "bool", - "default": "false" - } - ] - }, - { - "title": "Cinema Mode", - "description": "Bring 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" - }, - { - "title": "Custom Subtitles", - "description": "Replace Roku's default subtitle functions with custom functions that support CJK fonts. Fallback fonts must be configured and enabled on the server for CJK rendering to work.", - "settingName": "playback.subs.custom", - "type": "bool", - "default": "false" - }, { "title": "Next Episode Button Time", "description": "Set how many seconds before the end of an episode the Next Episode button should appear. Set to 0 to disable.", @@ -230,6 +190,46 @@ "settingName": "playback.subs.onlytext", "type": "bool", "default": "false" + }, + { + "title": "Video Codec Support", + "description": "Enable or disable Direct Play support for certain codecs.", + "children": [ + { + "title": "MPEG-2", + "description": "Support Direct Play of MPEG-2 content (e.g., Live TV). This will prevent transcoding of MPEG-2 content, but uses significantly more bandwidth.", + "settingName": "playback.mpeg2", + "type": "bool", + "default": "false" + }, + { + "title": "MPEG-4", + "description": "Support Direct Play of MPEG-4 content. This may need to be disabled for playback of DIVX encoded video files.", + "settingName": "playback.mpeg4", + "type": "bool", + "default": "true" + } + ] + }, + { + "title": "Video Profile Level Support", + "description": "Attempt Direct Play of potentially unsupported profile levels", + "children": [ + { + "title": "H.264", + "description": "Attempt Direct Play for H.264 media with unsupported profile levels before falling back to transcoding if it fails.", + "settingName": "playback.tryDirect.h264ProfileLevel", + "type": "bool", + "default": "false" + }, + { + "title": "HEVC", + "description": "Attempt Direct Play for HEVC media with unsupported profile levels before falling back to transcoding if it fails.", + "settingName": "playback.tryDirect.hevcProfileLevel", + "type": "bool", + "default": "false" + } + ] } ] }, @@ -423,6 +423,13 @@ "title": "Movies", "description": "Settings relating to the appearance of pages in Movie Libraries.", "children": [ + { + "title": "Community and Critical Ratings", + "description": "Ratings for how good a movie is.", + "settingName": "ui.movies.showRatings", + "type": "bool", + "default": "true" + }, { "title": "Default View", "description": "Default view for Movie Libraries.", @@ -439,13 +446,6 @@ "id": "MoviesGrid" } ] - }, - { - "title": "Community and Critical Ratings", - "description": "Ratings for how good a movie is.", - "settingName": "ui.movies.showRatings", - "type": "bool", - "default": "true" } ] }, From b4204303af93e3effb35eca1bb80dedb0cd9ef04 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Sun, 10 Nov 2024 01:24:00 +0000 Subject: [PATCH 16/29] Bump build version --- Makefile | 2 +- manifest | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index ac5cf59b9..058051740 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # If you want to get_images, you'll also need convert from ImageMagick ########################################################################## -VERSION := 2.2.3 +VERSION := 2.2.4 ## usage diff --git a/manifest b/manifest index f8ee154eb..ddf587fb8 100644 --- a/manifest +++ b/manifest @@ -3,7 +3,7 @@ title=Jellyfin major_version=2 minor_version=2 -build_version=3 +build_version=4 ### Main Menu Icons / Channel Poster Artwork diff --git a/package-lock.json b/package-lock.json index e4b1aac7f..44ec1ea9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jellyfin-roku", - "version": "2.2.3", + "version": "2.2.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jellyfin-roku", - "version": "2.2.3", + "version": "2.2.4", "hasInstallScript": true, "license": "GPL-2.0", "dependencies": { diff --git a/package.json b/package.json index ddf5a74d3..09fb41e6e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jellyfin-roku", "type": "module", - "version": "2.2.3", + "version": "2.2.4", "description": "Roku app for Jellyfin media server", "dependencies": { "@rokucommunity/bslib": "0.1.1", From 6dcf913a0bdacad4dd2e59239ded5539ae79a6d3 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Sun, 10 Nov 2024 01:24:17 +0000 Subject: [PATCH 17/29] Update API docs --- docs/api/components_home_HomeItem.bs.html | 28 +++++++++++++------ .../components_tvshows_TVListDetails.bs.html | 7 ++++- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/docs/api/components_home_HomeItem.bs.html b/docs/api/components_home_HomeItem.bs.html index 6f28722ee..0dfb4452f 100644 --- a/docs/api/components_home_HomeItem.bs.html +++ b/docs/api/components_home_HomeItem.bs.html @@ -64,10 +64,15 @@ if isValid(m.unplayedCount) then m.unplayedCount.visible = false itemData = m.top.itemContent if itemData = invalid then return - userSettings = m.global.session.user.settings itemData.Title = itemData.name ' Temporarily required while we move from "HomeItem" to "JFContentItem" + ' validate to prevent crash + userSettings = invalid + if isValid(m.global) and isValid(m.global.session) and isValid(m.global.session.user) and isValid(m.global.session.user.settings) + userSettings = m.global.session.user.settings + end if + ' validate to prevent crash if not isValid(m.itemPoster) then initItemPoster() if not isValid(m.itemText) then initItemText() @@ -166,17 +171,22 @@ drawProgressBar(itemData) end if - if userSettings["ui.general.episodeimagesnextup"] = "webclient" - tmpSetting = m.global.session.user.Configuration.useEpisodeImagesInNextUpAndResume - if isValid(tmpSetting) and tmpSetting - m.itemPoster.uri = itemData.thumbnailURL - else + if isValid(userSettings) + if userSettings["ui.general.episodeimagesnextup"] = "webclient" + tmpSetting = m.global.session.user.Configuration.useEpisodeImagesInNextUpAndResume + if isValid(tmpSetting) and tmpSetting + m.itemPoster.uri = itemData.thumbnailURL + else + m.itemPoster.uri = itemData.widePosterURL + end if + else if userSettings["ui.general.episodeimagesnextup"] = "show" m.itemPoster.uri = itemData.widePosterURL + else if userSettings["ui.general.episodeimagesnextup"] = "episode" + m.itemPoster.uri = itemData.thumbnailURL end if - else if userSettings["ui.general.episodeimagesnextup"] = "show" + else + ' use show image if user settings are invalid for some reason m.itemPoster.uri = itemData.widePosterURL - else if userSettings["ui.general.episodeimagesnextup"] = "episode" - m.itemPoster.uri = itemData.thumbnailURL end if ' Set Series and Episode Number for Extra Text diff --git a/docs/api/components_tvshows_TVListDetails.bs.html b/docs/api/components_tvshows_TVListDetails.bs.html index 2d3179c43..c7545a326 100644 --- a/docs/api/components_tvshows_TVListDetails.bs.html +++ b/docs/api/components_tvshows_TVListDetails.bs.html @@ -110,7 +110,12 @@ if isValid(itemData.MediaSources) for i = 0 to itemData.MediaSources.Count() - 1 if item.selectedVideoStreamId = itemData.MediaSources[i].id and isValid(itemData.MediaSources[i].MediaStreams[0]) - m.videoCodec.text = tr("Video") + ": " + itemData.MediaSources[i].MediaStreams[0].DisplayTitle + m.videoCodec.text = tr("Video") + ": " + if isValid(itemData.MediaSources[i].MediaStreams[0].DisplayTitle) + m.videoCodec.text = m.videoCodec.text + itemData.MediaSources[i].MediaStreams[0].DisplayTitle + else + m.videoCodec.text = m.videoCodec.text + tr("N/A") + end if SetupAudioDisplay(itemData.MediaSources[i].MediaStreams, item.selectedAudioStreamIndex) exit for end if From 98a73d899eb17d439c7cfe20c26fe4bae8dd1c25 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sun, 10 Nov 2024 07:41:54 -0500 Subject: [PATCH 18/29] make settings menu wrap --- components/settings/settings.bs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/settings/settings.bs b/components/settings/settings.bs index 55239d77d..200cf2bff 100644 --- a/components/settings/settings.bs +++ b/components/settings/settings.bs @@ -251,5 +251,19 @@ function onKeyEvent(key as string, press as boolean) as boolean settingSelected() end if + if key = "up" and m.settingsMenu.focusedChild <> invalid and m.settingsMenu.itemFocused = 0 + m.settingsMenu.jumpToItem = m.settingsMenu.content.getChildCount() - 1 + + return true + end if + + if key = "down" and m.settingsMenu.focusedChild <> invalid + if m.settingsMenu.itemFocused = m.settingsMenu.content.getChildCount() - 1 + m.settingsMenu.jumpToItem = 0 + + return true + end if + end if + return false end function From f00038a61adef78a5d39ed4797f736e1955d5a27 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 12 Nov 2024 13:08:51 -0500 Subject: [PATCH 19/29] stop adding h264 to codec string twice --- source/utils/deviceCapabilities.bs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source/utils/deviceCapabilities.bs b/source/utils/deviceCapabilities.bs index 44cc05d66..a7dd27034 100644 --- a/source/utils/deviceCapabilities.bs +++ b/source/utils/deviceCapabilities.bs @@ -211,19 +211,6 @@ function getTranscodingProfiles() as object ' ' AVC / h264 / MPEG4 AVC for each container in transcodingContainers - if di.CanDecodeVideo({ Codec: "h264", Container: container }).Result - if container = "mp4" - ' check for codec string before adding it - if mp4VideoCodecs.Instr(0, ",h264") = -1 - mp4VideoCodecs = mp4VideoCodecs + ",h264" - end if - else if container = "ts" - ' check for codec string before adding it - if tsVideoCodecs.Instr(0, ",h264") = -1 - tsVideoCodecs = tsVideoCodecs + ",h264" - end if - end if - end if if di.CanDecodeVideo({ Codec: "mpeg4 avc", Container: container }).Result if container = "mp4" ' check for codec string before adding it From a79c25978213fce255fbdfe848e648829730a318 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 12 Nov 2024 13:18:24 -0500 Subject: [PATCH 20/29] force a full transcode for AV1 instead of direct streaming --- source/utils/deviceCapabilities.bs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/utils/deviceCapabilities.bs b/source/utils/deviceCapabilities.bs index a7dd27034..f0f4413ab 100644 --- a/source/utils/deviceCapabilities.bs +++ b/source/utils/deviceCapabilities.bs @@ -288,11 +288,9 @@ function getTranscodingProfiles() as object end if ' AV1 - ' CanDecodeVideo() returns false for AV1 when the container is provided - ' Manually add AV1 to the mp4VideoCodecs list if support is detected - if di.CanDecodeVideo({ Codec: "av1" }).Result - mp4VideoCodecs = mp4VideoCodecs + ",av1" - end if + ' direct streaming av1 is not supported on roku + ' force a full transcode by omitting av1 from the transcoding profile + ' https://community.roku.com/t5/Roku-Developer-Program/HLS-fMP4-No-Audio/td-p/607399 ' AUDIO CODECS for each container in transcodingContainers From dd00fdf0de5fa47fa8c8f5a417369c67f3535e13 Mon Sep 17 00:00:00 2001 From: c21021 Date: Tue, 12 Nov 2024 16:29:35 -0500 Subject: [PATCH 21/29] Allow Intro Videos to be able to be skipped or paused --- components/video/VideoPlayerView.bs | 56 ++++++++++++----------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/components/video/VideoPlayerView.bs b/components/video/VideoPlayerView.bs index 7fd76714b..472279fab 100644 --- a/components/video/VideoPlayerView.bs +++ b/components/video/VideoPlayerView.bs @@ -438,13 +438,9 @@ sub onVideoContentLoaded() populateChapterMenu() - if m.LoadMetaDataTask.isIntro - ' Disable trackplay bar for intro videos - m.top.enableTrickPlay = false - else - ' Allow custom captions for non intro videos - m.top.allowCaptions = true - end if + + ' Allow custom captions for all videos including intro videos + m.top.allowCaptions = true ' Allow default subtitles m.top.unobserveField("selectedSubtitle") @@ -847,40 +843,34 @@ function onKeyEvent(key as string, press as boolean) as boolean end if else if key = "OK" and not m.top.trickPlayBar.visible - if not m.LoadMetaDataTask.isIntro - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true - - ' Show OSD, but don't pause video - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) - return true - end if + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - return false + ' Show OSD, but don't pause video + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true end if ' Disable OSD for intro videos - if not m.LoadMetaDataTask.isIntro - if key = "play" and not m.top.trickPlayBar.visible - - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true + if key = "play" and not m.top.trickPlayBar.visible - ' If video is paused, resume it and don't show OSD - if m.top.state = "paused" - m.top.control = "resume" - return true - end if + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - ' Pause video and show OSD - m.top.control = "pause" - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) + ' If video is paused, resume it and don't show OSD + if m.top.state = "paused" + m.top.control = "resume" return true end if + + ' Pause video and show OSD + m.top.control = "pause" + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true end if if key = "back" From 928b1da0c04cea482b10f589839cfdb05f4a30eb Mon Sep 17 00:00:00 2001 From: c21021 Date: Tue, 12 Nov 2024 17:37:57 -0500 Subject: [PATCH 22/29] Removed other restrictions on OSD for intro files --- components/video/VideoPlayerView.bs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/components/video/VideoPlayerView.bs b/components/video/VideoPlayerView.bs index 472279fab..e6cb34996 100644 --- a/components/video/VideoPlayerView.bs +++ b/components/video/VideoPlayerView.bs @@ -821,26 +821,22 @@ function onKeyEvent(key as string, press as boolean) as boolean if not press then return false if key = "down" and not m.top.trickPlayBar.visible - if not m.LoadMetaDataTask.isIntro - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) - return true - end if + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true else if key = "up" and not m.top.trickPlayBar.visible - if not m.LoadMetaDataTask.isIntro - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) - return true - end if + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true else if key = "OK" and not m.top.trickPlayBar.visible ' Don't allow user to open menu prior to video loading From ffac3fe799190c9a9308e5151f471b7747200171 Mon Sep 17 00:00:00 2001 From: Jimi Date: Fri, 15 Nov 2024 15:17:05 -0700 Subject: [PATCH 23/29] Subtitle should be on when a default one has been selected by the user. --- components/video/VideoPlayerView.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/video/VideoPlayerView.bs b/components/video/VideoPlayerView.bs index 109a5569c..ea9758071 100644 --- a/components/video/VideoPlayerView.bs +++ b/components/video/VideoPlayerView.bs @@ -466,8 +466,8 @@ sub onVideoContentLoaded() ' If IsForced, make sure to remember the Roku global setting so we ' can set it back when the video is done playing. m.originalClosedCaptionState = m.top.globalCaptionMode - m.top.globalCaptionMode = "On" end if + m.top.globalCaptionMode = "On" m.top.subtitleTrack = m.top.availableSubtitleTracks[availableSubtitleTrackIndex].TrackName end if end if From 24fe137029317c006c7a8726dd7543fee9cf2856 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Sat, 16 Nov 2024 21:37:14 +0000 Subject: [PATCH 24/29] Update API docs --- docs/api/components_settings_settings.bs.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/api/components_settings_settings.bs.html b/docs/api/components_settings_settings.bs.html index 363d8d16f..554f03621 100644 --- a/docs/api/components_settings_settings.bs.html +++ b/docs/api/components_settings_settings.bs.html @@ -253,6 +253,20 @@ settingSelected() end if + if key = "up" and m.settingsMenu.focusedChild <> invalid and m.settingsMenu.itemFocused = 0 + m.settingsMenu.jumpToItem = m.settingsMenu.content.getChildCount() - 1 + + return true + end if + + if key = "down" and m.settingsMenu.focusedChild <> invalid + if m.settingsMenu.itemFocused = m.settingsMenu.content.getChildCount() - 1 + m.settingsMenu.jumpToItem = 0 + + return true + end if + end if + return false end function
jellyfin-roku Code Documentation
\ No newline at end of file From 4d57f98c0b9d60fc0e64e5ed23f4394459f62c4a Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Mon, 18 Nov 2024 22:10:43 +0000 Subject: [PATCH 25/29] Bump build version --- Makefile | 2 +- manifest | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 058051740..a6e4a2e2a 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # If you want to get_images, you'll also need convert from ImageMagick ########################################################################## -VERSION := 2.2.4 +VERSION := 2.2.5 ## usage diff --git a/manifest b/manifest index ddf587fb8..dd907d766 100644 --- a/manifest +++ b/manifest @@ -3,7 +3,7 @@ title=Jellyfin major_version=2 minor_version=2 -build_version=4 +build_version=5 ### Main Menu Icons / Channel Poster Artwork diff --git a/package-lock.json b/package-lock.json index 44ec1ea9b..d53248cf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jellyfin-roku", - "version": "2.2.4", + "version": "2.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jellyfin-roku", - "version": "2.2.4", + "version": "2.2.5", "hasInstallScript": true, "license": "GPL-2.0", "dependencies": { diff --git a/package.json b/package.json index 09fb41e6e..459660d4f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jellyfin-roku", "type": "module", - "version": "2.2.4", + "version": "2.2.5", "description": "Roku app for Jellyfin media server", "dependencies": { "@rokucommunity/bslib": "0.1.1", From 700dcc2906d23e23551d54276a514199e269d53d Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Mon, 18 Nov 2024 22:10:52 +0000 Subject: [PATCH 26/29] Update API docs --- docs/api/components_home_HomeRows.bs.html | 9 -------- .../components_video_VideoPlayerView.bs.html | 2 +- .../source_utils_deviceCapabilities.bs.html | 21 +++---------------- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/docs/api/components_home_HomeRows.bs.html b/docs/api/components_home_HomeRows.bs.html index c3b5f3b0a..70d322dca 100644 --- a/docs/api/components_home_HomeRows.bs.html +++ b/docs/api/components_home_HomeRows.bs.html @@ -423,15 +423,6 @@ ' createContinueWatchingRow: Creates a row displaying items the user can continue watching ' sub createContinueWatchingRow() - sectionName = tr("Continue Watching") - - if not sectionExists(sectionName) - nextUpRow = m.top.content.CreateChild("HomeRow") - nextUpRow.title = sectionName - nextUpRow.imageWidth = homeRowItemSizes.WIDE_POSTER[0] - nextUpRow.cursorSize = homeRowItemSizes.WIDE_POSTER - end if - ' Load the Continue Watching Data m.LoadContinueWatchingTask.observeField("content", "updateContinueWatchingItems") m.LoadContinueWatchingTask.control = "RUN" diff --git a/docs/api/components_video_VideoPlayerView.bs.html b/docs/api/components_video_VideoPlayerView.bs.html index 4753c3c6a..4b7247f53 100644 --- a/docs/api/components_video_VideoPlayerView.bs.html +++ b/docs/api/components_video_VideoPlayerView.bs.html @@ -468,8 +468,8 @@ ' If IsForced, make sure to remember the Roku global setting so we ' can set it back when the video is done playing. m.originalClosedCaptionState = m.top.globalCaptionMode - m.top.globalCaptionMode = "On" end if + m.top.globalCaptionMode = "On" m.top.subtitleTrack = m.top.availableSubtitleTracks[availableSubtitleTrackIndex].TrackName end if end if diff --git a/docs/api/source_utils_deviceCapabilities.bs.html b/docs/api/source_utils_deviceCapabilities.bs.html index 9c720e119..07749c03d 100644 --- a/docs/api/source_utils_deviceCapabilities.bs.html +++ b/docs/api/source_utils_deviceCapabilities.bs.html @@ -213,19 +213,6 @@ ' ' AVC / h264 / MPEG4 AVC for each container in transcodingContainers - if di.CanDecodeVideo({ Codec: "h264", Container: container }).Result - if container = "mp4" - ' check for codec string before adding it - if mp4VideoCodecs.Instr(0, ",h264") = -1 - mp4VideoCodecs = mp4VideoCodecs + ",h264" - end if - else if container = "ts" - ' check for codec string before adding it - if tsVideoCodecs.Instr(0, ",h264") = -1 - tsVideoCodecs = tsVideoCodecs + ",h264" - end if - end if - end if if di.CanDecodeVideo({ Codec: "mpeg4 avc", Container: container }).Result if container = "mp4" ' check for codec string before adding it @@ -303,11 +290,9 @@ end if ' AV1 - ' CanDecodeVideo() returns false for AV1 when the container is provided - ' Manually add AV1 to the mp4VideoCodecs list if support is detected - if di.CanDecodeVideo({ Codec: "av1" }).Result - mp4VideoCodecs = mp4VideoCodecs + ",av1" - end if + ' direct streaming av1 is not supported on roku + ' force a full transcode by omitting av1 from the transcoding profile + ' https://community.roku.com/t5/Roku-Developer-Program/HLS-fMP4-No-Audio/td-p/607399 ' AUDIO CODECS for each container in transcodingContainers From b9e7324a1237eb60c64efb523b45f1d59e891ea9 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 19 Nov 2024 17:49:44 -0500 Subject: [PATCH 27/29] force mp3 audio when direct play fails because of unsupported aac stream --- components/ItemGrid/LoadVideoContentTask.bs | 5 +-- components/ItemGrid/LoadVideoContentTask.xml | 1 + components/video/VideoPlayerView.bs | 14 +++++++- components/video/VideoPlayerView.xml | 1 + source/api/Items.bs | 35 ++++++++++++-------- 5 files changed, 39 insertions(+), 17 deletions(-) diff --git a/components/ItemGrid/LoadVideoContentTask.bs b/components/ItemGrid/LoadVideoContentTask.bs index 69a5cce0c..503b5b5bd 100644 --- a/components/ItemGrid/LoadVideoContentTask.bs +++ b/components/ItemGrid/LoadVideoContentTask.bs @@ -54,6 +54,7 @@ sub loadItems() forceTranscoding = false m.top.content = [LoadItems_VideoPlayer(id, mediaSourceId, audio_stream_idx, forceTranscoding)] + m.top.forceMp3 = false end sub function LoadItems_VideoPlayer(id as string, mediaSourceId = invalid as dynamic, audio_stream_idx = 1 as integer, forceTranscoding = false as boolean) as dynamic @@ -157,7 +158,7 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s if not isValid(mediaSourceId) then mediaSourceId = video.id if meta.live then mediaSourceId = "" - m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition) + m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition, m.top.forceMp3) if not isValid(m.playbackInfo) video.errorMsg = "Error loading playback info" video.content = invalid @@ -174,7 +175,7 @@ sub LoadItems_AddVideoContent(video as object, mediaSourceId as dynamic, audio_s video.SelectedSubtitle = defaultSubtitleIndex subtitle_idx = defaultSubtitleIndex - m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition) + m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition, m.top.forceMp3) if not isValid(m.playbackInfo) video.errorMsg = "Error loading playback info" video.content = invalid diff --git a/components/ItemGrid/LoadVideoContentTask.xml b/components/ItemGrid/LoadVideoContentTask.xml index f935c3e33..20a6317ac 100644 --- a/components/ItemGrid/LoadVideoContentTask.xml +++ b/components/ItemGrid/LoadVideoContentTask.xml @@ -18,6 +18,7 @@ + diff --git a/components/video/VideoPlayerView.bs b/components/video/VideoPlayerView.bs index 109a5569c..757795dc9 100644 --- a/components/video/VideoPlayerView.bs +++ b/components/video/VideoPlayerView.bs @@ -34,7 +34,6 @@ sub init() m.playbackTimer = m.top.findNode("playbackTimer") m.bufferCheckTimer = m.top.findNode("bufferCheckTimer") - m.top.observeField("state", "onState") m.top.observeField("content", "onContentChange") m.top.observeField("selectedSubtitle", "onSubtitleChange") m.top.observeField("audioIndex", "onAudioIndexChange") @@ -397,6 +396,8 @@ sub onVideoContentLoaded() return end if + m.top.observeField("state", "onState") + m.top.content = videoContent[0].content m.top.PlaySessionId = videoContent[0].PlaySessionId m.top.videoId = videoContent[0].id @@ -639,6 +640,17 @@ sub onState(msg) if not m.playReported and m.top.transcodeAvailable m.top.retryWithTranscoding = true ' If playback was not reported, retry with transcoding + else if m.top.errorStr = "decoder:pump:Unsupported AAC stream." + m.log.info("retrying video with mp3 audio stream", m.currentItem.id, m.top.SelectedSubtitle, m.top.audioIndex) + + m.top.unobserveField("state") + m.LoadMetaDataTask.forceMp3 = true + m.LoadMetaDataTask.selectedSubtitleIndex = m.top.SelectedSubtitle + m.LoadMetaDataTask.selectedAudioStreamIndex = m.top.audioIndex + m.LoadMetaDataTask.itemId = m.currentItem.id + m.LoadMetaDataTask.observeField("content", "onVideoContentLoaded") + + m.LoadMetaDataTask.control = "RUN" else ' If an error was encountered, Display dialog showPlaybackErrorDialog(tr("Error During Playback")) diff --git a/components/video/VideoPlayerView.xml b/components/video/VideoPlayerView.xml index 2f7b67fe4..d66e9126c 100644 --- a/components/video/VideoPlayerView.xml +++ b/components/video/VideoPlayerView.xml @@ -20,6 +20,7 @@ + diff --git a/source/api/Items.bs b/source/api/Items.bs index 65ed564b9..2dcf12348 100644 --- a/source/api/Items.bs +++ b/source/api/Items.bs @@ -13,7 +13,7 @@ function ItemGetPlaybackInfo(id as string, startTimeTicks = 0 as longinteger) return getJson(resp) end function -function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = -1 as integer, startTimeTicks = 0 as longinteger) +function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = -1 as integer, startTimeTicks = 0 as longinteger, forceMp3 = false as boolean) params = { "UserId": m.global.session.user.id, "StartTimeTicks": startTimeTicks, @@ -49,24 +49,14 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT ' TODO: Remove this after server adds support for transcoding AAC from one profile to another if selectedAudioStream.Codec <> invalid and LCase(selectedAudioStream.Codec) = "aac" if selectedAudioStream.Profile <> invalid and LCase(selectedAudioStream.Profile) = "main" or LCase(selectedAudioStream.Profile) = "he-aac" - for each rule in deviceProfile.TranscodingProfiles - if rule.Container = "ts" or rule.Container = "mp4" - if rule.AudioCodec = "aac" - rule.AudioCodec = "mp3" - else if rule.AudioCodec.Left(4) = "aac," - rule.AudioCodec = mid(rule.AudioCodec, 5) - - if rule.AudioCodec.Left(3) <> "mp3" - rule.AudioCodec = "mp3," + rule.AudioCodec - end if - end if - end if - end for + forceMp3 = true end if end if end if end if + if forceMp3 then forceMp3Audio(deviceProfile) + req = APIRequest(Substitute("Items/{0}/PlaybackInfo", id), params) req.SetRequest("POST") return postJson(req, FormatJson({ "DeviceProfile": deviceProfile })) @@ -538,3 +528,20 @@ function TVEpisodeShuffleList(show_id as string) return data end function + +' updates the device profile we send the server to force mp3 audio transcoding instead of the default aac +sub forceMp3Audio(deviceProfile as object) + for each rule in deviceProfile.TranscodingProfiles + if rule.Container = "ts" or rule.Container = "mp4" + if rule.AudioCodec = "aac" + rule.AudioCodec = "mp3" + else if rule.AudioCodec.Left(4) = "aac," + rule.AudioCodec = mid(rule.AudioCodec, 5) + + if rule.AudioCodec.Left(3) <> "mp3" + rule.AudioCodec = "mp3," + rule.AudioCodec + end if + end if + end if + end for +end sub From c764252ccbc5272fca0f40e6e46f0d915c9544c3 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Wed, 20 Nov 2024 01:48:52 +0000 Subject: [PATCH 28/29] Update API docs --- ...ents_ItemGrid_LoadVideoContentTask.bs.html | 5 +-- .../components_video_VideoPlayerView.bs.html | 14 +++++++- docs/api/data/search.json | 2 +- docs/api/module-Items.html | 2 +- docs/api/source_api_Items.bs.html | 35 +++++++++++-------- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html b/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html index ebfac1cd9..bcc45e19a 100644 --- a/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html +++ b/docs/api/components_ItemGrid_LoadVideoContentTask.bs.html @@ -56,6 +56,7 @@ forceTranscoding = false m.top.content = [LoadItems_VideoPlayer(id, mediaSourceId, audio_stream_idx, forceTranscoding)] + m.top.forceMp3 = false end sub function LoadItems_VideoPlayer(id as string, mediaSourceId = invalid as dynamic, audio_stream_idx = 1 as integer, forceTranscoding = false as boolean) as dynamic @@ -174,7 +175,7 @@ if not isValid(mediaSourceId) then mediaSourceId = video.id if meta.live then mediaSourceId = "" - m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition) + m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition, m.top.forceMp3) if not isValid(m.playbackInfo) video.errorMsg = "Error loading playback info" video.content = invalid @@ -191,7 +192,7 @@ video.SelectedSubtitle = defaultSubtitleIndex subtitle_idx = defaultSubtitleIndex - m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition) + m.playbackInfo = ItemPostPlaybackInfo(video.id, mediaSourceId, audio_stream_idx, subtitle_idx, playbackPosition, m.top.forceMp3) if not isValid(m.playbackInfo) video.errorMsg = "Error loading playback info" video.content = invalid diff --git a/docs/api/components_video_VideoPlayerView.bs.html b/docs/api/components_video_VideoPlayerView.bs.html index 4b7247f53..2320be3fc 100644 --- a/docs/api/components_video_VideoPlayerView.bs.html +++ b/docs/api/components_video_VideoPlayerView.bs.html @@ -36,7 +36,6 @@ m.playbackTimer = m.top.findNode("playbackTimer") m.bufferCheckTimer = m.top.findNode("bufferCheckTimer") - m.top.observeField("state", "onState") m.top.observeField("content", "onContentChange") m.top.observeField("selectedSubtitle", "onSubtitleChange") m.top.observeField("audioIndex", "onAudioIndexChange") @@ -399,6 +398,8 @@ return end if + m.top.observeField("state", "onState") + m.top.content = videoContent[0].content m.top.PlaySessionId = videoContent[0].PlaySessionId m.top.videoId = videoContent[0].id @@ -641,6 +642,17 @@ if not m.playReported and m.top.transcodeAvailable m.top.retryWithTranscoding = true ' If playback was not reported, retry with transcoding + else if m.top.errorStr = "decoder:pump:Unsupported AAC stream." + m.log.info("retrying video with mp3 audio stream", m.currentItem.id, m.top.SelectedSubtitle, m.top.audioIndex) + + m.top.unobserveField("state") + m.LoadMetaDataTask.forceMp3 = true + m.LoadMetaDataTask.selectedSubtitleIndex = m.top.SelectedSubtitle + m.LoadMetaDataTask.selectedAudioStreamIndex = m.top.audioIndex + m.LoadMetaDataTask.itemId = m.currentItem.id + m.LoadMetaDataTask.observeField("content", "onVideoContentLoaded") + + m.LoadMetaDataTask.control = "RUN" else ' If an error was encountered, Display dialog showPlaybackErrorDialog(tr("Error During Playback")) diff --git a/docs/api/data/search.json b/docs/api/data/search.json index 3f2624923..1c23dfd60 100644 --- a/docs/api/data/search.json +++ b/docs/api/data/search.json @@ -1 +1 @@ -{"list":[{"title":"module:AlbumData","link":"AlbumData"},{"title":"module:AlbumData.setFields","link":"setFields"},{"title":"module:AlbumGrid","link":"AlbumGrid"},{"title":"module:AlbumGrid.getData","link":"getData"},{"title":"module:AlbumGrid.init","link":"init"},{"title":"module:AlbumGrid.onKeyEvent","link":"onKeyEvent"},{"title":"module:AlbumTrackList","link":"AlbumTrackList"},{"title":"module:AlbumTrackList.getData","link":"getData"},{"title":"module:AlbumTrackList.init","link":"init"},{"title":"module:AlbumView","link":"AlbumView"},{"title":"module:AlbumView.adjustScreenForNoOverview","link":"adjustScreenForNoOverview","description":"

Adjust scene by removing overview node and showing more songs

"},{"title":"module:AlbumView.createDialogPallete","link":"createDialogPallete"},{"title":"module:AlbumView.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:AlbumView.init","link":"init"},{"title":"module:AlbumView.onDoneLoading","link":"onDoneLoading"},{"title":"module:AlbumView.onKeyEvent","link":"onKeyEvent"},{"title":"module:AlbumView.pageContentChanged","link":"pageContentChanged","description":"

Set values for displayed values on screen

"},{"title":"module:AlbumView.setOnScreenTextValues","link":"setOnScreenTextValues","description":"

Populate on screen text variables

"},{"title":"module:AlbumView.setPosterImage","link":"setPosterImage","description":"

Set poster image on screen

"},{"title":"module:AlbumView.setScreenTitle","link":"setScreenTitle","description":"

Set screen's title text

"},{"title":"module:AlbumView.setupMainNode","link":"setupMainNode"},{"title":"module:Alpha","link":"Alpha"},{"title":"module:Alpha.init","link":"init"},{"title":"module:Alpha.onKeyEvent","link":"onKeyEvent"},{"title":"module:ArtistView","link":"ArtistView"},{"title":"module:ArtistView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:ArtistView.OnScreenShown","link":"OnScreenShown"},{"title":"module:ArtistView.artistOverviewChanged","link":"artistOverviewChanged","description":"

Event fired when page data is loaded

"},{"title":"module:ArtistView.createDialogPallete","link":"createDialogPallete"},{"title":"module:ArtistView.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:ArtistView.dscrShowFocus","link":"dscrShowFocus"},{"title":"module:ArtistView.init","link":"init"},{"title":"module:ArtistView.onAlbumsData","link":"onAlbumsData"},{"title":"module:ArtistView.onAlbumsEscape","link":"onAlbumsEscape"},{"title":"module:ArtistView.onAppearsOnData","link":"onAppearsOnData"},{"title":"module:ArtistView.onAppearsOnEscape","link":"onAppearsOnEscape"},{"title":"module:ArtistView.onBackdropImageLoaded","link":"onBackdropImageLoaded"},{"title":"module:ArtistView.onButtonSelectedChange","link":"onButtonSelectedChange","description":"

Event handler when user selected a different playback button

"},{"title":"module:ArtistView.onEllipsisChanged","link":"onEllipsisChanged"},{"title":"module:ArtistView.onKeyEvent","link":"onKeyEvent"},{"title":"module:ArtistView.onSectionNavigationEscape","link":"onSectionNavigationEscape"},{"title":"module:ArtistView.onSectionNavigationSelected","link":"onSectionNavigationSelected"},{"title":"module:ArtistView.onSectionScrollerChange","link":"onSectionScrollerChange"},{"title":"module:ArtistView.pageContentChanged","link":"pageContentChanged","description":"

Event fired when page data is loaded

"},{"title":"module:ArtistView.setBackdropImage","link":"setBackdropImage","description":"

Add backdrop image to screen

"},{"title":"module:ArtistView.setPosterImage","link":"setPosterImage"},{"title":"module:ArtistView.setScreenTitle","link":"setScreenTitle"},{"title":"module:ArtistView.setupButtons","link":"setupButtons","description":"

Setup playback buttons, default to Play button selected

"},{"title":"module:ArtistView.setupMainNode","link":"setupMainNode"},{"title":"module:AudioPlayer","link":"AudioPlayer"},{"title":"module:AudioPlayer.ReportPlayback","link":"ReportPlayback","description":"

Report playback to server

"},{"title":"module:AudioPlayer.audioStateChanged","link":"audioStateChanged","description":"

State Change Event Handler

"},{"title":"module:AudioPlayer.init","link":"init"},{"title":"module:AudioPlayerView","link":"AudioPlayerView"},{"title":"module:AudioPlayerView.LoadNextSong","link":"LoadNextSong"},{"title":"module:AudioPlayerView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:AudioPlayerView.audioPositionChanged","link":"audioPositionChanged"},{"title":"module:AudioPlayerView.audioStateChanged","link":"audioStateChanged"},{"title":"module:AudioPlayerView.bufferPositionChanged","link":"bufferPositionChanged"},{"title":"module:AudioPlayerView.endScreenSaver","link":"endScreenSaver"},{"title":"module:AudioPlayerView.exitScrubMode","link":"exitScrubMode","description":"

exitScrubMode: Moves player out of scrub mode state, resets back to standard play mode

"},{"title":"module:AudioPlayerView.findCurrentSongIndex","link":"findCurrentSongIndex"},{"title":"module:AudioPlayerView.init","link":"init"},{"title":"module:AudioPlayerView.loadButtons","link":"loadButtons","description":"

If we have more and 1 song to play, fade in the next and previous controls

"},{"title":"module:AudioPlayerView.loopClicked","link":"loopClicked"},{"title":"module:AudioPlayerView.moveSeekbarThumb","link":"moveSeekbarThumb","description":"

moveSeekbarThumb: Positions the thumb on the seekbar

"},{"title":"module:AudioPlayerView.nextClicked","link":"nextClicked"},{"title":"module:AudioPlayerView.onAudioStreamLoaded","link":"onAudioStreamLoaded"},{"title":"module:AudioPlayerView.onBackdropImageLoaded","link":"onBackdropImageLoaded"},{"title":"module:AudioPlayerView.onButtonSelectedChange","link":"onButtonSelectedChange","description":"

Event handler when user selected a different playback button

"},{"title":"module:AudioPlayerView.onKeyEvent","link":"onKeyEvent","description":"

Process key press events

"},{"title":"module:AudioPlayerView.onMetaDataLoaded","link":"onMetaDataLoaded"},{"title":"module:AudioPlayerView.onScreensaverTimeoutLoaded","link":"onScreensaverTimeoutLoaded"},{"title":"module:AudioPlayerView.pageContentChanged","link":"pageContentChanged","description":"

Update values on screen when page content changes

"},{"title":"module:AudioPlayerView.playAction","link":"playAction"},{"title":"module:AudioPlayerView.previousClicked","link":"previousClicked"},{"title":"module:AudioPlayerView.processScrubAction","link":"processScrubAction","description":"

processScrubAction: Handles +/- seeking for the audio trickplay bar

"},{"title":"module:AudioPlayerView.resetLoopModeToDefault","link":"resetLoopModeToDefault"},{"title":"module:AudioPlayerView.resetSeekbarThumb","link":"resetSeekbarThumb","description":"

resetSeekbarThumb: Resets the thumb to the playing position

"},{"title":"module:AudioPlayerView.screenSaverActive","link":"screenSaverActive"},{"title":"module:AudioPlayerView.setBackdropImage","link":"setBackdropImage","description":"

Add backdrop image to screen

"},{"title":"module:AudioPlayerView.setLoopButtonImage","link":"setLoopButtonImage"},{"title":"module:AudioPlayerView.setOnScreenTextValues","link":"setOnScreenTextValues","description":"

Populate on screen text variables

"},{"title":"module:AudioPlayerView.setPosterImage","link":"setPosterImage","description":"

Set poster image on screen

"},{"title":"module:AudioPlayerView.setScreenTitle","link":"setScreenTitle","description":"

Set screen's title text

"},{"title":"module:AudioPlayerView.setSelectedButtonState","link":"setSelectedButtonState","description":"

setSelectedButtonState: Changes the icon state url for the currently selected button

"},{"title":"module:AudioPlayerView.setShuffleIconState","link":"setShuffleIconState"},{"title":"module:AudioPlayerView.setTrackNumberDisplay","link":"setTrackNumberDisplay"},{"title":"module:AudioPlayerView.setupAnimationTasks","link":"setupAnimationTasks"},{"title":"module:AudioPlayerView.setupButtons","link":"setupButtons","description":"

Setup playback buttons, default to Play button selected

"},{"title":"module:AudioPlayerView.setupDataTasks","link":"setupDataTasks","description":"

Creates tasks to gather data needed to render Scene and play song

"},{"title":"module:AudioPlayerView.setupInfoNodes","link":"setupInfoNodes"},{"title":"module:AudioPlayerView.setupScreenSaver","link":"setupScreenSaver"},{"title":"module:AudioPlayerView.shuffleClicked","link":"shuffleClicked"},{"title":"module:AudioPlayerView.startScreenSaver","link":"startScreenSaver"},{"title":"module:AudioPlayerView.toggleShuffleEnabled","link":"toggleShuffleEnabled"},{"title":"module:AudioTrackListItem","link":"AudioTrackListItem"},{"title":"module:AudioTrackListItem.focusChanged","link":"focusChanged","description":"

Scroll description if focused

"},{"title":"module:AudioTrackListItem.init","link":"init"},{"title":"module:AudioTrackListItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:ButtonGroupHoriz","link":"ButtonGroupHoriz"},{"title":"module:ButtonGroupHoriz.init","link":"init"},{"title":"module:ButtonGroupHoriz.onKeyEvent","link":"onKeyEvent"},{"title":"module:ButtonGroupVert","link":"ButtonGroupVert"},{"title":"module:ButtonGroupVert.init","link":"init"},{"title":"module:ButtonGroupVert.onFocusButtonChanged","link":"onFocusButtonChanged"},{"title":"module:ButtonGroupVert.onFocusChanged","link":"onFocusChanged"},{"title":"module:ButtonGroupVert.onKeyEvent","link":"onKeyEvent"},{"title":"module:ChannelData","link":"ChannelData"},{"title":"module:ChannelData.setFields","link":"setFields"},{"title":"module:ChannelData.setPoster","link":"setPoster"},{"title":"module:Clock","link":"Clock"},{"title":"module:Clock.ClockFormat","link":"ClockFormat","description":"

Possible clock formats

"},{"title":"module:Clock.ClockFormat.h12","link":"h12"},{"title":"module:Clock.ClockFormat.h24","link":"h24"},{"title":"module:Clock.format12HourTime","link":"format12HourTime","description":"

format12HourTime: Returns a string with the current time formatted for a 12 hour clock

"},{"title":"module:Clock.format24HourTime","link":"format24HourTime","description":"

format24HourTime: Returns a string with the current time formatted for a 24 hour clock

"},{"title":"module:Clock.formatTimeAsString","link":"formatTimeAsString","description":"

formatTimeAsString: Returns a string with the current time formatted for either a 12 or 24 hour clock

"},{"title":"module:Clock.init","link":"init"},{"title":"module:Clock.onCurrentTimeTimerFire","link":"onCurrentTimeTimerFire","description":"

onCurrentTimeTimerFire: Code that runs every time the currentTimeTimer fires

"},{"title":"module:CollectionData","link":"CollectionData"},{"title":"module:CollectionData.setFields","link":"setFields"},{"title":"module:CollectionData.setPoster","link":"setPoster"},{"title":"module:ConfigData","link":"ConfigData"},{"title":"module:ConfigData.init","link":"init"},{"title":"module:ConfigItem","link":"ConfigItem"},{"title":"module:ConfigItem.init","link":"init"},{"title":"module:ConfigItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:ConfigItem.setColors","link":"setColors"},{"title":"module:ConfigList","link":"ConfigList"},{"title":"module:ConfigList.configListShowDialog","link":"configListShowDialog"},{"title":"module:ConfigList.dismiss_dialog","link":"dismiss_dialog"},{"title":"module:ConfigList.init","link":"init"},{"title":"module:ConfigList.onDialogButton","link":"onDialogButton"},{"title":"module:ConfigList.onItemSelected","link":"onItemSelected"},{"title":"module:ConfigList.setData","link":"setData"},{"title":"module:ExtrasItem","link":"ExtrasItem"},{"title":"module:ExtrasItem.focusChanged","link":"focusChanged"},{"title":"module:ExtrasItem.init","link":"init"},{"title":"module:ExtrasItem.initName","link":"initName"},{"title":"module:ExtrasItem.initPosterImg","link":"initPosterImg"},{"title":"module:ExtrasItem.initRole","link":"initRole"},{"title":"module:ExtrasItem.showContent","link":"showContent"},{"title":"module:ExtrasRowList","link":"ExtrasRowList"},{"title":"module:ExtrasRowList.addRowSize","link":"addRowSize"},{"title":"module:ExtrasRowList.buildRow","link":"buildRow"},{"title":"module:ExtrasRowList.init","link":"init"},{"title":"module:ExtrasRowList.loadParts","link":"loadParts"},{"title":"module:ExtrasRowList.loadPersonVideos","link":"loadPersonVideos"},{"title":"module:ExtrasRowList.onAdditionalPartsLoaded","link":"onAdditionalPartsLoaded"},{"title":"module:ExtrasRowList.onLikeThisLoaded","link":"onLikeThisLoaded"},{"title":"module:ExtrasRowList.onMoviesLoaded","link":"onMoviesLoaded"},{"title":"module:ExtrasRowList.onPeopleLoaded","link":"onPeopleLoaded"},{"title":"module:ExtrasRowList.onRowItemFocused","link":"onRowItemFocused"},{"title":"module:ExtrasRowList.onRowItemSelected","link":"onRowItemSelected"},{"title":"module:ExtrasRowList.onSeriesLoaded","link":"onSeriesLoaded"},{"title":"module:ExtrasRowList.onShowsLoaded","link":"onShowsLoaded"},{"title":"module:ExtrasRowList.onSpecialFeaturesLoaded","link":"onSpecialFeaturesLoaded"},{"title":"module:ExtrasRowList.showOrHideMe","link":"showOrHideMe","description":"

don't show popup panel if there is nothing to show

"},{"title":"module:ExtrasRowList.updateSize","link":"updateSize"},{"title":"module:FavoriteItemsTask","link":"FavoriteItemsTask"},{"title":"module:FavoriteItemsTask.init","link":"init"},{"title":"module:FavoriteItemsTask.setFavoriteStatus","link":"setFavoriteStatus"},{"title":"module:FolderData","link":"FolderData"},{"title":"module:FolderData.setFields","link":"setFields"},{"title":"module:FolderData.setPoster","link":"setPoster"},{"title":"module:GetFiltersTask","link":"GetFiltersTask"},{"title":"module:GetFiltersTask.getFiltersTask","link":"getFiltersTask"},{"title":"module:GetFiltersTask.init","link":"init"},{"title":"module:GetNextEpisodeTask","link":"GetNextEpisodeTask"},{"title":"module:GetNextEpisodeTask.getNextEpisodeTask","link":"getNextEpisodeTask"},{"title":"module:GetNextEpisodeTask.init","link":"init"},{"title":"module:GetPlaybackInfoTask","link":"GetPlaybackInfoTask"},{"title":"module:GetPlaybackInfoTask.GetTranscodingStats","link":"GetTranscodingStats"},{"title":"module:GetPlaybackInfoTask.ItemPostPlaybackInfo","link":"ItemPostPlaybackInfo"},{"title":"module:GetPlaybackInfoTask.getDisplayBitrate","link":"getDisplayBitrate"},{"title":"module:GetPlaybackInfoTask.getPlaybackInfoTask","link":"getPlaybackInfoTask","description":"

Returns an array of playback info to be displayed during playback.\nIn the future, with a custom playback info view, we can return an associated array.

"},{"title":"module:GetPlaybackInfoTask.havePlaybackInfo","link":"havePlaybackInfo"},{"title":"module:GetPlaybackInfoTask.init","link":"init"},{"title":"module:GetShuffleEpisodesTask","link":"GetShuffleEpisodesTask"},{"title":"module:GetShuffleEpisodesTask.getShuffleEpisodesTask","link":"getShuffleEpisodesTask"},{"title":"module:GetShuffleEpisodesTask.init","link":"init"},{"title":"module:GridItem","link":"GridItem"},{"title":"module:GridItem.focusChanged","link":"focusChanged","description":"

Display or hide title Visibility on focus change

"},{"title":"module:GridItem.focusChanging","link":"focusChanging","description":"

Use FocusPercent to animate scaling of Poser Image

"},{"title":"module:GridItem.init","link":"init"},{"title":"module:GridItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:GridItem.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and text when poster loaded

"},{"title":"module:GridItemSmall","link":"GridItemSmall"},{"title":"module:GridItemSmall.focusChanged","link":"focusChanged"},{"title":"module:GridItemSmall.init","link":"init"},{"title":"module:GridItemSmall.initTitle","link":"initTitle"},{"title":"module:GridItemSmall.itemContentChanged","link":"itemContentChanged"},{"title":"module:GridItemSmall.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and text when poster loaded

"},{"title":"module:Home","link":"Home"},{"title":"module:Home.OnScreenHidden","link":"OnScreenHidden","description":"

JFScreen hook called when the screen is hidden by the screen manager

"},{"title":"module:Home.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook called when the screen is displayed by the screen manager

"},{"title":"module:Home.init","link":"init"},{"title":"module:Home.loadLibraries","link":"loadLibraries"},{"title":"module:Home.postFinished","link":"postFinished","description":"

Triggered by m.postTask after completing a post.\nEmpty the task data when finished.

"},{"title":"module:Home.refresh","link":"refresh"},{"title":"module:HomeData","link":"HomeData"},{"title":"module:HomeData.setData","link":"setData"},{"title":"module:HomeItem","link":"HomeItem"},{"title":"module:HomeItem.drawProgressBar","link":"drawProgressBar","description":"

Draws and animates item progress bar

"},{"title":"module:HomeItem.focusChanged","link":"focusChanged","description":"

Enable title scrolling based on item Focus

"},{"title":"module:HomeItem.init","link":"init"},{"title":"module:HomeItem.initBackdrop","link":"initBackdrop"},{"title":"module:HomeItem.initItemIcon","link":"initItemIcon"},{"title":"module:HomeItem.initItemPoster","link":"initItemPoster"},{"title":"module:HomeItem.initItemText","link":"initItemText"},{"title":"module:HomeItem.initItemTextExtra","link":"initItemTextExtra"},{"title":"module:HomeItem.initPlayedIndicator","link":"initPlayedIndicator"},{"title":"module:HomeItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:HomeItem.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and icon when poster loaded

"},{"title":"module:HomeRows","link":"HomeRows"},{"title":"module:HomeRows.LOADING_WAIT_TIME","link":"LOADING_WAIT_TIME"},{"title":"module:HomeRows.addHomeSection","link":"addHomeSection","description":"

addHomeSection: Adds a new home section to the home rows.

"},{"title":"module:HomeRows.createContinueWatchingRow","link":"createContinueWatchingRow","description":"

createContinueWatchingRow: Creates a row displaying items the user can continue watching

"},{"title":"module:HomeRows.createFavoritesRow","link":"createFavoritesRow","description":"

createFavoritesRow: Creates a row displaying items from the user's favorites list

"},{"title":"module:HomeRows.createLatestInRows","link":"createLatestInRows","description":"

createLatestInRows: Creates a row displaying latest items in each of the user's libraries

"},{"title":"module:HomeRows.createLibraryRow","link":"createLibraryRow","description":"

createLibraryRow: Creates a row displaying the user's libraries

"},{"title":"module:HomeRows.createLiveTVRow","link":"createLiveTVRow","description":"

createLiveTVRow: Creates a row displaying the live tv now on section

"},{"title":"module:HomeRows.createNextUpRow","link":"createNextUpRow","description":"

createNextUpRow: Creates a row displaying next episodes up to watch

"},{"title":"module:HomeRows.filterNodeArray","link":"filterNodeArray"},{"title":"module:HomeRows.getOriginalSectionIndex","link":"getOriginalSectionIndex","description":"

getOriginalSectionIndex: Gets the index of a section from user settings and adds count of currently known latest media sections

"},{"title":"module:HomeRows.getSectionIndex","link":"getSectionIndex","description":"

getSectionIndex: Returns index of requested section in home row content

"},{"title":"module:HomeRows.init","link":"init"},{"title":"module:HomeRows.itemSelected","link":"itemSelected"},{"title":"module:HomeRows.loadLibraries","link":"loadLibraries"},{"title":"module:HomeRows.loadingTimerComplete","link":"loadingTimerComplete","description":"

loadingTimerComplete: Event handler for when loading wait time has expired

"},{"title":"module:HomeRows.onKeyEvent","link":"onKeyEvent"},{"title":"module:HomeRows.onLibrariesLoaded","link":"onLibrariesLoaded","description":"

onLibrariesLoaded: Handler when LoadLibrariesTask returns data

"},{"title":"module:HomeRows.processUserSections","link":"processUserSections","description":"

processUserSections: Loop through user's chosen home section settings and generate the content for each row

"},{"title":"module:HomeRows.removeHomeSection","link":"removeHomeSection","description":"

removeHomeSection: Removes a home section from the home rows

"},{"title":"module:HomeRows.sectionExists","link":"sectionExists","description":"

sectionExists: Checks if passed section exists in home row content

"},{"title":"module:HomeRows.setRowItemSize","link":"setRowItemSize","description":"

setRowItemSize: Loops through all home sections and sets the correct item sizes per row

"},{"title":"module:HomeRows.updateContinueWatchingItems","link":"updateContinueWatchingItems","description":"

updateContinueWatchingItems: Processes LoadContinueWatchingTask content. Removes, Creates, or Updates continue watching row as needed

"},{"title":"module:HomeRows.updateFavoritesItems","link":"updateFavoritesItems","description":"

updateFavoritesItems: Processes LoadFavoritesTask content. Removes, Creates, or Updates favorites row as needed

"},{"title":"module:HomeRows.updateHomeRows","link":"updateHomeRows","description":"

updateHomeRows: Update function exposed to outside components

"},{"title":"module:HomeRows.updateLatestItems","link":"updateLatestItems","description":"

updateLatestItems: Processes LoadItemsTask content. Removes, Creates, or Updates latest in {library} row as needed

"},{"title":"module:HomeRows.updateNextUpItems","link":"updateNextUpItems","description":"

updateNextUpItems: Processes LoadNextUpTask content. Removes, Creates, or Updates next up row as needed

"},{"title":"module:HomeRows.updateOnNowItems","link":"updateOnNowItems","description":"

updateOnNowItems: Processes LoadOnNowTask content. Removes, Creates, or Updates latest in on now row as needed

"},{"title":"module:HomeRows.updateSize","link":"updateSize"},{"title":"module:IconButton","link":"IconButton"},{"title":"module:IconButton.init","link":"init"},{"title":"module:IconButton.onBackgroundChanged","link":"onBackgroundChanged"},{"title":"module:IconButton.onFocusChanged","link":"onFocusChanged"},{"title":"module:IconButton.onHeightChanged","link":"onHeightChanged"},{"title":"module:IconButton.onIconChanged","link":"onIconChanged"},{"title":"module:IconButton.onKeyEvent","link":"onKeyEvent"},{"title":"module:IconButton.onPaddingChanged","link":"onPaddingChanged"},{"title":"module:IconButton.onTextChanged","link":"onTextChanged"},{"title":"module:IconButton.onWidthChanged","link":"onWidthChanged"},{"title":"module:IconButton.setIconSize","link":"setIconSize"},{"title":"module:Image","link":"Image"},{"title":"module:Image.ImageURL","link":"ImageURL"},{"title":"module:Image.ItemImages","link":"ItemImages"},{"title":"module:Image.PosterImage","link":"PosterImage"},{"title":"module:Image.UserImageURL","link":"UserImageURL"},{"title":"module:ImageData","link":"ImageData"},{"title":"module:ImageData.setFields","link":"setFields"},{"title":"module:IntegerKeyboard","link":"IntegerKeyboard"},{"title":"module:IntegerKeyboard.init","link":"init"},{"title":"module:IntegerKeyboard.keySelected","link":"keySelected"},{"title":"module:IntegerKeyboard.onKeyEvent","link":"onKeyEvent"},{"title":"module:ItemGrid","link":"ItemGrid"},{"title":"module:ItemGrid.ItemDataLoaded","link":"ItemDataLoaded","description":"

Handle loaded data, and add to Grid

"},{"title":"module:ItemGrid.SetBackground","link":"SetBackground","description":"

Set Background Image

"},{"title":"module:ItemGrid.SetUpOptions","link":"SetUpOptions","description":"

Data to display when options button selected

"},{"title":"module:ItemGrid.alphaActiveChanged","link":"alphaActiveChanged"},{"title":"module:ItemGrid.alphaSelectedChanged","link":"alphaSelectedChanged"},{"title":"module:ItemGrid.getCollectionType","link":"getCollectionType","description":"

Return parent collection type

"},{"title":"module:ItemGrid.getItemFocused","link":"getItemFocused","description":"

Returns Focused Item

"},{"title":"module:ItemGrid.inStringArray","link":"inStringArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:ItemGrid.init","link":"init"},{"title":"module:ItemGrid.loadInitialItems","link":"loadInitialItems","description":"

Load initial set of Data

"},{"title":"module:ItemGrid.loadMoreData","link":"loadMoreData","description":"

Load next set of items

"},{"title":"module:ItemGrid.newBGLoaded","link":"newBGLoaded","description":"

When Image Loading Status changes

"},{"title":"module:ItemGrid.onChannelFocused","link":"onChannelFocused"},{"title":"module:ItemGrid.onChannelSelected","link":"onChannelSelected"},{"title":"module:ItemGrid.onGenreItemSelected","link":"onGenreItemSelected","description":"

Genre Item Selected

"},{"title":"module:ItemGrid.onItemFocused","link":"onItemFocused","description":"

Handle new item being focused

"},{"title":"module:ItemGrid.onItemSelected","link":"onItemSelected","description":"

Item Selected

"},{"title":"module:ItemGrid.onKeyEvent","link":"onKeyEvent"},{"title":"module:ItemGrid.onvoiceFilter","link":"onvoiceFilter"},{"title":"module:ItemGrid.optionsClosed","link":"optionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:ItemGrid.setBoxsetsOptions","link":"setBoxsetsOptions","description":"

Set Boxset view, sort, and filter options

"},{"title":"module:ItemGrid.setDefaultOptions","link":"setDefaultOptions","description":"

Set Default view, sort, and filter options

"},{"title":"module:ItemGrid.setLiveTvOptions","link":"setLiveTvOptions","description":"

Set Live TV view, sort, and filter options

"},{"title":"module:ItemGrid.setMoviesOptions","link":"setMoviesOptions","description":"

Set Movies view, sort, and filter options

"},{"title":"module:ItemGrid.setMusicOptions","link":"setMusicOptions","description":"

Set Music view, sort, and filter options

"},{"title":"module:ItemGrid.setPhotoAlbumOptions","link":"setPhotoAlbumOptions","description":"

Set Photo Album view, sort, and filter options

"},{"title":"module:ItemGrid.setTvShowsOptions","link":"setTvShowsOptions","description":"

Set TV Show view, sort, and filter options

"},{"title":"module:ItemGrid.showTVGuide","link":"showTVGuide"},{"title":"module:ItemGrid.swapDone","link":"swapDone","description":"

Swap Complete

"},{"title":"module:ItemGrid.updateTitle","link":"updateTitle"},{"title":"module:ItemGridOptions","link":"ItemGridOptions"},{"title":"module:ItemGridOptions.buttonFocusChanged","link":"buttonFocusChanged","description":"

Switch menu shown when button focus changes

"},{"title":"module:ItemGridOptions.hideChecklist","link":"hideChecklist"},{"title":"module:ItemGridOptions.init","link":"init"},{"title":"module:ItemGridOptions.isFilterMenuDataValid","link":"isFilterMenuDataValid","description":"

Check if data for Filter Menu is valid

"},{"title":"module:ItemGridOptions.onFilterFocusChange","link":"onFilterFocusChange"},{"title":"module:ItemGridOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:ItemGridOptions.optionsSet","link":"optionsSet"},{"title":"module:ItemGridOptions.saveFavoriteItemSelected","link":"saveFavoriteItemSelected"},{"title":"module:ItemGridOptions.setHeartColor","link":"setHeartColor"},{"title":"module:ItemGridOptions.showChecklist","link":"showChecklist"},{"title":"module:ItemGridOptions.toggleFavorite","link":"toggleFavorite"},{"title":"module:Items","link":"Items"},{"title":"module:Items.AppearsOnList","link":"AppearsOnList","description":"

Get list of albums an artist appears on

"},{"title":"module:Items.ArtistOverview","link":"ArtistOverview","description":"

Music Artist Data

"},{"title":"module:Items.AudioItem","link":"AudioItem","description":"

Get Songs that are on an Album

"},{"title":"module:Items.AudioStream","link":"AudioStream"},{"title":"module:Items.BackdropImage","link":"BackdropImage"},{"title":"module:Items.CreateArtistMix","link":"CreateArtistMix","description":"

Get Instant Mix based on item

"},{"title":"module:Items.CreateInstantMix","link":"CreateInstantMix","description":"

Get Instant Mix based on item

"},{"title":"module:Items.GetIntroVideos","link":"GetIntroVideos","description":"

Get Intro Videos for an item

"},{"title":"module:Items.GetSongsByArtist","link":"GetSongsByArtist","description":"

Get list of songs belonging to an artist

"},{"title":"module:Items.ItemGetPlaybackInfo","link":"ItemGetPlaybackInfo"},{"title":"module:Items.ItemMetaData","link":"ItemMetaData","description":"

MetaData about an item

"},{"title":"module:Items.ItemPostPlaybackInfo","link":"ItemPostPlaybackInfo"},{"title":"module:Items.MusicAlbumList","link":"MusicAlbumList","description":"

Get list of albums belonging to an artist

"},{"title":"module:Items.MusicSongList","link":"MusicSongList","description":"

Get Songs that are on an Album

"},{"title":"module:Items.PlaylistItemList","link":"PlaylistItemList","description":"

Get Items that are under the provided item

"},{"title":"module:Items.TVEpisodeShuffleList","link":"TVEpisodeShuffleList"},{"title":"module:Items.TVEpisodes","link":"TVEpisodes","description":"

Returns a list of TV Shows for a given TV Show and season\nAccepts strings for the TV Show Id and the season Id

"},{"title":"module:Items.TVSeasonExtras","link":"TVSeasonExtras","description":"

Returns a list of extra features for a TV Show season\nAccepts a string that is a TV Show season id

"},{"title":"module:Items.TVSeasons","link":"TVSeasons","description":"

Seasons for a TV Show

"},{"title":"module:Items.searchMedia","link":"searchMedia","description":"

Search across all libraries

"},{"title":"module:Items.useTranscodeAudioStream","link":"useTranscodeAudioStream"},{"title":"module:JFButton","link":"JFButton"},{"title":"module:JFButton.init","link":"init"},{"title":"module:JFButton.onTextChanged","link":"onTextChanged","description":"

Whenever the text changes, pad both sides with whitespace so we can center the button text

"},{"title":"module:JFButtons","link":"JFButtons"},{"title":"module:JFButtons.focusChanged","link":"focusChanged","description":"

Change opacity of the highlighted menu item based on focus

"},{"title":"module:JFButtons.highlightSelected","link":"highlightSelected","description":"

Highlight selected menu option

"},{"title":"module:JFButtons.init","link":"init"},{"title":"module:JFButtons.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFButtons.renderChanged","link":"renderChanged","description":"

When options are fully displayed, set focus and selected option

"},{"title":"module:JFButtons.selectedIndexChanged","link":"selectedIndexChanged","description":"

When Selected Index set, ensure it is the one Focused

"},{"title":"module:JFButtons.showButtons","link":"showButtons"},{"title":"module:JFButtons.updateButtons","link":"updateButtons"},{"title":"module:JFContentItem","link":"JFContentItem"},{"title":"module:JFContentItem.setFields","link":"setFields","description":"

Called whenever m.top.json changes.\nIt is expected that each node that extends JFContentItem will override this function

"},{"title":"module:JFGroup","link":"JFGroup"},{"title":"module:JFGroup.init","link":"init"},{"title":"module:JFGroup.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFMessageDialog","link":"JFMessageDialog"},{"title":"module:JFMessageDialog.init","link":"init"},{"title":"module:JFMessageDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFMessageDialog.redraw","link":"redraw"},{"title":"module:JFMessageDialog.updateMessage","link":"updateMessage"},{"title":"module:JFMessageDialog.updateOptions","link":"updateOptions"},{"title":"module:JFOverhang","link":"JFOverhang"},{"title":"module:JFOverhang.init","link":"init"},{"title":"module:JFOverhang.isLogoVisibleChange","link":"isLogoVisibleChange","description":"

component boolean field isLogoVisibleChange has changed value

"},{"title":"module:JFOverhang.onVisibleChange","link":"onVisibleChange"},{"title":"module:JFOverhang.resetTime","link":"resetTime"},{"title":"module:JFOverhang.setClockVisibility","link":"setClockVisibility"},{"title":"module:JFOverhang.setRightSeperatorVisibility","link":"setRightSeperatorVisibility"},{"title":"module:JFOverhang.updateOptions","link":"updateOptions"},{"title":"module:JFOverhang.updateTime","link":"updateTime"},{"title":"module:JFOverhang.updateTimeDisplay","link":"updateTimeDisplay"},{"title":"module:JFOverhang.updateTitle","link":"updateTitle"},{"title":"module:JFOverhang.updateUser","link":"updateUser"},{"title":"module:JFScene","link":"JFScene"},{"title":"module:JFScene.disableRemoteChanged","link":"disableRemoteChanged","description":"

Triggered when the disableRemote boolean component field is changed

"},{"title":"module:JFScene.init","link":"init"},{"title":"module:JFScene.isLoadingChanged","link":"isLoadingChanged","description":"

Triggered when the isLoading boolean component field is changed

"},{"title":"module:JFScene.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFScreen","link":"JFScreen"},{"title":"module:JFScreen.OnScreenHidden","link":"OnScreenHidden","description":"

Function called when the screen is hidden by the screen manager\nIt is expected that screens override this function if required,\nto handle focus any actions required on the screen being hidden

"},{"title":"module:JFScreen.OnScreenShown","link":"OnScreenShown","description":"

Function called when the screen is displayed by the screen manager\nIt is expected that screens override this function to handle focus\nmanagmenet and any other actions required on screen shown

"},{"title":"module:JFScreen.init","link":"init"},{"title":"module:JFServer","link":"JFServer"},{"title":"module:JFServer.init","link":"init"},{"title":"module:JFServer.itemContentChanged","link":"itemContentChanged"},{"title":"module:JFServer.onFocusPercentChange","link":"onFocusPercentChange"},{"title":"module:JFServer.setTextColor","link":"setTextColor"},{"title":"module:JFVideo","link":"JFVideo"},{"title":"module:JFVideo.ReportPlayback","link":"ReportPlayback","description":"

Report playback to server

"},{"title":"module:JFVideo.bufferCheck","link":"bufferCheck","description":"

Check the the buffering has not hung

"},{"title":"module:JFVideo.checkTimeToDisplayNextEpisode","link":"checkTimeToDisplayNextEpisode","description":"

Checks if we need to display the Next Episode button

"},{"title":"module:JFVideo.hideNextEpisodeButton","link":"hideNextEpisodeButton","description":"

Runs hide Next Episode button animation and sets focus back to video

"},{"title":"module:JFVideo.init","link":"init"},{"title":"module:JFVideo.loadCaption","link":"loadCaption"},{"title":"module:JFVideo.onAllowCaptionsChange","link":"onAllowCaptionsChange"},{"title":"module:JFVideo.onContentChange","link":"onContentChange","description":"

Event handler for when video content field changes

"},{"title":"module:JFVideo.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFVideo.onNextEpisodeDataLoaded","link":"onNextEpisodeDataLoaded"},{"title":"module:JFVideo.onPositionChanged","link":"onPositionChanged","description":"

When Video Player state changes

"},{"title":"module:JFVideo.onState","link":"onState","description":"

When Video Player state changes

"},{"title":"module:JFVideo.showNextEpisodeButton","link":"showNextEpisodeButton","description":"

Runs Next Episode button animation and sets focus to button

"},{"title":"module:JFVideo.toggleCaption","link":"toggleCaption"},{"title":"module:JFVideo.updateCaption","link":"updateCaption"},{"title":"module:JFVideo.updateCount","link":"updateCount","description":"

Update count down text

"},{"title":"module:ListPoster","link":"ListPoster"},{"title":"module:ListPoster.focusChanged","link":"focusChanged","description":"

Enable title scrolling based on item Focus

"},{"title":"module:ListPoster.init","link":"init"},{"title":"module:ListPoster.itemContentChanged","link":"itemContentChanged"},{"title":"module:ListPoster.updateSize","link":"updateSize"},{"title":"module:LoadChannelsTask","link":"LoadChannelsTask"},{"title":"module:LoadChannelsTask.init","link":"init"},{"title":"module:LoadChannelsTask.loadChannels","link":"loadChannels"},{"title":"module:LoadItemsTask","link":"LoadItemsTask"},{"title":"module:LoadItemsTask.getPersonVideos","link":"getPersonVideos"},{"title":"module:LoadItemsTask.init","link":"init"},{"title":"module:LoadItemsTask.loadItems","link":"loadItems"},{"title":"module:LoadItemsTask2","link":"LoadItemsTask2"},{"title":"module:LoadItemsTask2.init","link":"init"},{"title":"module:LoadItemsTask2.loadItems","link":"loadItems"},{"title":"module:LoadPhotoTask","link":"LoadPhotoTask"},{"title":"module:LoadPhotoTask.init","link":"init"},{"title":"module:LoadPhotoTask.loadItems","link":"loadItems"},{"title":"module:LoadProgramDetailsTask","link":"LoadProgramDetailsTask"},{"title":"module:LoadProgramDetailsTask.init","link":"init"},{"title":"module:LoadProgramDetailsTask.loadProgramDetails","link":"loadProgramDetails"},{"title":"module:LoadScreenSaverTimeoutTask","link":"LoadScreenSaverTimeoutTask"},{"title":"module:LoadScreenSaverTimeoutTask.getScreensaverTimeout","link":"getScreensaverTimeout"},{"title":"module:LoadScreenSaverTimeoutTask.init","link":"init"},{"title":"module:LoadSheduleTask","link":"LoadSheduleTask"},{"title":"module:LoadSheduleTask.init","link":"init"},{"title":"module:LoadSheduleTask.loadSchedule","link":"loadSchedule"},{"title":"module:LoadVideoContentTask","link":"LoadVideoContentTask"},{"title":"module:LoadVideoContentTask.FindPreferredAudioStream","link":"FindPreferredAudioStream"},{"title":"module:LoadVideoContentTask.LoadItems_AddVideoContent","link":"LoadItems_AddVideoContent"},{"title":"module:LoadVideoContentTask.LoadItems_VideoPlayer","link":"LoadItems_VideoPlayer"},{"title":"module:LoadVideoContentTask.SubtitleSelection","link":"SubtitleSelection"},{"title":"module:LoadVideoContentTask.SubtitleSelection.none","link":"none"},{"title":"module:LoadVideoContentTask.SubtitleSelection.notset","link":"notset"},{"title":"module:LoadVideoContentTask.addAudioStreamsToVideo","link":"addAudioStreamsToVideo","description":"

addAudioStreamsToVideo: Add audio stream data to video

"},{"title":"module:LoadVideoContentTask.addNextEpisodesToQueue","link":"addNextEpisodesToQueue","description":"

Add next episodes to the playback queue

"},{"title":"module:LoadVideoContentTask.addSubtitlesToVideo","link":"addSubtitlesToVideo"},{"title":"module:LoadVideoContentTask.addVideoContentURL","link":"addVideoContentURL"},{"title":"module:LoadVideoContentTask.defaultSubtitleTrack","link":"defaultSubtitleTrack","description":"

defaultSubtitleTrack:

"},{"title":"module:LoadVideoContentTask.defaultSubtitleTrackFromVid","link":"defaultSubtitleTrackFromVid","description":"

defaultSubtitleTrackFromVid: Identifies the default subtitle track given video id

"},{"title":"module:LoadVideoContentTask.directPlaySupported","link":"directPlaySupported"},{"title":"module:LoadVideoContentTask.getContainerType","link":"getContainerType"},{"title":"module:LoadVideoContentTask.getTranscodeReasons","link":"getTranscodeReasons","description":"

Extract array of Transcode Reasons from the content URL

"},{"title":"module:LoadVideoContentTask.init","link":"init"},{"title":"module:LoadVideoContentTask.loadItems","link":"loadItems"},{"title":"module:LoadVideoContentTask.sortSubtitles","link":"sortSubtitles","description":"

Checks available subtitle tracks and puts subtitles in forced, default, and non-default/forced but preferred language at the top

"},{"title":"module:LoginScene","link":"LoginScene"},{"title":"module:LoginScene.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook.

"},{"title":"module:LoginScene.init","link":"init"},{"title":"module:LoginScene.onKeyEvent","link":"onKeyEvent"},{"title":"module:Main","link":"Main"},{"title":"module:Main.Main","link":"Main"},{"title":"module:MovieData","link":"MovieData"},{"title":"module:MovieData.setContainer","link":"setContainer"},{"title":"module:MovieData.setFields","link":"setFields"},{"title":"module:MovieData.setPoster","link":"setPoster"},{"title":"module:MovieDetails","link":"MovieDetails"},{"title":"module:MovieDetails.OnScreenShown","link":"OnScreenShown","description":"

OnScreenShown: Callback function when view is presented on screen

"},{"title":"module:MovieDetails.SetDefaultAudioTrack","link":"SetDefaultAudioTrack"},{"title":"module:MovieDetails.SetUpAudioOptions","link":"SetUpAudioOptions"},{"title":"module:MovieDetails.SetUpVideoOptions","link":"SetUpVideoOptions"},{"title":"module:MovieDetails.audioOptionsClosed","link":"audioOptionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:MovieDetails.getEndTime","link":"getEndTime"},{"title":"module:MovieDetails.getRuntime","link":"getRuntime"},{"title":"module:MovieDetails.init","link":"init"},{"title":"module:MovieDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:MovieDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:MovieDetails.onMoviePosterSwapAnimationStateChange","link":"onMoviePosterSwapAnimationStateChange","description":"

onMoviePosterSwapAnimationStateChange: Handler for changes to m.moviePosterSwapAnimation.state

"},{"title":"module:MovieDetails.onNewPosterImageURIChange","link":"onNewPosterImageURIChange","description":"

onNewPosterImageURIChange: Handler for newPosterImageURI param change

"},{"title":"module:MovieDetails.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

onPosterLoadStatusChanged: Handler for changes to m.moviePosterSwap.loadStatus

"},{"title":"module:MovieDetails.round","link":"round"},{"title":"module:MovieDetails.setFavoriteColor","link":"setFavoriteColor"},{"title":"module:MovieDetails.setFieldText","link":"setFieldText"},{"title":"module:MovieDetails.setWatchedColor","link":"setWatchedColor"},{"title":"module:MovieDetails.trailerAvailableChanged","link":"trailerAvailableChanged"},{"title":"module:MovieDetails.videoOptionsClosed","link":"videoOptionsClosed","description":"

Check if options were updated and if any reloding is needed...

"},{"title":"module:MovieLibraryView","link":"MovieLibraryView"},{"title":"module:MovieLibraryView.FilterDataLoaded","link":"FilterDataLoaded","description":"

Logo Image Loaded Event Handler

"},{"title":"module:MovieLibraryView.ItemDataLoaded","link":"ItemDataLoaded","description":"

Handle loaded data, and add to Grid

"},{"title":"module:MovieLibraryView.LogoImageLoaded","link":"LogoImageLoaded","description":"

Logo Image Loaded Event Handler

"},{"title":"module:MovieLibraryView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:MovieLibraryView.OnScreenShown","link":"OnScreenShown"},{"title":"module:MovieLibraryView.SetBackground","link":"SetBackground","description":"

Set Background Image

"},{"title":"module:MovieLibraryView.SetName","link":"SetName","description":"

Set Selected Movie Name

"},{"title":"module:MovieLibraryView.SetOfficialRating","link":"SetOfficialRating","description":"

Set Selected Movie OfficialRating

"},{"title":"module:MovieLibraryView.SetOverview","link":"SetOverview","description":"

Set Selected Movie Overview

"},{"title":"module:MovieLibraryView.SetProductionYear","link":"SetProductionYear","description":"

Set Selected Movie ProductionYear

"},{"title":"module:MovieLibraryView.alphaSelectedChanged","link":"alphaSelectedChanged"},{"title":"module:MovieLibraryView.getCollectionType","link":"getCollectionType","description":"

Return parent collection type

"},{"title":"module:MovieLibraryView.getItemFocused","link":"getItemFocused","description":"

Returns Focused Item

"},{"title":"module:MovieLibraryView.getRuntime","link":"getRuntime"},{"title":"module:MovieLibraryView.inStringArray","link":"inStringArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:MovieLibraryView.init","link":"init"},{"title":"module:MovieLibraryView.loadInitialItems","link":"loadInitialItems","description":"

Load initial set of Data

"},{"title":"module:MovieLibraryView.loadMoreData","link":"loadMoreData","description":"

Load next set of items

"},{"title":"module:MovieLibraryView.newBGLoaded","link":"newBGLoaded","description":"

When Image Loading Status changes

"},{"title":"module:MovieLibraryView.onChannelSelected","link":"onChannelSelected"},{"title":"module:MovieLibraryView.onGenreItemSelected","link":"onGenreItemSelected","description":"

Genre Item Selected

"},{"title":"module:MovieLibraryView.onItemFocused","link":"onItemFocused","description":"

Handle new item being focused

"},{"title":"module:MovieLibraryView.onItemSelected","link":"onItemSelected","description":"

Item Selected

"},{"title":"module:MovieLibraryView.onKeyEvent","link":"onKeyEvent"},{"title":"module:MovieLibraryView.onvoiceFilter","link":"onvoiceFilter"},{"title":"module:MovieLibraryView.optionsClosed","link":"optionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:MovieLibraryView.round","link":"round"},{"title":"module:MovieLibraryView.setFieldText","link":"setFieldText"},{"title":"module:MovieLibraryView.setMoviesOptions","link":"setMoviesOptions","description":"

Set Movies view, sort, and filter options

"},{"title":"module:MovieLibraryView.setSelectedOptions","link":"setSelectedOptions","description":"

Data to display when options button selected

"},{"title":"module:MovieLibraryView.setupNodes","link":"setupNodes"},{"title":"module:MovieLibraryView.swapDone","link":"swapDone","description":"

Swap Complete

"},{"title":"module:MovieOptions","link":"MovieOptions"},{"title":"module:MovieOptions.buttonFocusChanged","link":"buttonFocusChanged","description":"

Switch menu shown when button focus changes

"},{"title":"module:MovieOptions.init","link":"init"},{"title":"module:MovieOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:MovieOptions.optionsSet","link":"optionsSet"},{"title":"module:MusicAlbumData","link":"MusicAlbumData"},{"title":"module:MusicAlbumData.setFields","link":"setFields"},{"title":"module:MusicAlbumData.setPoster","link":"setPoster"},{"title":"module:MusicAlbumSongListData","link":"MusicAlbumSongListData"},{"title":"module:MusicAlbumSongListData.setFields","link":"setFields"},{"title":"module:MusicAlbumSongListData.setPoster","link":"setPoster"},{"title":"module:MusicArtistData","link":"MusicArtistData"},{"title":"module:MusicArtistData.setFields","link":"setFields"},{"title":"module:MusicArtistData.setPoster","link":"setPoster"},{"title":"module:MusicArtistGridItem","link":"MusicArtistGridItem"},{"title":"module:MusicArtistGridItem.focusChanged","link":"focusChanged","description":"

Display or hide title Visibility on focus change

"},{"title":"module:MusicArtistGridItem.init","link":"init"},{"title":"module:MusicArtistGridItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:MusicArtistGridItem.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and text when poster loaded

"},{"title":"module:MusicLibraryView","link":"MusicLibraryView"},{"title":"module:MusicLibraryView.ItemDataLoaded","link":"ItemDataLoaded","description":"

Handle loaded data, and add to Grid

"},{"title":"module:MusicLibraryView.LogoImageLoaded","link":"LogoImageLoaded","description":"

Logo Image Loaded Event Handler

"},{"title":"module:MusicLibraryView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:MusicLibraryView.OnScreenShown","link":"OnScreenShown"},{"title":"module:MusicLibraryView.SetAlbumCount","link":"SetAlbumCount","description":"

Set Selected Artist Album Count

"},{"title":"module:MusicLibraryView.SetBackground","link":"SetBackground","description":"

Set Background Image

"},{"title":"module:MusicLibraryView.SetGenres","link":"SetGenres","description":"

Set Selected Artist Genres

"},{"title":"module:MusicLibraryView.SetName","link":"SetName","description":"

Set Selected Artist Name

"},{"title":"module:MusicLibraryView.SetSongCount","link":"SetSongCount","description":"

Set Selected Artist Song Count

"},{"title":"module:MusicLibraryView.SetUpOptions","link":"SetUpOptions","description":"

Data to display when options button selected

"},{"title":"module:MusicLibraryView.alphaSelectedChanged","link":"alphaSelectedChanged"},{"title":"module:MusicLibraryView.getCollectionType","link":"getCollectionType","description":"

Return parent collection type

"},{"title":"module:MusicLibraryView.getItemFocused","link":"getItemFocused","description":"

Returns Focused Item

"},{"title":"module:MusicLibraryView.inStringArray","link":"inStringArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:MusicLibraryView.init","link":"init"},{"title":"module:MusicLibraryView.loadInitialItems","link":"loadInitialItems","description":"

Load initial set of Data

"},{"title":"module:MusicLibraryView.loadMoreData","link":"loadMoreData","description":"

Load next set of items

"},{"title":"module:MusicLibraryView.newBGLoaded","link":"newBGLoaded","description":"

When Image Loading Status changes

"},{"title":"module:MusicLibraryView.onChannelSelected","link":"onChannelSelected"},{"title":"module:MusicLibraryView.onGenreItemFocused","link":"onGenreItemFocused","description":"

Genre Item Focused

"},{"title":"module:MusicLibraryView.onGenreItemSelected","link":"onGenreItemSelected","description":"

Genre Item Selected

"},{"title":"module:MusicLibraryView.onItemFocused","link":"onItemFocused","description":"

Handle new item being focused

"},{"title":"module:MusicLibraryView.onItemSelected","link":"onItemSelected","description":"

Item Selected

"},{"title":"module:MusicLibraryView.onKeyEvent","link":"onKeyEvent"},{"title":"module:MusicLibraryView.onvoiceFilter","link":"onvoiceFilter"},{"title":"module:MusicLibraryView.optionsClosed","link":"optionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:MusicLibraryView.setFieldText","link":"setFieldText"},{"title":"module:MusicLibraryView.setMusicOptions","link":"setMusicOptions","description":"

Set Music view, sort, and filter options

"},{"title":"module:MusicLibraryView.setupNodes","link":"setupNodes"},{"title":"module:MusicLibraryView.swapDone","link":"swapDone","description":"

Swap Complete

"},{"title":"module:MusicSongData","link":"MusicSongData"},{"title":"module:MusicSongData.setFields","link":"setFields"},{"title":"module:MusicSongData.setPoster","link":"setPoster"},{"title":"module:OSD","link":"OSD"},{"title":"module:OSD.LOGO_RIGHT_PADDING","link":"LOGO_RIGHT_PADDING"},{"title":"module:OSD.OPTIONCONTROLS_TOP_PADDING","link":"OPTIONCONTROLS_TOP_PADDING"},{"title":"module:OSD.inactiveCheck","link":"inactiveCheck","description":"

inactiveCheck: Checks if the time since last keypress is greater than or equal to the allowed inactive time of the menu.

"},{"title":"module:OSD.init","link":"init"},{"title":"module:OSD.moveOptionControls","link":"moveOptionControls","description":"

moveOptionControls: Moves option controls node based on passed pixel values

"},{"title":"module:OSD.onButtonSelected","link":"onButtonSelected","description":"

onButtonSelected: Handler for selection of buttons from the menu.

"},{"title":"module:OSD.onEpisodeNumberChanged","link":"onEpisodeNumberChanged","description":"

onEpisodeNumberChanged: Handler for changes to m.top.episodeNumber param.

"},{"title":"module:OSD.onEpisodeNumberEndChanged","link":"onEpisodeNumberEndChanged","description":"

onEpisodeNumberEndChanged: Handler for changes to m.top.episodeNumberEnd param.

"},{"title":"module:OSD.onFocusChanged","link":"onFocusChanged","description":"

onFocusChanged: Handler for changes to the focus of this menu.

"},{"title":"module:OSD.onItemTitleTextChanged","link":"onItemTitleTextChanged","description":"

onItemTitleTextChanged: Handler for changes to m.top.itemTitleText param.

"},{"title":"module:OSD.onKeyEvent","link":"onKeyEvent"},{"title":"module:OSD.onLogoImageChanged","link":"onLogoImageChanged","description":"

onLogoImageChanged: Handler for changes to m.top.logoImage param.

"},{"title":"module:OSD.onLogoLoadStatusChanged","link":"onLogoLoadStatusChanged","description":"

onLogoLoadStatusChanged: Handler for changes to logo image's status.

"},{"title":"module:OSD.onPlaybackStateChanged","link":"onPlaybackStateChanged","description":"

onPlaybackStateChanged: Handler for changes to m.top.playbackState param

"},{"title":"module:OSD.onProgressPercentageChanged","link":"onProgressPercentageChanged","description":"

onProgressPercentageChanged: Handler for changes to m.top.progressPercentage param

"},{"title":"module:OSD.onSeasonNumberChanged","link":"onSeasonNumberChanged","description":"

onSeasonNumberChanged: Handler for changes to m.top.seasonNumber param.

"},{"title":"module:OSD.onVisibleChanged","link":"onVisibleChanged","description":"

onVisibleChanged: Handler for changes to the visibility of this menu.

"},{"title":"module:OSD.resetFocusToDefaultButton","link":"resetFocusToDefaultButton","description":"

resetFocusToDefaultButton: Reset focus back to the default button

"},{"title":"module:OptionNode","link":"OptionNode"},{"title":"module:OptionNode.init","link":"init"},{"title":"module:OptionsButton","link":"OptionsButton"},{"title":"module:OptionsButton.init","link":"init"},{"title":"module:OptionsButton.press","link":"press"},{"title":"module:OptionsData","link":"OptionsData"},{"title":"module:OptionsData.init","link":"init"},{"title":"module:OptionsData.press","link":"press"},{"title":"module:OptionsData.update_title","link":"update_title"},{"title":"module:OptionsSlider","link":"OptionsSlider"},{"title":"module:OptionsSlider.init","link":"init"},{"title":"module:OptionsSlider.onKeyEvent","link":"onKeyEvent"},{"title":"module:OptionsSlider.setFields","link":"setFields"},{"title":"module:OverviewDialog","link":"OverviewDialog"},{"title":"module:OverviewDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:OverviewDialog.setOverview","link":"setOverview"},{"title":"module:OverviewDialog.setTitle","link":"setTitle"},{"title":"module:PersonData","link":"PersonData"},{"title":"module:PersonData.setFields","link":"setFields"},{"title":"module:PersonData.setPoster","link":"setPoster"},{"title":"module:PersonDetails","link":"PersonDetails"},{"title":"module:PersonDetails.createDialogPallete","link":"createDialogPallete"},{"title":"module:PersonDetails.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:PersonDetails.dscrShowFocus","link":"dscrShowFocus"},{"title":"module:PersonDetails.init","link":"init"},{"title":"module:PersonDetails.loadPerson","link":"loadPerson"},{"title":"module:PersonDetails.onButtonGroupEscaped","link":"onButtonGroupEscaped"},{"title":"module:PersonDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:PersonDetails.setFavoriteColor","link":"setFavoriteColor"},{"title":"module:PersonDetails.shortDate","link":"shortDate"},{"title":"module:PhotoData","link":"PhotoData"},{"title":"module:PhotoData.setFields","link":"setFields"},{"title":"module:PhotoData.setPoster","link":"setPoster"},{"title":"module:PhotoDetails","link":"PhotoDetails"},{"title":"module:PhotoDetails.OnScreenHidden","link":"OnScreenHidden","description":"

JFScreen hook.\nUsed to ensure tasks are stopped

"},{"title":"module:PhotoDetails.init","link":"init"},{"title":"module:PhotoDetails.isRandomChanged","link":"isRandomChanged","description":"

isRandom component field has changed

"},{"title":"module:PhotoDetails.isSlideshowChanged","link":"isSlideshowChanged","description":"

isSlideshow component field has changed

"},{"title":"module:PhotoDetails.isValidToContinue","link":"isValidToContinue"},{"title":"module:PhotoDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:PhotoDetails.nextSlide","link":"nextSlide"},{"title":"module:PhotoDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:PhotoDetails.onPhotoLoaded","link":"onPhotoLoaded"},{"title":"module:PhotoDetails.statusUpdate","link":"statusUpdate"},{"title":"module:PlaybackDialog","link":"PlaybackDialog"},{"title":"module:PlaybackDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:PlayedCheckmark","link":"PlayedCheckmark"},{"title":"module:PlayedCheckmark.init","link":"init"},{"title":"module:PlaylistData","link":"PlaylistData"},{"title":"module:PlaylistData.setFields","link":"setFields"},{"title":"module:PlaylistData.setPoster","link":"setPoster"},{"title":"module:PlaylistView","link":"PlaylistView"},{"title":"module:PlaylistView.adjustScreenForNoOverview","link":"adjustScreenForNoOverview","description":"

Adjust scene by removing overview node and showing more songs

"},{"title":"module:PlaylistView.createDialogPallete","link":"createDialogPallete"},{"title":"module:PlaylistView.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:PlaylistView.init","link":"init"},{"title":"module:PlaylistView.onDoneLoading","link":"onDoneLoading"},{"title":"module:PlaylistView.onKeyEvent","link":"onKeyEvent"},{"title":"module:PlaylistView.pageContentChanged","link":"pageContentChanged","description":"

Set values for displayed values on screen

"},{"title":"module:PlaylistView.setOnScreenTextValues","link":"setOnScreenTextValues","description":"

Populate on screen text variables

"},{"title":"module:PlaylistView.setPosterImage","link":"setPosterImage","description":"

Set poster image on screen

"},{"title":"module:PlaylistView.setScreenTitle","link":"setScreenTitle","description":"

Set screen's title text

"},{"title":"module:PlaylistView.setupMainNode","link":"setupMainNode"},{"title":"module:PlaystateTask","link":"PlaystateTask"},{"title":"module:PlaystateTask.PlaystateDefaults","link":"PlaystateDefaults"},{"title":"module:PlaystateTask.PlaystateUpdate","link":"PlaystateUpdate"},{"title":"module:PlaystateTask.init","link":"init"},{"title":"module:PostTask","link":"PostTask"},{"title":"module:PostTask.asyncPost","link":"asyncPost","description":"

Post data and wait for response code

"},{"title":"module:PostTask.empty","link":"empty","description":"

Revert PostTask to default state

"},{"title":"module:PostTask.init","link":"init"},{"title":"module:PostTask.postItems","link":"postItems","description":"

Main function for PostTask.\nPosts either an array of data\nor a string of data to an API endpoint.\nSaves the response information

"},{"title":"module:ProgramDetails","link":"ProgramDetails"},{"title":"module:ProgramDetails.channelUpdated","link":"channelUpdated"},{"title":"module:ProgramDetails.focusChanged","link":"focusChanged","description":"

Show view channel button when item has Focus

"},{"title":"module:ProgramDetails.getDurationStringFromSeconds","link":"getDurationStringFromSeconds","description":"

Get program duration string (e.g. 1h 20m)

"},{"title":"module:ProgramDetails.getRelativeDayName","link":"getRelativeDayName","description":"

Get relative date name for a date (yesterday, today, tomorrow, or otherwise weekday name )

"},{"title":"module:ProgramDetails.init","link":"init"},{"title":"module:ProgramDetails.onAnimationComplete","link":"onAnimationComplete"},{"title":"module:ProgramDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:ProgramDetails.programUpdated","link":"programUpdated"},{"title":"module:ProgramDetails.setupLabels","link":"setupLabels","description":"

Set up Live and Repeat label sizes

"},{"title":"module:ProgramDetails.updateLabels","link":"updateLabels"},{"title":"module:PublicUserData","link":"PublicUserData"},{"title":"module:PublicUserData.init","link":"init"},{"title":"module:QueueManager","link":"QueueManager"},{"title":"module:QueueManager.clear","link":"clear","description":"

Clear all content from play queue

"},{"title":"module:QueueManager.clearHold","link":"clearHold","description":"

Clear all hold content

"},{"title":"module:QueueManager.deleteAtIndex","link":"deleteAtIndex","description":"

Delete item from play queue at passed index

"},{"title":"module:QueueManager.getCount","link":"getCount","description":"

Return the number of items in the play queue

"},{"title":"module:QueueManager.getCurrentItem","link":"getCurrentItem","description":"

Return the item currently in focus from the play queue

"},{"title":"module:QueueManager.getHold","link":"getHold","description":"

Return the items in the hold

"},{"title":"module:QueueManager.getIsShuffled","link":"getIsShuffled","description":"

Return whether or not shuffle is enabled

"},{"title":"module:QueueManager.getItemByIndex","link":"getItemByIndex","description":"

Return the item in the passed index from the play queue

"},{"title":"module:QueueManager.getItemType","link":"getItemType","description":"

getItemType: Returns the media type of the passed item

"},{"title":"module:QueueManager.getPosition","link":"getPosition","description":"

Returns current playback position within the queue

"},{"title":"module:QueueManager.getQueue","link":"getQueue","description":"

Return the current play queue

"},{"title":"module:QueueManager.getQueueTypes","link":"getQueueTypes","description":"

Return the types of items in current play queue

"},{"title":"module:QueueManager.getQueueUniqueTypes","link":"getQueueUniqueTypes","description":"

Return the unique types of items in current play queue

"},{"title":"module:QueueManager.getUnshuffledQueue","link":"getUnshuffledQueue","description":"

Return original, unshuffled queue

"},{"title":"module:QueueManager.hold","link":"hold","description":"

Hold an item

"},{"title":"module:QueueManager.init","link":"init"},{"title":"module:QueueManager.isPrerollActive","link":"isPrerollActive","description":"

Return isPrerollActive status

"},{"title":"module:QueueManager.moveBack","link":"moveBack","description":"

Move queue position back one

"},{"title":"module:QueueManager.moveForward","link":"moveForward","description":"

Move queue position ahead one

"},{"title":"module:QueueManager.peek","link":"peek","description":"

Return item at end of play queue without removing

"},{"title":"module:QueueManager.playQueue","link":"playQueue","description":"

Play items in queue

"},{"title":"module:QueueManager.pop","link":"pop","description":"

Remove item at end of play queue

"},{"title":"module:QueueManager.push","link":"push","description":"

Push new items to the play queue

"},{"title":"module:QueueManager.resetQueueItemOrder","link":"resetQueueItemOrder","description":"

Reset queue items back to original, unshuffled order

"},{"title":"module:QueueManager.resetShuffle","link":"resetShuffle","description":"

Reset shuffle to off state

"},{"title":"module:QueueManager.set","link":"set","description":"

Replace play queue with passed array

"},{"title":"module:QueueManager.setPosition","link":"setPosition","description":"

Set the queue position

"},{"title":"module:QueueManager.setPrerollStatus","link":"setPrerollStatus","description":"

Set prerollActive status

"},{"title":"module:QueueManager.setTopStartingPoint","link":"setTopStartingPoint","description":"

Set starting point for top item in the queue

"},{"title":"module:QueueManager.shuffleQueueItems","link":"shuffleQueueItems","description":"

Save a copy of the original queue and randomize order of queue items

"},{"title":"module:QueueManager.toggleShuffle","link":"toggleShuffle","description":"

Toggle shuffleEnabled state

"},{"title":"module:QueueManager.top","link":"top","description":"

Return the fitst item in the play queue

"},{"title":"module:QuickConnect","link":"QuickConnect"},{"title":"module:QuickConnect.init","link":"init"},{"title":"module:QuickConnect.monitorQuickConnect","link":"monitorQuickConnect"},{"title":"module:QuickConnectDialog","link":"QuickConnectDialog"},{"title":"module:QuickConnectDialog.OnAuthenticated","link":"OnAuthenticated"},{"title":"module:QuickConnectDialog.init","link":"init"},{"title":"module:QuickConnectDialog.onButtonSelected","link":"onButtonSelected"},{"title":"module:QuickConnectDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:QuickConnectDialog.quickConnectClosed","link":"quickConnectClosed"},{"title":"module:QuickConnectDialog.quickConnectStatus","link":"quickConnectStatus"},{"title":"module:RadioDialog","link":"RadioDialog"},{"title":"module:RadioDialog.init","link":"init"},{"title":"module:RadioDialog.moveScrollBar","link":"moveScrollBar","description":"

Move the popup's scroll bar

"},{"title":"module:RadioDialog.onButtonSelected","link":"onButtonSelected","description":"

Event handler for when user selected a button

"},{"title":"module:RadioDialog.onContentDataChanged","link":"onContentDataChanged"},{"title":"module:RadioDialog.onItemFocused","link":"onItemFocused","description":"

Event handler for when user's cursor highlights an option in the option list

"},{"title":"module:RadioDialog.onItemSelected","link":"onItemSelected","description":"

Once user selected an item, move cursor down to OK button

"},{"title":"module:RadioDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:RadioDialog.onScrollBarFocus","link":"onScrollBarFocus","description":"

If somehow the scrollbar gains focus, set focus back to the option list

"},{"title":"module:RecordProgramTask","link":"RecordProgramTask"},{"title":"module:RecordProgramTask.RecordOrCancelProgram","link":"RecordOrCancelProgram"},{"title":"module:RecordProgramTask.init","link":"init"},{"title":"module:RecordingData","link":"RecordingData"},{"title":"module:RecordingData.setFields","link":"setFields"},{"title":"module:RecordingData.setPoster","link":"setPoster"},{"title":"module:SceneManager","link":"SceneManager"},{"title":"module:SceneManager.clearPreviousScene","link":"clearPreviousScene","description":"

Clear previous scene from group stack

"},{"title":"module:SceneManager.clearScenes","link":"clearScenes","description":"

Clear all content from group stack

"},{"title":"module:SceneManager.deleteSceneAtIndex","link":"deleteSceneAtIndex","description":"

Delete scene from group stack at passed index

"},{"title":"module:SceneManager.dismissDialog","link":"dismissDialog","description":"

Close currently displayed dialog

"},{"title":"module:SceneManager.getActiveScene","link":"getActiveScene","description":"

Return group at top of stack without removing

"},{"title":"module:SceneManager.init","link":"init"},{"title":"module:SceneManager.isDialogOpen","link":"isDialogOpen","description":"

Returns bool indicating if dialog is currently displayed

"},{"title":"module:SceneManager.optionClosed","link":"optionClosed","description":"

Return button the user selected

"},{"title":"module:SceneManager.optionDialog","link":"optionDialog","description":"

Display dialog to user with an OK button

"},{"title":"module:SceneManager.optionSelected","link":"optionSelected","description":"

Return button the user selected

"},{"title":"module:SceneManager.popScene","link":"popScene","description":"

Remove the current group and load the last group from the stack

"},{"title":"module:SceneManager.pushScene","link":"pushScene","description":"

Push a new group onto the stack, replacing the existing group on the screen

"},{"title":"module:SceneManager.radioDialog","link":"radioDialog","description":"

Display dialog to user with an OK button

"},{"title":"module:SceneManager.registerOverhangData","link":"registerOverhangData","description":"

Register observers for overhang data

"},{"title":"module:SceneManager.resetTime","link":"resetTime","description":"

Reset time

"},{"title":"module:SceneManager.settings","link":"settings","description":"

Display user/device settings screen

"},{"title":"module:SceneManager.standardDialog","link":"standardDialog","description":"

Display dialog to user with an OK button

"},{"title":"module:SceneManager.unregisterOverhangData","link":"unregisterOverhangData","description":"

Remove observers for overhang data

"},{"title":"module:SceneManager.updateOptions","link":"updateOptions","description":"

Update options availability

"},{"title":"module:SceneManager.updateOverhangTitle","link":"updateOverhangTitle","description":"

Update overhang title

"},{"title":"module:SceneManager.updateOverhangVisible","link":"updateOverhangVisible","description":"

Update whether the overhang is visible or not

"},{"title":"module:SceneManager.updateUser","link":"updateUser","description":"

Update username in overhang

"},{"title":"module:SceneManager.userMessage","link":"userMessage","description":"

Display dialog to user with an OK button

"},{"title":"module:ScheduleProgramData","link":"ScheduleProgramData"},{"title":"module:ScheduleProgramData.setFields","link":"setFields"},{"title":"module:ScheduleProgramData.setPoster","link":"setPoster"},{"title":"module:SearchBox","link":"SearchBox"},{"title":"module:SearchBox.init","link":"init"},{"title":"module:SearchBox.searchMedias","link":"searchMedias"},{"title":"module:SearchData","link":"SearchData"},{"title":"module:SearchData.setFields","link":"setFields"},{"title":"module:SearchData.setPoster","link":"setPoster"},{"title":"module:SearchResults","link":"SearchResults"},{"title":"module:SearchResults.init","link":"init"},{"title":"module:SearchResults.loadResults","link":"loadResults"},{"title":"module:SearchResults.onKeyEvent","link":"onKeyEvent"},{"title":"module:SearchResults.searchMedias","link":"searchMedias"},{"title":"module:SearchRow","link":"SearchRow"},{"title":"module:SearchRow.addRow","link":"addRow"},{"title":"module:SearchRow.getData","link":"getData"},{"title":"module:SearchRow.init","link":"init"},{"title":"module:SearchRow.updateSize","link":"updateSize"},{"title":"module:SearchTask","link":"SearchTask"},{"title":"module:SearchTask.init","link":"init"},{"title":"module:SearchTask.search","link":"search"},{"title":"module:SeriesData","link":"SeriesData"},{"title":"module:SeriesData.setFields","link":"setFields"},{"title":"module:SeriesData.setPoster","link":"setPoster"},{"title":"module:ServerDiscoveryTask","link":"ServerDiscoveryTask"},{"title":"module:ServerDiscoveryTask.AddServer","link":"AddServer"},{"title":"module:ServerDiscoveryTask.ProcessClientDiscoveryResponse","link":"ProcessClientDiscoveryResponse"},{"title":"module:ServerDiscoveryTask.ProcessSSDPResponse","link":"ProcessSSDPResponse"},{"title":"module:ServerDiscoveryTask.SendClientDiscoveryBroadcast","link":"SendClientDiscoveryBroadcast"},{"title":"module:ServerDiscoveryTask.SendSSDPBroadcast","link":"SendSSDPBroadcast"},{"title":"module:ServerDiscoveryTask.execute","link":"execute"},{"title":"module:ServerDiscoveryTask.init","link":"init","description":"

Task used to discover jellyfin servers on the local network

"},{"title":"module:SetServerScreen","link":"SetServerScreen"},{"title":"module:SetServerScreen.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook called when the screen is displayed by the screen manager

"},{"title":"module:SetServerScreen.ScanForServers","link":"ScanForServers"},{"title":"module:SetServerScreen.ScanForServersComplete","link":"ScanForServersComplete"},{"title":"module:SetServerScreen.ShowKeyboard","link":"ShowKeyboard"},{"title":"module:SetServerScreen.clearErrorMessage","link":"clearErrorMessage"},{"title":"module:SetServerScreen.init","link":"init"},{"title":"module:SetServerScreen.onDialogButton","link":"onDialogButton"},{"title":"module:SetServerScreen.onKeyEvent","link":"onKeyEvent"},{"title":"module:ShowScenes","link":"ShowScenes"},{"title":"module:ShowScenes.CreateAlbumView","link":"CreateAlbumView","description":"

Shows details on selected album. Description text, image, and list of available songs

"},{"title":"module:ShowScenes.CreateArtistView","link":"CreateArtistView","description":"

Shows details on selected artist. Bio, image, and list of available albums

"},{"title":"module:ShowScenes.CreateHomeGroup","link":"CreateHomeGroup"},{"title":"module:ShowScenes.CreateItemGrid","link":"CreateItemGrid"},{"title":"module:ShowScenes.CreateMovieDetailsGroup","link":"CreateMovieDetailsGroup"},{"title":"module:ShowScenes.CreateMovieLibraryView","link":"CreateMovieLibraryView"},{"title":"module:ShowScenes.CreateMusicLibraryView","link":"CreateMusicLibraryView"},{"title":"module:ShowScenes.CreatePersonView","link":"CreatePersonView"},{"title":"module:ShowScenes.CreatePlaylistView","link":"CreatePlaylistView","description":"

Shows details on selected playlist. Description text, image, and list of available items

"},{"title":"module:ShowScenes.CreateSearchPage","link":"CreateSearchPage"},{"title":"module:ShowScenes.CreateSeasonDetailsGroup","link":"CreateSeasonDetailsGroup"},{"title":"module:ShowScenes.CreateSeasonDetailsGroupByID","link":"CreateSeasonDetailsGroupByID"},{"title":"module:ShowScenes.CreateSeriesDetailsGroup","link":"CreateSeriesDetailsGroup"},{"title":"module:ShowScenes.CreateServerGroup","link":"CreateServerGroup"},{"title":"module:ShowScenes.CreateSigninGroup","link":"CreateSigninGroup"},{"title":"module:ShowScenes.CreateUserSelectGroup","link":"CreateUserSelectGroup"},{"title":"module:ShowScenes.CreateVideoPlayerGroup","link":"CreateVideoPlayerGroup"},{"title":"module:ShowScenes.DeleteFromServerList","link":"DeleteFromServerList"},{"title":"module:ShowScenes.LoginFlow","link":"LoginFlow"},{"title":"module:ShowScenes.SaveServerList","link":"SaveServerList"},{"title":"module:ShowScenes.SendPerformanceBeacon","link":"SendPerformanceBeacon","description":"

Roku Performance monitoring

"},{"title":"module:ShowScenes.playbackOptionDialog","link":"playbackOptionDialog","description":"

Opens dialog asking user if they want to resume video or start playback over only on the home screen

"},{"title":"module:SlideOutButton","link":"SlideOutButton"},{"title":"module:SlideOutButton.init","link":"init"},{"title":"module:SlideOutButton.onBackgroundChanged","link":"onBackgroundChanged"},{"title":"module:SlideOutButton.onFocusChanged","link":"onFocusChanged"},{"title":"module:SlideOutButton.onHeightChanged","link":"onHeightChanged"},{"title":"module:SlideOutButton.onHighlightChanged","link":"onHighlightChanged"},{"title":"module:SlideOutButton.onIconChanged","link":"onIconChanged"},{"title":"module:SlideOutButton.onKeyEvent","link":"onKeyEvent"},{"title":"module:SlideOutButton.onPaddingChanged","link":"onPaddingChanged"},{"title":"module:SlideOutButton.onTextChanged","link":"onTextChanged"},{"title":"module:SlideOutButton.onWidthChanged","link":"onWidthChanged"},{"title":"module:SlideOutButton.setIconSize","link":"setIconSize"},{"title":"module:SongItem","link":"SongItem"},{"title":"module:SongItem.focusChanged","link":"focusChanged"},{"title":"module:SongItem.init","link":"init"},{"title":"module:SongItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:Spinner","link":"Spinner"},{"title":"module:Spinner.init","link":"init"},{"title":"module:StandardDialog","link":"StandardDialog"},{"title":"module:StandardDialog.init","link":"init"},{"title":"module:StandardDialog.onContentDataChanged","link":"onContentDataChanged"},{"title":"module:Subtitles","link":"Subtitles"},{"title":"module:Subtitles.availSubtitleTrackIdx","link":"availSubtitleTrackIdx","description":"

Roku translates the info provided in subtitleTracks into availableSubtitleTracks\nIncluding ignoring tracks, if they are not understood, thus making indexing unpredictable.\nThis function translates between our internel selected subtitle index\nand the corresponding index in availableSubtitleTracks.

"},{"title":"module:Subtitles.changeSubtitleDuringPlayback","link":"changeSubtitleDuringPlayback"},{"title":"module:Subtitles.defaultSubtitleTrack","link":"defaultSubtitleTrack","description":"

Identify the default subtitle track\nif "requires_text" is true, only return a track if it is textual\nThis allows forcing text subs, since roku requires transcoding of non-text subs\nreturns the server-side track index for the appriate subtitle

"},{"title":"module:Subtitles.defaultSubtitleTrackFromVid","link":"defaultSubtitleTrackFromVid","description":"

Identify the default subtitle track for a given video id\nreturns the server-side track index for the appriate subtitle

"},{"title":"module:Subtitles.getSubtitleLanguages","link":"getSubtitleLanguages"},{"title":"module:Subtitles.getSubtitleSelIdxFromSubIdx","link":"getSubtitleSelIdxFromSubIdx","description":"

The subtitle index on the server differs from the index we track locally\nThis function converts the former into the latter

"},{"title":"module:Subtitles.selectSubtitleTrack","link":"selectSubtitleTrack"},{"title":"module:Subtitles.selectSubtitleTrackDialog","link":"selectSubtitleTrackDialog","description":"

Present Dialog to user to select subtitle track

"},{"title":"module:Subtitles.setupSubtitle","link":"setupSubtitle","description":"

Given a set of subtitles, and a subtitle index (the index on the server, not in the list provided)\nthis will set all relevant settings for roku (mainly closed captions) and return the index of the\nsubtitle track specified, but indexed based on the provided list of subtitles

"},{"title":"module:Subtitles.sortSubtitles","link":"sortSubtitles","description":"

Checks available subtitle tracks and puts subtitles in forced, default, and non-default/forced but preferred language at the top

"},{"title":"module:Subtitles.turnoffSubtitles","link":"turnoffSubtitles"},{"title":"module:TVEpisode","link":"TVEpisode"},{"title":"module:TVEpisode.setFields","link":"setFields"},{"title":"module:TVEpisode.setPoster","link":"setPoster"},{"title":"module:TVEpisodeData","link":"TVEpisodeData"},{"title":"module:TVEpisodeData.setFields","link":"setFields"},{"title":"module:TVEpisodeData.setPoster","link":"setPoster"},{"title":"module:TVEpisodeRow","link":"TVEpisodeRow"},{"title":"module:TVEpisodeRow.init","link":"init"},{"title":"module:TVEpisodeRow.onItemSelected","link":"onItemSelected"},{"title":"module:TVEpisodeRow.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVEpisodeRow.setData","link":"setData"},{"title":"module:TVEpisodeRow.setupRows","link":"setupRows"},{"title":"module:TVEpisodeRow.updateSize","link":"updateSize"},{"title":"module:TVEpisodeRowWithOptions","link":"TVEpisodeRowWithOptions"},{"title":"module:TVEpisodeRowWithOptions.SetUpAudioOptions","link":"SetUpAudioOptions","description":"

List of audio tracks to choose from

"},{"title":"module:TVEpisodeRowWithOptions.SetUpVideoOptions","link":"SetUpVideoOptions","description":"

List of video versions to choose from

"},{"title":"module:TVEpisodeRowWithOptions.audioOptionsClosed","link":"audioOptionsClosed"},{"title":"module:TVEpisodeRowWithOptions.init","link":"init"},{"title":"module:TVEpisodeRowWithOptions.onItemSelected","link":"onItemSelected"},{"title":"module:TVEpisodeRowWithOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVEpisodeRowWithOptions.rowsDoneLoading","link":"rowsDoneLoading"},{"title":"module:TVEpisodeRowWithOptions.setupRows","link":"setupRows"},{"title":"module:TVEpisodeRowWithOptions.videoOptionsClosed","link":"videoOptionsClosed"},{"title":"module:TVEpisodes","link":"TVEpisodes"},{"title":"module:TVEpisodes.OnScreenShown","link":"OnScreenShown","description":"

OnScreenShown: Callback function when view is presented on screen

"},{"title":"module:TVEpisodes.getFocusedItem","link":"getFocusedItem","description":"

get the currently focused item

"},{"title":"module:TVEpisodes.init","link":"init"},{"title":"module:TVEpisodes.onItemSelected","link":"onItemSelected"},{"title":"module:TVEpisodes.onKeyEvent","link":"onKeyEvent","description":"

Handle navigation input from the remote and act on it

"},{"title":"module:TVEpisodes.setExtraButtonVisibility","link":"setExtraButtonVisibility","description":"

Updates the visibility of the Extras button based on if this season has any extra features

"},{"title":"module:TVEpisodes.setSeasonLoading","link":"setSeasonLoading"},{"title":"module:TVEpisodes.updateSeason","link":"updateSeason"},{"title":"module:TVListDetails","link":"TVListDetails"},{"title":"module:TVListDetails.DisplayAudioAvailable","link":"DisplayAudioAvailable","description":"

Adds "+N" (e.g. +1) if there is more than one audio track to choose from

"},{"title":"module:TVListDetails.DisplayVideoAvailable","link":"DisplayVideoAvailable","description":"

Adds "+N" (e.g. +1) if there is more than one video version to choose from

"},{"title":"module:TVListDetails.SetupAudioDisplay","link":"SetupAudioDisplay","description":"

Display current audio_codec and check if there is more than one audio track to choose from...

"},{"title":"module:TVListDetails.focusChanged","link":"focusChanged"},{"title":"module:TVListDetails.getEndTime","link":"getEndTime"},{"title":"module:TVListDetails.getRuntime","link":"getRuntime"},{"title":"module:TVListDetails.init","link":"init"},{"title":"module:TVListDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:TVListOptions","link":"TVListOptions"},{"title":"module:TVListOptions.buttonFocusChanged","link":"buttonFocusChanged","description":"

Switch menu shown when button focus changes

"},{"title":"module:TVListOptions.init","link":"init"},{"title":"module:TVListOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVListOptions.optionsSet","link":"optionsSet"},{"title":"module:TVSeasonData","link":"TVSeasonData"},{"title":"module:TVSeasonData.setFields","link":"setFields"},{"title":"module:TVSeasonData.setPoster","link":"setPoster"},{"title":"module:TVSeasonRow","link":"TVSeasonRow"},{"title":"module:TVSeasonRow.getData","link":"getData"},{"title":"module:TVSeasonRow.init","link":"init"},{"title":"module:TVSeasonRow.updateSize","link":"updateSize"},{"title":"module:TVShowDescription","link":"TVShowDescription"},{"title":"module:TVShowDescription.getEndTime","link":"getEndTime"},{"title":"module:TVShowDescription.getHistory","link":"getHistory"},{"title":"module:TVShowDescription.getRuntime","link":"getRuntime"},{"title":"module:TVShowDescription.init","link":"init"},{"title":"module:TVShowDescription.itemContentChanged","link":"itemContentChanged"},{"title":"module:TVShowDescription.round","link":"round"},{"title":"module:TVShowDescription.setFieldText","link":"setFieldText"},{"title":"module:TVShowDetails","link":"TVShowDetails"},{"title":"module:TVShowDetails.getEndTime","link":"getEndTime"},{"title":"module:TVShowDetails.getHistory","link":"getHistory"},{"title":"module:TVShowDetails.getRuntime","link":"getRuntime"},{"title":"module:TVShowDetails.init","link":"init"},{"title":"module:TVShowDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:TVShowDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVShowDetails.onShuffleEpisodeDataLoaded","link":"onShuffleEpisodeDataLoaded"},{"title":"module:TVShowDetails.round","link":"round"},{"title":"module:TVShowDetails.setFieldText","link":"setFieldText"},{"title":"module:TextSizeTask","link":"TextSizeTask"},{"title":"module:TextSizeTask.getTextSize","link":"getTextSize"},{"title":"module:TextSizeTask.init","link":"init"},{"title":"module:UserData","link":"UserData"},{"title":"module:UserData.getPreference","link":"getPreference"},{"title":"module:UserData.loadFromJSON","link":"loadFromJSON"},{"title":"module:UserData.loadFromRegistry","link":"loadFromRegistry"},{"title":"module:UserData.removeFromRegistry","link":"removeFromRegistry"},{"title":"module:UserData.saveToRegistry","link":"saveToRegistry"},{"title":"module:UserData.setDataFromJSON","link":"setDataFromJSON"},{"title":"module:UserData.setPreference","link":"setPreference"},{"title":"module:UserData.setServer","link":"setServer"},{"title":"module:UserItem","link":"UserItem"},{"title":"module:UserItem.init","link":"init"},{"title":"module:UserItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:UserLibrary","link":"UserLibrary"},{"title":"module:UserLibrary.MarkItemFavorite","link":"MarkItemFavorite"},{"title":"module:UserLibrary.MarkItemWatched","link":"MarkItemWatched"},{"title":"module:UserLibrary.UnmarkItemFavorite","link":"UnmarkItemFavorite"},{"title":"module:UserLibrary.UnmarkItemWatched","link":"UnmarkItemWatched"},{"title":"module:UserRow","link":"UserRow"},{"title":"module:UserRow.init","link":"init"},{"title":"module:UserRow.onKeyEvent","link":"onKeyEvent"},{"title":"module:UserRow.setData","link":"setData"},{"title":"module:UserRow.setUser","link":"setUser"},{"title":"module:UserRow.updateSize","link":"updateSize"},{"title":"module:UserSelect","link":"UserSelect"},{"title":"module:UserSelect.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook called when the screen is displayed by the screen manager

"},{"title":"module:UserSelect.init","link":"init"},{"title":"module:UserSelect.itemContentChanged","link":"itemContentChanged"},{"title":"module:UserSelect.onKeyEvent","link":"onKeyEvent"},{"title":"module:UserSelect.redraw","link":"redraw"},{"title":"module:VideoData","link":"VideoData"},{"title":"module:VideoData.setFields","link":"setFields"},{"title":"module:VideoData.setPoster","link":"setPoster"},{"title":"module:VideoPlayer","link":"VideoPlayer"},{"title":"module:VideoPlayer.AddVideoContent","link":"AddVideoContent"},{"title":"module:VideoPlayer.GetPlaybackInfo","link":"GetPlaybackInfo","description":"

Returns an array of playback info to be displayed during playback.\nIn the future, with a custom playback info view, we can return an associated array.

"},{"title":"module:VideoPlayer.GetTranscodingStats","link":"GetTranscodingStats"},{"title":"module:VideoPlayer.PlayIntroVideo","link":"PlayIntroVideo"},{"title":"module:VideoPlayer.VideoPlayer","link":"VideoPlayer"},{"title":"module:VideoPlayer.autoPlayNextEpisode","link":"autoPlayNextEpisode"},{"title":"module:VideoPlayer.directPlaySupported","link":"directPlaySupported"},{"title":"module:VideoPlayer.getAudioFormat","link":"getAudioFormat"},{"title":"module:VideoPlayer.getAudioInfo","link":"getAudioInfo"},{"title":"module:VideoPlayer.getContainerType","link":"getContainerType"},{"title":"module:VideoPlayer.getDisplayBitrate","link":"getDisplayBitrate"},{"title":"module:VideoPlayer.getTranscodeReasons","link":"getTranscodeReasons","description":"

Extract array of Transcode Reasons from the content URL

"},{"title":"module:VideoPlayer.havePlaybackInfo","link":"havePlaybackInfo"},{"title":"module:VideoPlayer.startPlayBackOver","link":"startPlayBackOver","description":"

Opens dialog asking user if they want to resume video or start playback over only on the home screen

"},{"title":"module:VideoPlayerView","link":"VideoPlayerView"},{"title":"module:VideoPlayerView.ReportPlayback","link":"ReportPlayback","description":"

Report playback to server

"},{"title":"module:VideoPlayerView.availSubtitleTrackIdx","link":"availSubtitleTrackIdx","description":"

availSubtitleTrackIdx: Returns Roku's index for requested subtitle track

"},{"title":"module:VideoPlayerView.bufferCheck","link":"bufferCheck","description":"

Check the the buffering has not hung

"},{"title":"module:VideoPlayerView.checkTimeToDisplayNextEpisode","link":"checkTimeToDisplayNextEpisode","description":"

Checks if we need to display the Next Episode button

"},{"title":"module:VideoPlayerView.getCurrentChapterIndex","link":"getCurrentChapterIndex","description":"

getCurrentChapterIndex: Finds current chapter index

"},{"title":"module:VideoPlayerView.handleChapterListAction","link":"handleChapterListAction","description":"

handleChapterListAction: Handles action to show chapter list

"},{"title":"module:VideoPlayerView.handleChapterSkipAction","link":"handleChapterSkipAction","description":"

handleChapterSkipAction: Handles user command to skip chapters in playing video

"},{"title":"module:VideoPlayerView.handleHideAction","link":"handleHideAction","description":"

handleHideAction: Handles action to hide OSD menu

"},{"title":"module:VideoPlayerView.handleItemSkipAction","link":"handleItemSkipAction","description":"

handleItemSkipAction: Handles user command to skip items

"},{"title":"module:VideoPlayerView.handleShowAudioMenuAction","link":"handleShowAudioMenuAction","description":"

handleShowAudioMenuAction: Handles action to show audio selection menu

"},{"title":"module:VideoPlayerView.handleShowSubtitleMenuAction","link":"handleShowSubtitleMenuAction","description":"

handleShowSubtitleMenuAction: Handles action to show subtitle selection menu

"},{"title":"module:VideoPlayerView.handleShowVideoInfoPopupAction","link":"handleShowVideoInfoPopupAction","description":"

handleShowVideoInfoPopupAction: Handles action to show video info popup

"},{"title":"module:VideoPlayerView.handleVideoPlayPauseAction","link":"handleVideoPlayPauseAction","description":"

handleVideoPlayPauseAction: Handles action to either play or pause the video content

"},{"title":"module:VideoPlayerView.hideNextEpisodeButton","link":"hideNextEpisodeButton","description":"

Runs hide Next Episode button animation and sets focus back to video

"},{"title":"module:VideoPlayerView.init","link":"init"},{"title":"module:VideoPlayerView.loadCaption","link":"loadCaption","description":"

Set caption url to server subtitle track

"},{"title":"module:VideoPlayerView.onAllowCaptionsChange","link":"onAllowCaptionsChange","description":"

Only setup caption items if captions are allowed

"},{"title":"module:VideoPlayerView.onAudioIndexChange","link":"onAudioIndexChange","description":"

Event handler for when audioIndex changes

"},{"title":"module:VideoPlayerView.onContentChange","link":"onContentChange","description":"

Event handler for when video content field changes

"},{"title":"module:VideoPlayerView.onKeyEvent","link":"onKeyEvent"},{"title":"module:VideoPlayerView.onNextEpisodeDataLoaded","link":"onNextEpisodeDataLoaded"},{"title":"module:VideoPlayerView.onOSDAction","link":"onOSDAction","description":"

onOSDAction: Process action events from OSD to their respective handlers

"},{"title":"module:VideoPlayerView.onPlaybackErrorButtonSelected","link":"onPlaybackErrorButtonSelected"},{"title":"module:VideoPlayerView.onPlaybackErrorDialogClosed","link":"onPlaybackErrorDialogClosed"},{"title":"module:VideoPlayerView.onPositionChanged","link":"onPositionChanged","description":"

When Video Player state changes

"},{"title":"module:VideoPlayerView.onState","link":"onState","description":"

When Video Player state changes

"},{"title":"module:VideoPlayerView.onSubtitleChange","link":"onSubtitleChange","description":"

Event handler for when selectedSubtitle changes

"},{"title":"module:VideoPlayerView.onVideoContentLoaded","link":"onVideoContentLoaded"},{"title":"module:VideoPlayerView.populateChapterMenu","link":"populateChapterMenu","description":"

populateChapterMenu: ' Parse chapter data from API and appeand to chapter list menu

"},{"title":"module:VideoPlayerView.showNextEpisodeButton","link":"showNextEpisodeButton","description":"

Runs Next Episode button animation and sets focus to button

"},{"title":"module:VideoPlayerView.showPlaybackErrorDialog","link":"showPlaybackErrorDialog"},{"title":"module:VideoPlayerView.stateAllowsOSD","link":"stateAllowsOSD","description":"

stateAllowsOSD: Check if current video state allows showing the OSD

"},{"title":"module:VideoPlayerView.toggleCaption","link":"toggleCaption","description":"

Toggles visibility of custom subtitles and sets captionTask's player state

"},{"title":"module:VideoPlayerView.updateCaption","link":"updateCaption","description":"

Removes old subtitle lines and adds new subtitle lines

"},{"title":"module:VideoPlayerView.updateCount","link":"updateCount","description":"

Update count down text

"},{"title":"module:VideoTrackListItem","link":"VideoTrackListItem"},{"title":"module:VideoTrackListItem.focusChanged","link":"focusChanged","description":"

Scroll description if focused

"},{"title":"module:VideoTrackListItem.init","link":"init"},{"title":"module:VideoTrackListItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:ViewCreator","link":"ViewCreator"},{"title":"module:ViewCreator.CreateAudioPlayerView","link":"CreateAudioPlayerView"},{"title":"module:ViewCreator.CreateVideoPlayerView","link":"CreateVideoPlayerView","description":"

Play Video

"},{"title":"module:ViewCreator.availSubtitleTrackIdx","link":"availSubtitleTrackIdx","description":"

Roku translates the info provided in subtitleTracks into availableSubtitleTracks\nIncluding ignoring tracks, if they are not understood, thus making indexing unpredictable.\nThis function translates between our internel selected subtitle index\nand the corresponding index in availableSubtitleTracks.

"},{"title":"module:ViewCreator.onPlaybackInfoLoaded","link":"onPlaybackInfoLoaded","description":"

The playback info task has returned data

"},{"title":"module:ViewCreator.onSelectAudioPressed","link":"onSelectAudioPressed","description":"

onSelectAudioPressed: Display audio selection dialog

"},{"title":"module:ViewCreator.onSelectPlaybackInfoPressed","link":"onSelectPlaybackInfoPressed","description":"

User requested playback info

"},{"title":"module:ViewCreator.onSelectSubtitlePressed","link":"onSelectSubtitlePressed","description":"

User requested subtitle selection popup

"},{"title":"module:ViewCreator.onSelectionMade","link":"onSelectionMade","description":"

User has selected something from the radioDialog popup

"},{"title":"module:ViewCreator.onStateChange","link":"onStateChange","description":"

Playback state change event handlers

"},{"title":"module:ViewCreator.processAudioSelection","link":"processAudioSelection","description":"

processAudioSelection: Audio track selection handler

"},{"title":"module:ViewCreator.processSubtitleSelection","link":"processSubtitleSelection"},{"title":"module:WhatsNewDialog","link":"WhatsNewDialog"},{"title":"module:WhatsNewDialog.init","link":"init"},{"title":"module:WhatsNewDialog.setPalette","link":"setPalette"},{"title":"module:baserequest","link":"baserequest"},{"title":"module:baserequest.APIRequest","link":"APIRequest"},{"title":"module:baserequest.authRequest","link":"authRequest","description":"

Takes and returns a roUrlTransfer object after adding a Jellyfin "Authorization" header

"},{"title":"module:baserequest.buildAuthHeader","link":"buildAuthHeader","description":"

Returns a string containing the "Authorization" header payload

"},{"title":"module:baserequest.buildParams","link":"buildParams"},{"title":"module:baserequest.buildURL","link":"buildURL"},{"title":"module:baserequest.deleteVoid","link":"deleteVoid"},{"title":"module:baserequest.getJson","link":"getJson"},{"title":"module:baserequest.getString","link":"getString"},{"title":"module:baserequest.getVoid","link":"getVoid"},{"title":"module:baserequest.get_url","link":"get_url"},{"title":"module:baserequest.headVoid","link":"headVoid"},{"title":"module:baserequest.postJson","link":"postJson"},{"title":"module:baserequest.postString","link":"postString"},{"title":"module:baserequest.postVoid","link":"postVoid"},{"title":"module:baserequest.setCertificateAuthority","link":"setCertificateAuthority","description":"

sets the certificate authority by file path on the passed node

"},{"title":"module:captionTask","link":"captionTask"},{"title":"module:captionTask.fetchCaption","link":"fetchCaption"},{"title":"module:captionTask.init","link":"init"},{"title":"module:captionTask.isTime","link":"isTime"},{"title":"module:captionTask.newLayoutGroup","link":"newLayoutGroup"},{"title":"module:captionTask.newRect","link":"newRect"},{"title":"module:captionTask.newlabel","link":"newlabel"},{"title":"module:captionTask.parseVTT","link":"parseVTT"},{"title":"module:captionTask.setFont","link":"setFont"},{"title":"module:captionTask.toMs","link":"toMs"},{"title":"module:captionTask.updateCaption","link":"updateCaption"},{"title":"module:conditional","link":"conditional"},{"title":"module:conditional.printRegistry","link":"printRegistry","description":"

Print out all of the registry contents to the debug log

"},{"title":"module:config","link":"config"},{"title":"module:config.GetConfigTree","link":"GetConfigTree","description":"

Read config tree from json config file and return

"},{"title":"module:config.RegistryReadAll","link":"RegistryReadAll","description":"

Return all data found inside a registry section

"},{"title":"module:config.findConfigTreeKey","link":"findConfigTreeKey","description":"

Recursivly search the config tree for entry with settingname equal to key

"},{"title":"module:config.getRegistrySections","link":"getRegistrySections","description":"

Return an array of all the registry section keys

"},{"title":"module:config.getSavedUsers","link":"getSavedUsers","description":"

Returns an array of saved users from the registry\nthat belong to the active server

"},{"title":"module:config.get_setting","link":"get_setting","description":"

"Jellyfin" registry accessors for the default global settings

"},{"title":"module:config.get_user_setting","link":"get_user_setting","description":"

User registry accessors for the currently active user

"},{"title":"module:config.registry_delete","link":"registry_delete"},{"title":"module:config.registry_read","link":"registry_read","description":"

Generic registry accessors

"},{"title":"module:config.registry_write","link":"registry_write"},{"title":"module:config.set_setting","link":"set_setting"},{"title":"module:config.set_user_setting","link":"set_user_setting"},{"title":"module:config.unset_setting","link":"unset_setting"},{"title":"module:config.unset_user_setting","link":"unset_user_setting"},{"title":"module:deviceCapabilities","link":"deviceCapabilities"},{"title":"module:deviceCapabilities.GetBitRateLimit","link":"GetBitRateLimit"},{"title":"module:deviceCapabilities.GetDirectPlayProfiles","link":"GetDirectPlayProfiles"},{"title":"module:deviceCapabilities.canPlay4k","link":"canPlay4k","description":"

does the connected display support playing 4k video?

"},{"title":"module:deviceCapabilities.getCodecProfiles","link":"getCodecProfiles"},{"title":"module:deviceCapabilities.getContainerProfiles","link":"getContainerProfiles"},{"title":"module:deviceCapabilities.getDeviceCapabilities","link":"getDeviceCapabilities","description":"

Returns the Device Capabilities for Roku.\nAlso prints out the device profile for debugging

"},{"title":"module:deviceCapabilities.getDeviceProfile","link":"getDeviceProfile"},{"title":"module:deviceCapabilities.getMaxHeightArray","link":"getMaxHeightArray"},{"title":"module:deviceCapabilities.getMaxWidthArray","link":"getMaxWidthArray"},{"title":"module:deviceCapabilities.getSubtitleProfiles","link":"getSubtitleProfiles"},{"title":"module:deviceCapabilities.getTranscodingProfiles","link":"getTranscodingProfiles"},{"title":"module:deviceCapabilities.printDeviceProfile","link":"printDeviceProfile","description":"

Print out the deviceProfile for debugging

"},{"title":"module:deviceCapabilities.removeDecimals","link":"removeDecimals","description":"

Remove all decimals from a string

"},{"title":"module:deviceCapabilities.setPreferredCodec","link":"setPreferredCodec","description":"

Takes and returns a comma delimited string of codecs.\nMoves the preferred codec to the front of the string

"},{"title":"module:deviceCapabilities.updateProfileArray","link":"updateProfileArray","description":"

Recieves and returns an assArray of supported profiles and levels for each video codec

"},{"title":"module:globals","link":"globals"},{"title":"module:globals.SaveAppToGlobal","link":"SaveAppToGlobal","description":"

Save information from roAppInfo to m.global.app

"},{"title":"module:globals.SaveDeviceToGlobal","link":"SaveDeviceToGlobal","description":"

Save information from roDeviceInfo to m.global.device

"},{"title":"module:globals.setConstants","link":"setConstants"},{"title":"module:migrations","link":"migrations"},{"title":"module:migrations.CLIENT_VERSION_REQUIRING_BASE_MIGRATION","link":"CLIENT_VERSION_REQUIRING_BASE_MIGRATION"},{"title":"module:migrations.runGlobalMigrations","link":"runGlobalMigrations","description":"

Run all necessary registry mirations on the "global" Jellyfin registry section

"},{"title":"module:migrations.runRegistryUserMigrations","link":"runRegistryUserMigrations"},{"title":"module:misc","link":"misc"},{"title":"module:misc.AssocArrayEqual","link":"AssocArrayEqual"},{"title":"module:misc.arrayHasValue","link":"arrayHasValue","description":"

Check if a specific value is inside of an array

"},{"title":"module:misc.createLogoPoster","link":"createLogoPoster","description":"

Create and return a Jellyfin logo poster node

"},{"title":"module:misc.createOverhangUser","link":"createOverhangUser"},{"title":"module:misc.createSeperator","link":"createSeperator","description":"

Create and return a rectangle node used as a seperator in the overhang

"},{"title":"module:misc.div_ceiling","link":"div_ceiling"},{"title":"module:misc.findNodeBySubtype","link":"findNodeBySubtype"},{"title":"module:misc.formatTime","link":"formatTime","description":"

Format time as 12 or 24 hour format based on system clock setting

"},{"title":"module:misc.getButton","link":"getButton"},{"title":"module:misc.getMinutes","link":"getMinutes","description":"

Converts ticks to minutes

"},{"title":"module:misc.getMsgPicker","link":"getMsgPicker"},{"title":"module:misc.get_dialog_result","link":"get_dialog_result","description":"

Returns the item selected or -1 on backpress or other unhandled closure of dialog.

"},{"title":"module:misc.inArray","link":"inArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:misc.inferServerUrl","link":"inferServerUrl","description":"

take an incomplete url string and use it to make educated guesses about\nthe complete url. then tests these guesses to see if it can find a jf server\nreturns the url of the server it found, or an empty string

"},{"title":"module:misc.isAllValid","link":"isAllValid","description":"

Returns whether or not all items in passed array are valid

"},{"title":"module:misc.isChainValid","link":"isChainValid","description":"

isChainValid: Returns whether or not all the properties in the passed property chain are valid.\nStops evaluating at first found false value

"},{"title":"module:misc.isJellyfinServer","link":"isJellyfinServer","description":"

accepts the raw json string of /system/info/public and returns\na boolean indicating if ProductName is "Jellyfin Server"

"},{"title":"module:misc.isLocalhost","link":"isLocalhost","description":"

Returns true if the string is a loopback, such as 'localhost' or '127.0.0.1'

"},{"title":"module:misc.isNodeEvent","link":"isNodeEvent"},{"title":"module:misc.isValid","link":"isValid","description":"

Returns whether or not passed value is valid

"},{"title":"module:misc.isValidAndNotEmpty","link":"isValidAndNotEmpty","description":"

Returns whether or not passed value is valid and not empty\nAccepts a string, or any countable type (arrays and lists)

"},{"title":"module:misc.lastFocusedChild","link":"lastFocusedChild"},{"title":"module:misc.leftPad","link":"leftPad"},{"title":"module:misc.message_dialog","link":"message_dialog"},{"title":"module:misc.option_dialog","link":"option_dialog"},{"title":"module:misc.parseUrl","link":"parseUrl","description":"

Returns an array from a url = [ url, proto, host, port, subdir+params ]\nIf port or subdir are not found, an empty string will be added to the array\nProto must be declared or array will be empty

"},{"title":"module:misc.roundNumber","link":"roundNumber","description":"

Rounds number to nearest integer

"},{"title":"module:misc.secondsToEndTime","link":"secondsToEndTime"},{"title":"module:misc.secondsToHuman","link":"secondsToHuman"},{"title":"module:misc.setFieldTextValue","link":"setFieldTextValue"},{"title":"module:misc.show_dialog","link":"show_dialog"},{"title":"module:misc.shuffleArray","link":"shuffleArray","description":"

Takes an array of data, shuffles the order, then returns the array\nuses the Fisher-Yates shuffling algorithm

"},{"title":"module:misc.startLoadingSpinner","link":"startLoadingSpinner","description":"

startLoadingSpinner: Start a loading spinner and attach it to the main JFScene.\nDisplays an invisible ProgressDialog node by default to disable keypresses while loading.

"},{"title":"module:misc.stopLoadingSpinner","link":"stopLoadingSpinner"},{"title":"module:misc.ticksToHuman","link":"ticksToHuman"},{"title":"module:misc.toBoolean","link":"toBoolean","description":"

convert value to boolean and return value

"},{"title":"module:misc.toString","link":"toString"},{"title":"module:misc.urlCandidates","link":"urlCandidates","description":"

this is the "educated guess" logic for inferServerUrl that generates a list of complete url's as candidates\nfor the tests in inferServerUrl. takes an incomplete url as an arg and returns a list of extrapolated\nfull urls.

"},{"title":"module:misc.versionChecker","link":"versionChecker","description":"

Returns whether or not a version number (e.g. 10.7.7) is greater or equal\nto some minimum version allowed (e.g. 10.8.0)

"},{"title":"module:quickplay","link":"quickplay"},{"title":"module:schedule","link":"schedule"},{"title":"module:schedule.channelFilterSet","link":"channelFilterSet"},{"title":"module:schedule.channelsearchTermSet","link":"channelsearchTermSet","description":"

Voice Search set

"},{"title":"module:schedule.focusProgramDetails","link":"focusProgramDetails","description":"

Move the TV Guide Grid down or up depending whether details are selected

"},{"title":"module:schedule.init","link":"init"},{"title":"module:schedule.onChannelsLoaded","link":"onChannelsLoaded","description":"

Initial list of channels loaded

"},{"title":"module:schedule.onGridScrolled","link":"onGridScrolled","description":"

As user scrolls grid, check if more data requries to be loaded

"},{"title":"module:schedule.onKeyEvent","link":"onKeyEvent"},{"title":"module:schedule.onProgramDetailsLoaded","link":"onProgramDetailsLoaded","description":"

Update the Program Details with full information

"},{"title":"module:schedule.onProgramFocused","link":"onProgramFocused"},{"title":"module:schedule.onProgramSelected","link":"onProgramSelected"},{"title":"module:schedule.onRecordChannelSelected","link":"onRecordChannelSelected","description":"

Handle user selecting "Record Channel" from Program Details

"},{"title":"module:schedule.onRecordOperationDone","link":"onRecordOperationDone"},{"title":"module:schedule.onRecordSeriesChannelSelected","link":"onRecordSeriesChannelSelected","description":"

Handle user selecting "Record Series" from Program Details

"},{"title":"module:schedule.onScheduleLoaded","link":"onScheduleLoaded","description":"

When LoadScheduleTask completes (initial or more data) and we have a schedule to display

"},{"title":"module:schedule.onWatchChannelSelected","link":"onWatchChannelSelected","description":"

Handle user selecting "Watch Channel" from Program Details

"},{"title":"module:section","link":"section"},{"title":"module:section.init","link":"init"},{"title":"module:section.onFocusChange","link":"onFocusChange"},{"title":"module:section.onIDChange","link":"onIDChange"},{"title":"module:section.onTranslationChange","link":"onTranslationChange"},{"title":"module:section.scrollDownToOnDeck","link":"scrollDownToOnDeck"},{"title":"module:section.scrollOffBottom","link":"scrollOffBottom"},{"title":"module:section.scrollOffOnDeck","link":"scrollOffOnDeck"},{"title":"module:section.scrollOffTop","link":"scrollOffTop"},{"title":"module:section.scrollUpToOnDeck","link":"scrollUpToOnDeck"},{"title":"module:section.showFromBottom","link":"showFromBottom"},{"title":"module:section.showFromTop","link":"showFromTop"},{"title":"module:sectionScroller","link":"sectionScroller"},{"title":"module:sectionScroller.displayedIndexChanged","link":"displayedIndexChanged"},{"title":"module:sectionScroller.init","link":"init"},{"title":"module:sectionScroller.onFocusChange","link":"onFocusChange"},{"title":"module:settings","link":"settings"},{"title":"module:settings.LoadMenu","link":"LoadMenu"},{"title":"module:settings.OnScreenHidden","link":"OnScreenHidden","description":"

JFScreen hook that gets ran as needed.\nAssumes settings were changed and they affect the device profile.\nPosts a new device profile to the server using the task thread

"},{"title":"module:settings.boolSettingChanged","link":"boolSettingChanged"},{"title":"module:settings.init","link":"init"},{"title":"module:settings.isFormInFocus","link":"isFormInFocus","description":"

Returns true if any of the data entry forms are in focus

"},{"title":"module:settings.onKeyEvent","link":"onKeyEvent"},{"title":"module:settings.onKeyGridEscape","link":"onKeyGridEscape"},{"title":"module:settings.onKeyGridSubmit","link":"onKeyGridSubmit"},{"title":"module:settings.postFinished","link":"postFinished","description":"

Triggered by m.postTask after completing a post.\nEmpty the task data when finished.

"},{"title":"module:settings.radioSettingChanged","link":"radioSettingChanged"},{"title":"module:settings.settingFocused","link":"settingFocused"},{"title":"module:settings.settingSelected","link":"settingSelected"},{"title":"module:userauth","link":"userauth"},{"title":"module:userauth.AboutMe","link":"AboutMe"},{"title":"module:userauth.AuthenticateViaQuickConnect","link":"AuthenticateViaQuickConnect"},{"title":"module:userauth.AvailableUsers","link":"AvailableUsers"},{"title":"module:userauth.GetPublicUsers","link":"GetPublicUsers"},{"title":"module:userauth.LoadUserAbilities","link":"LoadUserAbilities"},{"title":"module:userauth.ServerInfo","link":"ServerInfo"},{"title":"module:userauth.SignOut","link":"SignOut"},{"title":"module:userauth.checkQuickConnect","link":"checkQuickConnect"},{"title":"module:userauth.get_token","link":"get_token"},{"title":"module:userauth.initQuickConnect","link":"initQuickConnect"},{"title":"quickplay","link":"quickplay"},{"title":"quickplay.album","link":"album","description":"

A music album.\nPlay the entire album starting with track 1.

"},{"title":"quickplay.artist","link":"artist","description":"

A music artist.\nShuffle play all songs by artist.

"},{"title":"quickplay.audio","link":"audio","description":"

A single audio file.

"},{"title":"quickplay.boxset","link":"boxset","description":"

A boxset.\nPlay all items inside.

"},{"title":"quickplay.collectionFolder","link":"collectionFolder","description":"

Quick Play A CollectionFolder.\nShuffle play the items inside\nwith some differences based on collectionType.

"},{"title":"quickplay.folder","link":"folder","description":"

Quick Play A folder.\nShuffle play all items found

"},{"title":"quickplay.multipleSeries","link":"multipleSeries","description":"

More than one TV Show Series.\nShuffle play all watched episodes

"},{"title":"quickplay.musicVideo","link":"musicVideo","description":"

A single music video file.

"},{"title":"quickplay.person","link":"person","description":"

Quick Play A Person.\nShuffle play all videos found

"},{"title":"quickplay.photo","link":"photo","description":"

A single photo.

"},{"title":"quickplay.photoAlbum","link":"photoAlbum","description":"

A photo album.

"},{"title":"quickplay.playlist","link":"playlist","description":"

Quick Play A Playlist.\nPlay the first unwatched episode.\nIf none, play the whole season starting with episode 1.

"},{"title":"quickplay.program","link":"program","description":"

Quick Play A Live Program

"},{"title":"quickplay.pushToQueue","link":"pushToQueue","description":"

Takes an array of items and adds to global queue.\nAlso shuffles the playlist if asked

"},{"title":"quickplay.season","link":"season","description":"

A TV Show Season.\nPlay the first unwatched episode.\nIf none, play the whole season starting with episode 1.

"},{"title":"quickplay.series","link":"series","description":"

A TV Show Series.\nPlay the first unwatched episode.\nIf none, shuffle play the whole series.

"},{"title":"quickplay.tvChannel","link":"tvChannel","description":"

Quick Play A TVChannel

"},{"title":"quickplay.userView","link":"userView","description":"

Quick Play A UserView.\nPlay logic depends on "collectionType".

"},{"title":"quickplay.video","link":"video","description":"

A single video file.

"},{"title":"quickplay.videoContainer","link":"videoContainer","description":"

A container with some kind of videos inside of it

"}]} \ No newline at end of file +{"list":[{"title":"module:AlbumData","link":"AlbumData"},{"title":"module:AlbumData.setFields","link":"setFields"},{"title":"module:AlbumGrid","link":"AlbumGrid"},{"title":"module:AlbumGrid.getData","link":"getData"},{"title":"module:AlbumGrid.init","link":"init"},{"title":"module:AlbumGrid.onKeyEvent","link":"onKeyEvent"},{"title":"module:AlbumTrackList","link":"AlbumTrackList"},{"title":"module:AlbumTrackList.getData","link":"getData"},{"title":"module:AlbumTrackList.init","link":"init"},{"title":"module:AlbumView","link":"AlbumView"},{"title":"module:AlbumView.adjustScreenForNoOverview","link":"adjustScreenForNoOverview","description":"

Adjust scene by removing overview node and showing more songs

"},{"title":"module:AlbumView.createDialogPallete","link":"createDialogPallete"},{"title":"module:AlbumView.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:AlbumView.init","link":"init"},{"title":"module:AlbumView.onDoneLoading","link":"onDoneLoading"},{"title":"module:AlbumView.onKeyEvent","link":"onKeyEvent"},{"title":"module:AlbumView.pageContentChanged","link":"pageContentChanged","description":"

Set values for displayed values on screen

"},{"title":"module:AlbumView.setOnScreenTextValues","link":"setOnScreenTextValues","description":"

Populate on screen text variables

"},{"title":"module:AlbumView.setPosterImage","link":"setPosterImage","description":"

Set poster image on screen

"},{"title":"module:AlbumView.setScreenTitle","link":"setScreenTitle","description":"

Set screen's title text

"},{"title":"module:AlbumView.setupMainNode","link":"setupMainNode"},{"title":"module:Alpha","link":"Alpha"},{"title":"module:Alpha.init","link":"init"},{"title":"module:Alpha.onKeyEvent","link":"onKeyEvent"},{"title":"module:ArtistView","link":"ArtistView"},{"title":"module:ArtistView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:ArtistView.OnScreenShown","link":"OnScreenShown"},{"title":"module:ArtistView.artistOverviewChanged","link":"artistOverviewChanged","description":"

Event fired when page data is loaded

"},{"title":"module:ArtistView.createDialogPallete","link":"createDialogPallete"},{"title":"module:ArtistView.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:ArtistView.dscrShowFocus","link":"dscrShowFocus"},{"title":"module:ArtistView.init","link":"init"},{"title":"module:ArtistView.onAlbumsData","link":"onAlbumsData"},{"title":"module:ArtistView.onAlbumsEscape","link":"onAlbumsEscape"},{"title":"module:ArtistView.onAppearsOnData","link":"onAppearsOnData"},{"title":"module:ArtistView.onAppearsOnEscape","link":"onAppearsOnEscape"},{"title":"module:ArtistView.onBackdropImageLoaded","link":"onBackdropImageLoaded"},{"title":"module:ArtistView.onButtonSelectedChange","link":"onButtonSelectedChange","description":"

Event handler when user selected a different playback button

"},{"title":"module:ArtistView.onEllipsisChanged","link":"onEllipsisChanged"},{"title":"module:ArtistView.onKeyEvent","link":"onKeyEvent"},{"title":"module:ArtistView.onSectionNavigationEscape","link":"onSectionNavigationEscape"},{"title":"module:ArtistView.onSectionNavigationSelected","link":"onSectionNavigationSelected"},{"title":"module:ArtistView.onSectionScrollerChange","link":"onSectionScrollerChange"},{"title":"module:ArtistView.pageContentChanged","link":"pageContentChanged","description":"

Event fired when page data is loaded

"},{"title":"module:ArtistView.setBackdropImage","link":"setBackdropImage","description":"

Add backdrop image to screen

"},{"title":"module:ArtistView.setPosterImage","link":"setPosterImage"},{"title":"module:ArtistView.setScreenTitle","link":"setScreenTitle"},{"title":"module:ArtistView.setupButtons","link":"setupButtons","description":"

Setup playback buttons, default to Play button selected

"},{"title":"module:ArtistView.setupMainNode","link":"setupMainNode"},{"title":"module:AudioPlayer","link":"AudioPlayer"},{"title":"module:AudioPlayer.ReportPlayback","link":"ReportPlayback","description":"

Report playback to server

"},{"title":"module:AudioPlayer.audioStateChanged","link":"audioStateChanged","description":"

State Change Event Handler

"},{"title":"module:AudioPlayer.init","link":"init"},{"title":"module:AudioPlayerView","link":"AudioPlayerView"},{"title":"module:AudioPlayerView.LoadNextSong","link":"LoadNextSong"},{"title":"module:AudioPlayerView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:AudioPlayerView.audioPositionChanged","link":"audioPositionChanged"},{"title":"module:AudioPlayerView.audioStateChanged","link":"audioStateChanged"},{"title":"module:AudioPlayerView.bufferPositionChanged","link":"bufferPositionChanged"},{"title":"module:AudioPlayerView.endScreenSaver","link":"endScreenSaver"},{"title":"module:AudioPlayerView.exitScrubMode","link":"exitScrubMode","description":"

exitScrubMode: Moves player out of scrub mode state, resets back to standard play mode

"},{"title":"module:AudioPlayerView.findCurrentSongIndex","link":"findCurrentSongIndex"},{"title":"module:AudioPlayerView.init","link":"init"},{"title":"module:AudioPlayerView.loadButtons","link":"loadButtons","description":"

If we have more and 1 song to play, fade in the next and previous controls

"},{"title":"module:AudioPlayerView.loopClicked","link":"loopClicked"},{"title":"module:AudioPlayerView.moveSeekbarThumb","link":"moveSeekbarThumb","description":"

moveSeekbarThumb: Positions the thumb on the seekbar

"},{"title":"module:AudioPlayerView.nextClicked","link":"nextClicked"},{"title":"module:AudioPlayerView.onAudioStreamLoaded","link":"onAudioStreamLoaded"},{"title":"module:AudioPlayerView.onBackdropImageLoaded","link":"onBackdropImageLoaded"},{"title":"module:AudioPlayerView.onButtonSelectedChange","link":"onButtonSelectedChange","description":"

Event handler when user selected a different playback button

"},{"title":"module:AudioPlayerView.onKeyEvent","link":"onKeyEvent","description":"

Process key press events

"},{"title":"module:AudioPlayerView.onMetaDataLoaded","link":"onMetaDataLoaded"},{"title":"module:AudioPlayerView.onScreensaverTimeoutLoaded","link":"onScreensaverTimeoutLoaded"},{"title":"module:AudioPlayerView.pageContentChanged","link":"pageContentChanged","description":"

Update values on screen when page content changes

"},{"title":"module:AudioPlayerView.playAction","link":"playAction"},{"title":"module:AudioPlayerView.previousClicked","link":"previousClicked"},{"title":"module:AudioPlayerView.processScrubAction","link":"processScrubAction","description":"

processScrubAction: Handles +/- seeking for the audio trickplay bar

"},{"title":"module:AudioPlayerView.resetLoopModeToDefault","link":"resetLoopModeToDefault"},{"title":"module:AudioPlayerView.resetSeekbarThumb","link":"resetSeekbarThumb","description":"

resetSeekbarThumb: Resets the thumb to the playing position

"},{"title":"module:AudioPlayerView.screenSaverActive","link":"screenSaverActive"},{"title":"module:AudioPlayerView.setBackdropImage","link":"setBackdropImage","description":"

Add backdrop image to screen

"},{"title":"module:AudioPlayerView.setLoopButtonImage","link":"setLoopButtonImage"},{"title":"module:AudioPlayerView.setOnScreenTextValues","link":"setOnScreenTextValues","description":"

Populate on screen text variables

"},{"title":"module:AudioPlayerView.setPosterImage","link":"setPosterImage","description":"

Set poster image on screen

"},{"title":"module:AudioPlayerView.setScreenTitle","link":"setScreenTitle","description":"

Set screen's title text

"},{"title":"module:AudioPlayerView.setSelectedButtonState","link":"setSelectedButtonState","description":"

setSelectedButtonState: Changes the icon state url for the currently selected button

"},{"title":"module:AudioPlayerView.setShuffleIconState","link":"setShuffleIconState"},{"title":"module:AudioPlayerView.setTrackNumberDisplay","link":"setTrackNumberDisplay"},{"title":"module:AudioPlayerView.setupAnimationTasks","link":"setupAnimationTasks"},{"title":"module:AudioPlayerView.setupButtons","link":"setupButtons","description":"

Setup playback buttons, default to Play button selected

"},{"title":"module:AudioPlayerView.setupDataTasks","link":"setupDataTasks","description":"

Creates tasks to gather data needed to render Scene and play song

"},{"title":"module:AudioPlayerView.setupInfoNodes","link":"setupInfoNodes"},{"title":"module:AudioPlayerView.setupScreenSaver","link":"setupScreenSaver"},{"title":"module:AudioPlayerView.shuffleClicked","link":"shuffleClicked"},{"title":"module:AudioPlayerView.startScreenSaver","link":"startScreenSaver"},{"title":"module:AudioPlayerView.toggleShuffleEnabled","link":"toggleShuffleEnabled"},{"title":"module:AudioTrackListItem","link":"AudioTrackListItem"},{"title":"module:AudioTrackListItem.focusChanged","link":"focusChanged","description":"

Scroll description if focused

"},{"title":"module:AudioTrackListItem.init","link":"init"},{"title":"module:AudioTrackListItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:ButtonGroupHoriz","link":"ButtonGroupHoriz"},{"title":"module:ButtonGroupHoriz.init","link":"init"},{"title":"module:ButtonGroupHoriz.onKeyEvent","link":"onKeyEvent"},{"title":"module:ButtonGroupVert","link":"ButtonGroupVert"},{"title":"module:ButtonGroupVert.init","link":"init"},{"title":"module:ButtonGroupVert.onFocusButtonChanged","link":"onFocusButtonChanged"},{"title":"module:ButtonGroupVert.onFocusChanged","link":"onFocusChanged"},{"title":"module:ButtonGroupVert.onKeyEvent","link":"onKeyEvent"},{"title":"module:ChannelData","link":"ChannelData"},{"title":"module:ChannelData.setFields","link":"setFields"},{"title":"module:ChannelData.setPoster","link":"setPoster"},{"title":"module:Clock","link":"Clock"},{"title":"module:Clock.ClockFormat","link":"ClockFormat","description":"

Possible clock formats

"},{"title":"module:Clock.ClockFormat.h12","link":"h12"},{"title":"module:Clock.ClockFormat.h24","link":"h24"},{"title":"module:Clock.format12HourTime","link":"format12HourTime","description":"

format12HourTime: Returns a string with the current time formatted for a 12 hour clock

"},{"title":"module:Clock.format24HourTime","link":"format24HourTime","description":"

format24HourTime: Returns a string with the current time formatted for a 24 hour clock

"},{"title":"module:Clock.formatTimeAsString","link":"formatTimeAsString","description":"

formatTimeAsString: Returns a string with the current time formatted for either a 12 or 24 hour clock

"},{"title":"module:Clock.init","link":"init"},{"title":"module:Clock.onCurrentTimeTimerFire","link":"onCurrentTimeTimerFire","description":"

onCurrentTimeTimerFire: Code that runs every time the currentTimeTimer fires

"},{"title":"module:CollectionData","link":"CollectionData"},{"title":"module:CollectionData.setFields","link":"setFields"},{"title":"module:CollectionData.setPoster","link":"setPoster"},{"title":"module:ConfigData","link":"ConfigData"},{"title":"module:ConfigData.init","link":"init"},{"title":"module:ConfigItem","link":"ConfigItem"},{"title":"module:ConfigItem.init","link":"init"},{"title":"module:ConfigItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:ConfigItem.setColors","link":"setColors"},{"title":"module:ConfigList","link":"ConfigList"},{"title":"module:ConfigList.configListShowDialog","link":"configListShowDialog"},{"title":"module:ConfigList.dismiss_dialog","link":"dismiss_dialog"},{"title":"module:ConfigList.init","link":"init"},{"title":"module:ConfigList.onDialogButton","link":"onDialogButton"},{"title":"module:ConfigList.onItemSelected","link":"onItemSelected"},{"title":"module:ConfigList.setData","link":"setData"},{"title":"module:ExtrasItem","link":"ExtrasItem"},{"title":"module:ExtrasItem.focusChanged","link":"focusChanged"},{"title":"module:ExtrasItem.init","link":"init"},{"title":"module:ExtrasItem.initName","link":"initName"},{"title":"module:ExtrasItem.initPosterImg","link":"initPosterImg"},{"title":"module:ExtrasItem.initRole","link":"initRole"},{"title":"module:ExtrasItem.showContent","link":"showContent"},{"title":"module:ExtrasRowList","link":"ExtrasRowList"},{"title":"module:ExtrasRowList.addRowSize","link":"addRowSize"},{"title":"module:ExtrasRowList.buildRow","link":"buildRow"},{"title":"module:ExtrasRowList.init","link":"init"},{"title":"module:ExtrasRowList.loadParts","link":"loadParts"},{"title":"module:ExtrasRowList.loadPersonVideos","link":"loadPersonVideos"},{"title":"module:ExtrasRowList.onAdditionalPartsLoaded","link":"onAdditionalPartsLoaded"},{"title":"module:ExtrasRowList.onLikeThisLoaded","link":"onLikeThisLoaded"},{"title":"module:ExtrasRowList.onMoviesLoaded","link":"onMoviesLoaded"},{"title":"module:ExtrasRowList.onPeopleLoaded","link":"onPeopleLoaded"},{"title":"module:ExtrasRowList.onRowItemFocused","link":"onRowItemFocused"},{"title":"module:ExtrasRowList.onRowItemSelected","link":"onRowItemSelected"},{"title":"module:ExtrasRowList.onSeriesLoaded","link":"onSeriesLoaded"},{"title":"module:ExtrasRowList.onShowsLoaded","link":"onShowsLoaded"},{"title":"module:ExtrasRowList.onSpecialFeaturesLoaded","link":"onSpecialFeaturesLoaded"},{"title":"module:ExtrasRowList.showOrHideMe","link":"showOrHideMe","description":"

don't show popup panel if there is nothing to show

"},{"title":"module:ExtrasRowList.updateSize","link":"updateSize"},{"title":"module:FavoriteItemsTask","link":"FavoriteItemsTask"},{"title":"module:FavoriteItemsTask.init","link":"init"},{"title":"module:FavoriteItemsTask.setFavoriteStatus","link":"setFavoriteStatus"},{"title":"module:FolderData","link":"FolderData"},{"title":"module:FolderData.setFields","link":"setFields"},{"title":"module:FolderData.setPoster","link":"setPoster"},{"title":"module:GetFiltersTask","link":"GetFiltersTask"},{"title":"module:GetFiltersTask.getFiltersTask","link":"getFiltersTask"},{"title":"module:GetFiltersTask.init","link":"init"},{"title":"module:GetNextEpisodeTask","link":"GetNextEpisodeTask"},{"title":"module:GetNextEpisodeTask.getNextEpisodeTask","link":"getNextEpisodeTask"},{"title":"module:GetNextEpisodeTask.init","link":"init"},{"title":"module:GetPlaybackInfoTask","link":"GetPlaybackInfoTask"},{"title":"module:GetPlaybackInfoTask.GetTranscodingStats","link":"GetTranscodingStats"},{"title":"module:GetPlaybackInfoTask.ItemPostPlaybackInfo","link":"ItemPostPlaybackInfo"},{"title":"module:GetPlaybackInfoTask.getDisplayBitrate","link":"getDisplayBitrate"},{"title":"module:GetPlaybackInfoTask.getPlaybackInfoTask","link":"getPlaybackInfoTask","description":"

Returns an array of playback info to be displayed during playback.\nIn the future, with a custom playback info view, we can return an associated array.

"},{"title":"module:GetPlaybackInfoTask.havePlaybackInfo","link":"havePlaybackInfo"},{"title":"module:GetPlaybackInfoTask.init","link":"init"},{"title":"module:GetShuffleEpisodesTask","link":"GetShuffleEpisodesTask"},{"title":"module:GetShuffleEpisodesTask.getShuffleEpisodesTask","link":"getShuffleEpisodesTask"},{"title":"module:GetShuffleEpisodesTask.init","link":"init"},{"title":"module:GridItem","link":"GridItem"},{"title":"module:GridItem.focusChanged","link":"focusChanged","description":"

Display or hide title Visibility on focus change

"},{"title":"module:GridItem.focusChanging","link":"focusChanging","description":"

Use FocusPercent to animate scaling of Poser Image

"},{"title":"module:GridItem.init","link":"init"},{"title":"module:GridItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:GridItem.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and text when poster loaded

"},{"title":"module:GridItemSmall","link":"GridItemSmall"},{"title":"module:GridItemSmall.focusChanged","link":"focusChanged"},{"title":"module:GridItemSmall.init","link":"init"},{"title":"module:GridItemSmall.initTitle","link":"initTitle"},{"title":"module:GridItemSmall.itemContentChanged","link":"itemContentChanged"},{"title":"module:GridItemSmall.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and text when poster loaded

"},{"title":"module:Home","link":"Home"},{"title":"module:Home.OnScreenHidden","link":"OnScreenHidden","description":"

JFScreen hook called when the screen is hidden by the screen manager

"},{"title":"module:Home.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook called when the screen is displayed by the screen manager

"},{"title":"module:Home.init","link":"init"},{"title":"module:Home.loadLibraries","link":"loadLibraries"},{"title":"module:Home.postFinished","link":"postFinished","description":"

Triggered by m.postTask after completing a post.\nEmpty the task data when finished.

"},{"title":"module:Home.refresh","link":"refresh"},{"title":"module:HomeData","link":"HomeData"},{"title":"module:HomeData.setData","link":"setData"},{"title":"module:HomeItem","link":"HomeItem"},{"title":"module:HomeItem.drawProgressBar","link":"drawProgressBar","description":"

Draws and animates item progress bar

"},{"title":"module:HomeItem.focusChanged","link":"focusChanged","description":"

Enable title scrolling based on item Focus

"},{"title":"module:HomeItem.init","link":"init"},{"title":"module:HomeItem.initBackdrop","link":"initBackdrop"},{"title":"module:HomeItem.initItemIcon","link":"initItemIcon"},{"title":"module:HomeItem.initItemPoster","link":"initItemPoster"},{"title":"module:HomeItem.initItemText","link":"initItemText"},{"title":"module:HomeItem.initItemTextExtra","link":"initItemTextExtra"},{"title":"module:HomeItem.initPlayedIndicator","link":"initPlayedIndicator"},{"title":"module:HomeItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:HomeItem.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and icon when poster loaded

"},{"title":"module:HomeRows","link":"HomeRows"},{"title":"module:HomeRows.LOADING_WAIT_TIME","link":"LOADING_WAIT_TIME"},{"title":"module:HomeRows.addHomeSection","link":"addHomeSection","description":"

addHomeSection: Adds a new home section to the home rows.

"},{"title":"module:HomeRows.createContinueWatchingRow","link":"createContinueWatchingRow","description":"

createContinueWatchingRow: Creates a row displaying items the user can continue watching

"},{"title":"module:HomeRows.createFavoritesRow","link":"createFavoritesRow","description":"

createFavoritesRow: Creates a row displaying items from the user's favorites list

"},{"title":"module:HomeRows.createLatestInRows","link":"createLatestInRows","description":"

createLatestInRows: Creates a row displaying latest items in each of the user's libraries

"},{"title":"module:HomeRows.createLibraryRow","link":"createLibraryRow","description":"

createLibraryRow: Creates a row displaying the user's libraries

"},{"title":"module:HomeRows.createLiveTVRow","link":"createLiveTVRow","description":"

createLiveTVRow: Creates a row displaying the live tv now on section

"},{"title":"module:HomeRows.createNextUpRow","link":"createNextUpRow","description":"

createNextUpRow: Creates a row displaying next episodes up to watch

"},{"title":"module:HomeRows.filterNodeArray","link":"filterNodeArray"},{"title":"module:HomeRows.getOriginalSectionIndex","link":"getOriginalSectionIndex","description":"

getOriginalSectionIndex: Gets the index of a section from user settings and adds count of currently known latest media sections

"},{"title":"module:HomeRows.getSectionIndex","link":"getSectionIndex","description":"

getSectionIndex: Returns index of requested section in home row content

"},{"title":"module:HomeRows.init","link":"init"},{"title":"module:HomeRows.itemSelected","link":"itemSelected"},{"title":"module:HomeRows.loadLibraries","link":"loadLibraries"},{"title":"module:HomeRows.loadingTimerComplete","link":"loadingTimerComplete","description":"

loadingTimerComplete: Event handler for when loading wait time has expired

"},{"title":"module:HomeRows.onKeyEvent","link":"onKeyEvent"},{"title":"module:HomeRows.onLibrariesLoaded","link":"onLibrariesLoaded","description":"

onLibrariesLoaded: Handler when LoadLibrariesTask returns data

"},{"title":"module:HomeRows.processUserSections","link":"processUserSections","description":"

processUserSections: Loop through user's chosen home section settings and generate the content for each row

"},{"title":"module:HomeRows.removeHomeSection","link":"removeHomeSection","description":"

removeHomeSection: Removes a home section from the home rows

"},{"title":"module:HomeRows.sectionExists","link":"sectionExists","description":"

sectionExists: Checks if passed section exists in home row content

"},{"title":"module:HomeRows.setRowItemSize","link":"setRowItemSize","description":"

setRowItemSize: Loops through all home sections and sets the correct item sizes per row

"},{"title":"module:HomeRows.updateContinueWatchingItems","link":"updateContinueWatchingItems","description":"

updateContinueWatchingItems: Processes LoadContinueWatchingTask content. Removes, Creates, or Updates continue watching row as needed

"},{"title":"module:HomeRows.updateFavoritesItems","link":"updateFavoritesItems","description":"

updateFavoritesItems: Processes LoadFavoritesTask content. Removes, Creates, or Updates favorites row as needed

"},{"title":"module:HomeRows.updateHomeRows","link":"updateHomeRows","description":"

updateHomeRows: Update function exposed to outside components

"},{"title":"module:HomeRows.updateLatestItems","link":"updateLatestItems","description":"

updateLatestItems: Processes LoadItemsTask content. Removes, Creates, or Updates latest in {library} row as needed

"},{"title":"module:HomeRows.updateNextUpItems","link":"updateNextUpItems","description":"

updateNextUpItems: Processes LoadNextUpTask content. Removes, Creates, or Updates next up row as needed

"},{"title":"module:HomeRows.updateOnNowItems","link":"updateOnNowItems","description":"

updateOnNowItems: Processes LoadOnNowTask content. Removes, Creates, or Updates latest in on now row as needed

"},{"title":"module:HomeRows.updateSize","link":"updateSize"},{"title":"module:IconButton","link":"IconButton"},{"title":"module:IconButton.init","link":"init"},{"title":"module:IconButton.onBackgroundChanged","link":"onBackgroundChanged"},{"title":"module:IconButton.onFocusChanged","link":"onFocusChanged"},{"title":"module:IconButton.onHeightChanged","link":"onHeightChanged"},{"title":"module:IconButton.onIconChanged","link":"onIconChanged"},{"title":"module:IconButton.onKeyEvent","link":"onKeyEvent"},{"title":"module:IconButton.onPaddingChanged","link":"onPaddingChanged"},{"title":"module:IconButton.onTextChanged","link":"onTextChanged"},{"title":"module:IconButton.onWidthChanged","link":"onWidthChanged"},{"title":"module:IconButton.setIconSize","link":"setIconSize"},{"title":"module:Image","link":"Image"},{"title":"module:Image.ImageURL","link":"ImageURL"},{"title":"module:Image.ItemImages","link":"ItemImages"},{"title":"module:Image.PosterImage","link":"PosterImage"},{"title":"module:Image.UserImageURL","link":"UserImageURL"},{"title":"module:ImageData","link":"ImageData"},{"title":"module:ImageData.setFields","link":"setFields"},{"title":"module:IntegerKeyboard","link":"IntegerKeyboard"},{"title":"module:IntegerKeyboard.init","link":"init"},{"title":"module:IntegerKeyboard.keySelected","link":"keySelected"},{"title":"module:IntegerKeyboard.onKeyEvent","link":"onKeyEvent"},{"title":"module:ItemGrid","link":"ItemGrid"},{"title":"module:ItemGrid.ItemDataLoaded","link":"ItemDataLoaded","description":"

Handle loaded data, and add to Grid

"},{"title":"module:ItemGrid.SetBackground","link":"SetBackground","description":"

Set Background Image

"},{"title":"module:ItemGrid.SetUpOptions","link":"SetUpOptions","description":"

Data to display when options button selected

"},{"title":"module:ItemGrid.alphaActiveChanged","link":"alphaActiveChanged"},{"title":"module:ItemGrid.alphaSelectedChanged","link":"alphaSelectedChanged"},{"title":"module:ItemGrid.getCollectionType","link":"getCollectionType","description":"

Return parent collection type

"},{"title":"module:ItemGrid.getItemFocused","link":"getItemFocused","description":"

Returns Focused Item

"},{"title":"module:ItemGrid.inStringArray","link":"inStringArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:ItemGrid.init","link":"init"},{"title":"module:ItemGrid.loadInitialItems","link":"loadInitialItems","description":"

Load initial set of Data

"},{"title":"module:ItemGrid.loadMoreData","link":"loadMoreData","description":"

Load next set of items

"},{"title":"module:ItemGrid.newBGLoaded","link":"newBGLoaded","description":"

When Image Loading Status changes

"},{"title":"module:ItemGrid.onChannelFocused","link":"onChannelFocused"},{"title":"module:ItemGrid.onChannelSelected","link":"onChannelSelected"},{"title":"module:ItemGrid.onGenreItemSelected","link":"onGenreItemSelected","description":"

Genre Item Selected

"},{"title":"module:ItemGrid.onItemFocused","link":"onItemFocused","description":"

Handle new item being focused

"},{"title":"module:ItemGrid.onItemSelected","link":"onItemSelected","description":"

Item Selected

"},{"title":"module:ItemGrid.onKeyEvent","link":"onKeyEvent"},{"title":"module:ItemGrid.onvoiceFilter","link":"onvoiceFilter"},{"title":"module:ItemGrid.optionsClosed","link":"optionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:ItemGrid.setBoxsetsOptions","link":"setBoxsetsOptions","description":"

Set Boxset view, sort, and filter options

"},{"title":"module:ItemGrid.setDefaultOptions","link":"setDefaultOptions","description":"

Set Default view, sort, and filter options

"},{"title":"module:ItemGrid.setLiveTvOptions","link":"setLiveTvOptions","description":"

Set Live TV view, sort, and filter options

"},{"title":"module:ItemGrid.setMoviesOptions","link":"setMoviesOptions","description":"

Set Movies view, sort, and filter options

"},{"title":"module:ItemGrid.setMusicOptions","link":"setMusicOptions","description":"

Set Music view, sort, and filter options

"},{"title":"module:ItemGrid.setPhotoAlbumOptions","link":"setPhotoAlbumOptions","description":"

Set Photo Album view, sort, and filter options

"},{"title":"module:ItemGrid.setTvShowsOptions","link":"setTvShowsOptions","description":"

Set TV Show view, sort, and filter options

"},{"title":"module:ItemGrid.showTVGuide","link":"showTVGuide"},{"title":"module:ItemGrid.swapDone","link":"swapDone","description":"

Swap Complete

"},{"title":"module:ItemGrid.updateTitle","link":"updateTitle"},{"title":"module:ItemGridOptions","link":"ItemGridOptions"},{"title":"module:ItemGridOptions.buttonFocusChanged","link":"buttonFocusChanged","description":"

Switch menu shown when button focus changes

"},{"title":"module:ItemGridOptions.hideChecklist","link":"hideChecklist"},{"title":"module:ItemGridOptions.init","link":"init"},{"title":"module:ItemGridOptions.isFilterMenuDataValid","link":"isFilterMenuDataValid","description":"

Check if data for Filter Menu is valid

"},{"title":"module:ItemGridOptions.onFilterFocusChange","link":"onFilterFocusChange"},{"title":"module:ItemGridOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:ItemGridOptions.optionsSet","link":"optionsSet"},{"title":"module:ItemGridOptions.saveFavoriteItemSelected","link":"saveFavoriteItemSelected"},{"title":"module:ItemGridOptions.setHeartColor","link":"setHeartColor"},{"title":"module:ItemGridOptions.showChecklist","link":"showChecklist"},{"title":"module:ItemGridOptions.toggleFavorite","link":"toggleFavorite"},{"title":"module:Items","link":"Items"},{"title":"module:Items.AppearsOnList","link":"AppearsOnList","description":"

Get list of albums an artist appears on

"},{"title":"module:Items.ArtistOverview","link":"ArtistOverview","description":"

Music Artist Data

"},{"title":"module:Items.AudioItem","link":"AudioItem","description":"

Get Songs that are on an Album

"},{"title":"module:Items.AudioStream","link":"AudioStream"},{"title":"module:Items.BackdropImage","link":"BackdropImage"},{"title":"module:Items.CreateArtistMix","link":"CreateArtistMix","description":"

Get Instant Mix based on item

"},{"title":"module:Items.CreateInstantMix","link":"CreateInstantMix","description":"

Get Instant Mix based on item

"},{"title":"module:Items.GetIntroVideos","link":"GetIntroVideos","description":"

Get Intro Videos for an item

"},{"title":"module:Items.GetSongsByArtist","link":"GetSongsByArtist","description":"

Get list of songs belonging to an artist

"},{"title":"module:Items.ItemGetPlaybackInfo","link":"ItemGetPlaybackInfo"},{"title":"module:Items.ItemMetaData","link":"ItemMetaData","description":"

MetaData about an item

"},{"title":"module:Items.ItemPostPlaybackInfo","link":"ItemPostPlaybackInfo"},{"title":"module:Items.MusicAlbumList","link":"MusicAlbumList","description":"

Get list of albums belonging to an artist

"},{"title":"module:Items.MusicSongList","link":"MusicSongList","description":"

Get Songs that are on an Album

"},{"title":"module:Items.PlaylistItemList","link":"PlaylistItemList","description":"

Get Items that are under the provided item

"},{"title":"module:Items.TVEpisodeShuffleList","link":"TVEpisodeShuffleList"},{"title":"module:Items.TVEpisodes","link":"TVEpisodes","description":"

Returns a list of TV Shows for a given TV Show and season\nAccepts strings for the TV Show Id and the season Id

"},{"title":"module:Items.TVSeasonExtras","link":"TVSeasonExtras","description":"

Returns a list of extra features for a TV Show season\nAccepts a string that is a TV Show season id

"},{"title":"module:Items.TVSeasons","link":"TVSeasons","description":"

Seasons for a TV Show

"},{"title":"module:Items.forceMp3Audio","link":"forceMp3Audio","description":"

updates the device profile we send the server to force mp3 audio transcoding instead of the default aac

"},{"title":"module:Items.searchMedia","link":"searchMedia","description":"

Search across all libraries

"},{"title":"module:Items.useTranscodeAudioStream","link":"useTranscodeAudioStream"},{"title":"module:JFButton","link":"JFButton"},{"title":"module:JFButton.init","link":"init"},{"title":"module:JFButton.onTextChanged","link":"onTextChanged","description":"

Whenever the text changes, pad both sides with whitespace so we can center the button text

"},{"title":"module:JFButtons","link":"JFButtons"},{"title":"module:JFButtons.focusChanged","link":"focusChanged","description":"

Change opacity of the highlighted menu item based on focus

"},{"title":"module:JFButtons.highlightSelected","link":"highlightSelected","description":"

Highlight selected menu option

"},{"title":"module:JFButtons.init","link":"init"},{"title":"module:JFButtons.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFButtons.renderChanged","link":"renderChanged","description":"

When options are fully displayed, set focus and selected option

"},{"title":"module:JFButtons.selectedIndexChanged","link":"selectedIndexChanged","description":"

When Selected Index set, ensure it is the one Focused

"},{"title":"module:JFButtons.showButtons","link":"showButtons"},{"title":"module:JFButtons.updateButtons","link":"updateButtons"},{"title":"module:JFContentItem","link":"JFContentItem"},{"title":"module:JFContentItem.setFields","link":"setFields","description":"

Called whenever m.top.json changes.\nIt is expected that each node that extends JFContentItem will override this function

"},{"title":"module:JFGroup","link":"JFGroup"},{"title":"module:JFGroup.init","link":"init"},{"title":"module:JFGroup.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFMessageDialog","link":"JFMessageDialog"},{"title":"module:JFMessageDialog.init","link":"init"},{"title":"module:JFMessageDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFMessageDialog.redraw","link":"redraw"},{"title":"module:JFMessageDialog.updateMessage","link":"updateMessage"},{"title":"module:JFMessageDialog.updateOptions","link":"updateOptions"},{"title":"module:JFOverhang","link":"JFOverhang"},{"title":"module:JFOverhang.init","link":"init"},{"title":"module:JFOverhang.isLogoVisibleChange","link":"isLogoVisibleChange","description":"

component boolean field isLogoVisibleChange has changed value

"},{"title":"module:JFOverhang.onVisibleChange","link":"onVisibleChange"},{"title":"module:JFOverhang.resetTime","link":"resetTime"},{"title":"module:JFOverhang.setClockVisibility","link":"setClockVisibility"},{"title":"module:JFOverhang.setRightSeperatorVisibility","link":"setRightSeperatorVisibility"},{"title":"module:JFOverhang.updateOptions","link":"updateOptions"},{"title":"module:JFOverhang.updateTime","link":"updateTime"},{"title":"module:JFOverhang.updateTimeDisplay","link":"updateTimeDisplay"},{"title":"module:JFOverhang.updateTitle","link":"updateTitle"},{"title":"module:JFOverhang.updateUser","link":"updateUser"},{"title":"module:JFScene","link":"JFScene"},{"title":"module:JFScene.disableRemoteChanged","link":"disableRemoteChanged","description":"

Triggered when the disableRemote boolean component field is changed

"},{"title":"module:JFScene.init","link":"init"},{"title":"module:JFScene.isLoadingChanged","link":"isLoadingChanged","description":"

Triggered when the isLoading boolean component field is changed

"},{"title":"module:JFScene.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFScreen","link":"JFScreen"},{"title":"module:JFScreen.OnScreenHidden","link":"OnScreenHidden","description":"

Function called when the screen is hidden by the screen manager\nIt is expected that screens override this function if required,\nto handle focus any actions required on the screen being hidden

"},{"title":"module:JFScreen.OnScreenShown","link":"OnScreenShown","description":"

Function called when the screen is displayed by the screen manager\nIt is expected that screens override this function to handle focus\nmanagmenet and any other actions required on screen shown

"},{"title":"module:JFScreen.init","link":"init"},{"title":"module:JFServer","link":"JFServer"},{"title":"module:JFServer.init","link":"init"},{"title":"module:JFServer.itemContentChanged","link":"itemContentChanged"},{"title":"module:JFServer.onFocusPercentChange","link":"onFocusPercentChange"},{"title":"module:JFServer.setTextColor","link":"setTextColor"},{"title":"module:JFVideo","link":"JFVideo"},{"title":"module:JFVideo.ReportPlayback","link":"ReportPlayback","description":"

Report playback to server

"},{"title":"module:JFVideo.bufferCheck","link":"bufferCheck","description":"

Check the the buffering has not hung

"},{"title":"module:JFVideo.checkTimeToDisplayNextEpisode","link":"checkTimeToDisplayNextEpisode","description":"

Checks if we need to display the Next Episode button

"},{"title":"module:JFVideo.hideNextEpisodeButton","link":"hideNextEpisodeButton","description":"

Runs hide Next Episode button animation and sets focus back to video

"},{"title":"module:JFVideo.init","link":"init"},{"title":"module:JFVideo.loadCaption","link":"loadCaption"},{"title":"module:JFVideo.onAllowCaptionsChange","link":"onAllowCaptionsChange"},{"title":"module:JFVideo.onContentChange","link":"onContentChange","description":"

Event handler for when video content field changes

"},{"title":"module:JFVideo.onKeyEvent","link":"onKeyEvent"},{"title":"module:JFVideo.onNextEpisodeDataLoaded","link":"onNextEpisodeDataLoaded"},{"title":"module:JFVideo.onPositionChanged","link":"onPositionChanged","description":"

When Video Player state changes

"},{"title":"module:JFVideo.onState","link":"onState","description":"

When Video Player state changes

"},{"title":"module:JFVideo.showNextEpisodeButton","link":"showNextEpisodeButton","description":"

Runs Next Episode button animation and sets focus to button

"},{"title":"module:JFVideo.toggleCaption","link":"toggleCaption"},{"title":"module:JFVideo.updateCaption","link":"updateCaption"},{"title":"module:JFVideo.updateCount","link":"updateCount","description":"

Update count down text

"},{"title":"module:ListPoster","link":"ListPoster"},{"title":"module:ListPoster.focusChanged","link":"focusChanged","description":"

Enable title scrolling based on item Focus

"},{"title":"module:ListPoster.init","link":"init"},{"title":"module:ListPoster.itemContentChanged","link":"itemContentChanged"},{"title":"module:ListPoster.updateSize","link":"updateSize"},{"title":"module:LoadChannelsTask","link":"LoadChannelsTask"},{"title":"module:LoadChannelsTask.init","link":"init"},{"title":"module:LoadChannelsTask.loadChannels","link":"loadChannels"},{"title":"module:LoadItemsTask","link":"LoadItemsTask"},{"title":"module:LoadItemsTask.getPersonVideos","link":"getPersonVideos"},{"title":"module:LoadItemsTask.init","link":"init"},{"title":"module:LoadItemsTask.loadItems","link":"loadItems"},{"title":"module:LoadItemsTask2","link":"LoadItemsTask2"},{"title":"module:LoadItemsTask2.init","link":"init"},{"title":"module:LoadItemsTask2.loadItems","link":"loadItems"},{"title":"module:LoadPhotoTask","link":"LoadPhotoTask"},{"title":"module:LoadPhotoTask.init","link":"init"},{"title":"module:LoadPhotoTask.loadItems","link":"loadItems"},{"title":"module:LoadProgramDetailsTask","link":"LoadProgramDetailsTask"},{"title":"module:LoadProgramDetailsTask.init","link":"init"},{"title":"module:LoadProgramDetailsTask.loadProgramDetails","link":"loadProgramDetails"},{"title":"module:LoadScreenSaverTimeoutTask","link":"LoadScreenSaverTimeoutTask"},{"title":"module:LoadScreenSaverTimeoutTask.getScreensaverTimeout","link":"getScreensaverTimeout"},{"title":"module:LoadScreenSaverTimeoutTask.init","link":"init"},{"title":"module:LoadSheduleTask","link":"LoadSheduleTask"},{"title":"module:LoadSheduleTask.init","link":"init"},{"title":"module:LoadSheduleTask.loadSchedule","link":"loadSchedule"},{"title":"module:LoadVideoContentTask","link":"LoadVideoContentTask"},{"title":"module:LoadVideoContentTask.FindPreferredAudioStream","link":"FindPreferredAudioStream"},{"title":"module:LoadVideoContentTask.LoadItems_AddVideoContent","link":"LoadItems_AddVideoContent"},{"title":"module:LoadVideoContentTask.LoadItems_VideoPlayer","link":"LoadItems_VideoPlayer"},{"title":"module:LoadVideoContentTask.SubtitleSelection","link":"SubtitleSelection"},{"title":"module:LoadVideoContentTask.SubtitleSelection.none","link":"none"},{"title":"module:LoadVideoContentTask.SubtitleSelection.notset","link":"notset"},{"title":"module:LoadVideoContentTask.addAudioStreamsToVideo","link":"addAudioStreamsToVideo","description":"

addAudioStreamsToVideo: Add audio stream data to video

"},{"title":"module:LoadVideoContentTask.addNextEpisodesToQueue","link":"addNextEpisodesToQueue","description":"

Add next episodes to the playback queue

"},{"title":"module:LoadVideoContentTask.addSubtitlesToVideo","link":"addSubtitlesToVideo"},{"title":"module:LoadVideoContentTask.addVideoContentURL","link":"addVideoContentURL"},{"title":"module:LoadVideoContentTask.defaultSubtitleTrack","link":"defaultSubtitleTrack","description":"

defaultSubtitleTrack:

"},{"title":"module:LoadVideoContentTask.defaultSubtitleTrackFromVid","link":"defaultSubtitleTrackFromVid","description":"

defaultSubtitleTrackFromVid: Identifies the default subtitle track given video id

"},{"title":"module:LoadVideoContentTask.directPlaySupported","link":"directPlaySupported"},{"title":"module:LoadVideoContentTask.getContainerType","link":"getContainerType"},{"title":"module:LoadVideoContentTask.getTranscodeReasons","link":"getTranscodeReasons","description":"

Extract array of Transcode Reasons from the content URL

"},{"title":"module:LoadVideoContentTask.init","link":"init"},{"title":"module:LoadVideoContentTask.loadItems","link":"loadItems"},{"title":"module:LoadVideoContentTask.sortSubtitles","link":"sortSubtitles","description":"

Checks available subtitle tracks and puts subtitles in forced, default, and non-default/forced but preferred language at the top

"},{"title":"module:LoginScene","link":"LoginScene"},{"title":"module:LoginScene.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook.

"},{"title":"module:LoginScene.init","link":"init"},{"title":"module:LoginScene.onKeyEvent","link":"onKeyEvent"},{"title":"module:Main","link":"Main"},{"title":"module:Main.Main","link":"Main"},{"title":"module:MovieData","link":"MovieData"},{"title":"module:MovieData.setContainer","link":"setContainer"},{"title":"module:MovieData.setFields","link":"setFields"},{"title":"module:MovieData.setPoster","link":"setPoster"},{"title":"module:MovieDetails","link":"MovieDetails"},{"title":"module:MovieDetails.OnScreenShown","link":"OnScreenShown","description":"

OnScreenShown: Callback function when view is presented on screen

"},{"title":"module:MovieDetails.SetDefaultAudioTrack","link":"SetDefaultAudioTrack"},{"title":"module:MovieDetails.SetUpAudioOptions","link":"SetUpAudioOptions"},{"title":"module:MovieDetails.SetUpVideoOptions","link":"SetUpVideoOptions"},{"title":"module:MovieDetails.audioOptionsClosed","link":"audioOptionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:MovieDetails.getEndTime","link":"getEndTime"},{"title":"module:MovieDetails.getRuntime","link":"getRuntime"},{"title":"module:MovieDetails.init","link":"init"},{"title":"module:MovieDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:MovieDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:MovieDetails.onMoviePosterSwapAnimationStateChange","link":"onMoviePosterSwapAnimationStateChange","description":"

onMoviePosterSwapAnimationStateChange: Handler for changes to m.moviePosterSwapAnimation.state

"},{"title":"module:MovieDetails.onNewPosterImageURIChange","link":"onNewPosterImageURIChange","description":"

onNewPosterImageURIChange: Handler for newPosterImageURI param change

"},{"title":"module:MovieDetails.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

onPosterLoadStatusChanged: Handler for changes to m.moviePosterSwap.loadStatus

"},{"title":"module:MovieDetails.round","link":"round"},{"title":"module:MovieDetails.setFavoriteColor","link":"setFavoriteColor"},{"title":"module:MovieDetails.setFieldText","link":"setFieldText"},{"title":"module:MovieDetails.setWatchedColor","link":"setWatchedColor"},{"title":"module:MovieDetails.trailerAvailableChanged","link":"trailerAvailableChanged"},{"title":"module:MovieDetails.videoOptionsClosed","link":"videoOptionsClosed","description":"

Check if options were updated and if any reloding is needed...

"},{"title":"module:MovieLibraryView","link":"MovieLibraryView"},{"title":"module:MovieLibraryView.FilterDataLoaded","link":"FilterDataLoaded","description":"

Logo Image Loaded Event Handler

"},{"title":"module:MovieLibraryView.ItemDataLoaded","link":"ItemDataLoaded","description":"

Handle loaded data, and add to Grid

"},{"title":"module:MovieLibraryView.LogoImageLoaded","link":"LogoImageLoaded","description":"

Logo Image Loaded Event Handler

"},{"title":"module:MovieLibraryView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:MovieLibraryView.OnScreenShown","link":"OnScreenShown"},{"title":"module:MovieLibraryView.SetBackground","link":"SetBackground","description":"

Set Background Image

"},{"title":"module:MovieLibraryView.SetName","link":"SetName","description":"

Set Selected Movie Name

"},{"title":"module:MovieLibraryView.SetOfficialRating","link":"SetOfficialRating","description":"

Set Selected Movie OfficialRating

"},{"title":"module:MovieLibraryView.SetOverview","link":"SetOverview","description":"

Set Selected Movie Overview

"},{"title":"module:MovieLibraryView.SetProductionYear","link":"SetProductionYear","description":"

Set Selected Movie ProductionYear

"},{"title":"module:MovieLibraryView.alphaSelectedChanged","link":"alphaSelectedChanged"},{"title":"module:MovieLibraryView.getCollectionType","link":"getCollectionType","description":"

Return parent collection type

"},{"title":"module:MovieLibraryView.getItemFocused","link":"getItemFocused","description":"

Returns Focused Item

"},{"title":"module:MovieLibraryView.getRuntime","link":"getRuntime"},{"title":"module:MovieLibraryView.inStringArray","link":"inStringArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:MovieLibraryView.init","link":"init"},{"title":"module:MovieLibraryView.loadInitialItems","link":"loadInitialItems","description":"

Load initial set of Data

"},{"title":"module:MovieLibraryView.loadMoreData","link":"loadMoreData","description":"

Load next set of items

"},{"title":"module:MovieLibraryView.newBGLoaded","link":"newBGLoaded","description":"

When Image Loading Status changes

"},{"title":"module:MovieLibraryView.onChannelSelected","link":"onChannelSelected"},{"title":"module:MovieLibraryView.onGenreItemSelected","link":"onGenreItemSelected","description":"

Genre Item Selected

"},{"title":"module:MovieLibraryView.onItemFocused","link":"onItemFocused","description":"

Handle new item being focused

"},{"title":"module:MovieLibraryView.onItemSelected","link":"onItemSelected","description":"

Item Selected

"},{"title":"module:MovieLibraryView.onKeyEvent","link":"onKeyEvent"},{"title":"module:MovieLibraryView.onvoiceFilter","link":"onvoiceFilter"},{"title":"module:MovieLibraryView.optionsClosed","link":"optionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:MovieLibraryView.round","link":"round"},{"title":"module:MovieLibraryView.setFieldText","link":"setFieldText"},{"title":"module:MovieLibraryView.setMoviesOptions","link":"setMoviesOptions","description":"

Set Movies view, sort, and filter options

"},{"title":"module:MovieLibraryView.setSelectedOptions","link":"setSelectedOptions","description":"

Data to display when options button selected

"},{"title":"module:MovieLibraryView.setupNodes","link":"setupNodes"},{"title":"module:MovieLibraryView.swapDone","link":"swapDone","description":"

Swap Complete

"},{"title":"module:MovieOptions","link":"MovieOptions"},{"title":"module:MovieOptions.buttonFocusChanged","link":"buttonFocusChanged","description":"

Switch menu shown when button focus changes

"},{"title":"module:MovieOptions.init","link":"init"},{"title":"module:MovieOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:MovieOptions.optionsSet","link":"optionsSet"},{"title":"module:MusicAlbumData","link":"MusicAlbumData"},{"title":"module:MusicAlbumData.setFields","link":"setFields"},{"title":"module:MusicAlbumData.setPoster","link":"setPoster"},{"title":"module:MusicAlbumSongListData","link":"MusicAlbumSongListData"},{"title":"module:MusicAlbumSongListData.setFields","link":"setFields"},{"title":"module:MusicAlbumSongListData.setPoster","link":"setPoster"},{"title":"module:MusicArtistData","link":"MusicArtistData"},{"title":"module:MusicArtistData.setFields","link":"setFields"},{"title":"module:MusicArtistData.setPoster","link":"setPoster"},{"title":"module:MusicArtistGridItem","link":"MusicArtistGridItem"},{"title":"module:MusicArtistGridItem.focusChanged","link":"focusChanged","description":"

Display or hide title Visibility on focus change

"},{"title":"module:MusicArtistGridItem.init","link":"init"},{"title":"module:MusicArtistGridItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:MusicArtistGridItem.onPosterLoadStatusChanged","link":"onPosterLoadStatusChanged","description":"

Hide backdrop and text when poster loaded

"},{"title":"module:MusicLibraryView","link":"MusicLibraryView"},{"title":"module:MusicLibraryView.ItemDataLoaded","link":"ItemDataLoaded","description":"

Handle loaded data, and add to Grid

"},{"title":"module:MusicLibraryView.LogoImageLoaded","link":"LogoImageLoaded","description":"

Logo Image Loaded Event Handler

"},{"title":"module:MusicLibraryView.OnScreenHidden","link":"OnScreenHidden"},{"title":"module:MusicLibraryView.OnScreenShown","link":"OnScreenShown"},{"title":"module:MusicLibraryView.SetAlbumCount","link":"SetAlbumCount","description":"

Set Selected Artist Album Count

"},{"title":"module:MusicLibraryView.SetBackground","link":"SetBackground","description":"

Set Background Image

"},{"title":"module:MusicLibraryView.SetGenres","link":"SetGenres","description":"

Set Selected Artist Genres

"},{"title":"module:MusicLibraryView.SetName","link":"SetName","description":"

Set Selected Artist Name

"},{"title":"module:MusicLibraryView.SetSongCount","link":"SetSongCount","description":"

Set Selected Artist Song Count

"},{"title":"module:MusicLibraryView.SetUpOptions","link":"SetUpOptions","description":"

Data to display when options button selected

"},{"title":"module:MusicLibraryView.alphaSelectedChanged","link":"alphaSelectedChanged"},{"title":"module:MusicLibraryView.getCollectionType","link":"getCollectionType","description":"

Return parent collection type

"},{"title":"module:MusicLibraryView.getItemFocused","link":"getItemFocused","description":"

Returns Focused Item

"},{"title":"module:MusicLibraryView.inStringArray","link":"inStringArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:MusicLibraryView.init","link":"init"},{"title":"module:MusicLibraryView.loadInitialItems","link":"loadInitialItems","description":"

Load initial set of Data

"},{"title":"module:MusicLibraryView.loadMoreData","link":"loadMoreData","description":"

Load next set of items

"},{"title":"module:MusicLibraryView.newBGLoaded","link":"newBGLoaded","description":"

When Image Loading Status changes

"},{"title":"module:MusicLibraryView.onChannelSelected","link":"onChannelSelected"},{"title":"module:MusicLibraryView.onGenreItemFocused","link":"onGenreItemFocused","description":"

Genre Item Focused

"},{"title":"module:MusicLibraryView.onGenreItemSelected","link":"onGenreItemSelected","description":"

Genre Item Selected

"},{"title":"module:MusicLibraryView.onItemFocused","link":"onItemFocused","description":"

Handle new item being focused

"},{"title":"module:MusicLibraryView.onItemSelected","link":"onItemSelected","description":"

Item Selected

"},{"title":"module:MusicLibraryView.onKeyEvent","link":"onKeyEvent"},{"title":"module:MusicLibraryView.onvoiceFilter","link":"onvoiceFilter"},{"title":"module:MusicLibraryView.optionsClosed","link":"optionsClosed","description":"

Check if options updated and any reloading required

"},{"title":"module:MusicLibraryView.setFieldText","link":"setFieldText"},{"title":"module:MusicLibraryView.setMusicOptions","link":"setMusicOptions","description":"

Set Music view, sort, and filter options

"},{"title":"module:MusicLibraryView.setupNodes","link":"setupNodes"},{"title":"module:MusicLibraryView.swapDone","link":"swapDone","description":"

Swap Complete

"},{"title":"module:MusicSongData","link":"MusicSongData"},{"title":"module:MusicSongData.setFields","link":"setFields"},{"title":"module:MusicSongData.setPoster","link":"setPoster"},{"title":"module:OSD","link":"OSD"},{"title":"module:OSD.LOGO_RIGHT_PADDING","link":"LOGO_RIGHT_PADDING"},{"title":"module:OSD.OPTIONCONTROLS_TOP_PADDING","link":"OPTIONCONTROLS_TOP_PADDING"},{"title":"module:OSD.inactiveCheck","link":"inactiveCheck","description":"

inactiveCheck: Checks if the time since last keypress is greater than or equal to the allowed inactive time of the menu.

"},{"title":"module:OSD.init","link":"init"},{"title":"module:OSD.moveOptionControls","link":"moveOptionControls","description":"

moveOptionControls: Moves option controls node based on passed pixel values

"},{"title":"module:OSD.onButtonSelected","link":"onButtonSelected","description":"

onButtonSelected: Handler for selection of buttons from the menu.

"},{"title":"module:OSD.onEpisodeNumberChanged","link":"onEpisodeNumberChanged","description":"

onEpisodeNumberChanged: Handler for changes to m.top.episodeNumber param.

"},{"title":"module:OSD.onEpisodeNumberEndChanged","link":"onEpisodeNumberEndChanged","description":"

onEpisodeNumberEndChanged: Handler for changes to m.top.episodeNumberEnd param.

"},{"title":"module:OSD.onFocusChanged","link":"onFocusChanged","description":"

onFocusChanged: Handler for changes to the focus of this menu.

"},{"title":"module:OSD.onItemTitleTextChanged","link":"onItemTitleTextChanged","description":"

onItemTitleTextChanged: Handler for changes to m.top.itemTitleText param.

"},{"title":"module:OSD.onKeyEvent","link":"onKeyEvent"},{"title":"module:OSD.onLogoImageChanged","link":"onLogoImageChanged","description":"

onLogoImageChanged: Handler for changes to m.top.logoImage param.

"},{"title":"module:OSD.onLogoLoadStatusChanged","link":"onLogoLoadStatusChanged","description":"

onLogoLoadStatusChanged: Handler for changes to logo image's status.

"},{"title":"module:OSD.onPlaybackStateChanged","link":"onPlaybackStateChanged","description":"

onPlaybackStateChanged: Handler for changes to m.top.playbackState param

"},{"title":"module:OSD.onProgressPercentageChanged","link":"onProgressPercentageChanged","description":"

onProgressPercentageChanged: Handler for changes to m.top.progressPercentage param

"},{"title":"module:OSD.onSeasonNumberChanged","link":"onSeasonNumberChanged","description":"

onSeasonNumberChanged: Handler for changes to m.top.seasonNumber param.

"},{"title":"module:OSD.onVisibleChanged","link":"onVisibleChanged","description":"

onVisibleChanged: Handler for changes to the visibility of this menu.

"},{"title":"module:OSD.resetFocusToDefaultButton","link":"resetFocusToDefaultButton","description":"

resetFocusToDefaultButton: Reset focus back to the default button

"},{"title":"module:OptionNode","link":"OptionNode"},{"title":"module:OptionNode.init","link":"init"},{"title":"module:OptionsButton","link":"OptionsButton"},{"title":"module:OptionsButton.init","link":"init"},{"title":"module:OptionsButton.press","link":"press"},{"title":"module:OptionsData","link":"OptionsData"},{"title":"module:OptionsData.init","link":"init"},{"title":"module:OptionsData.press","link":"press"},{"title":"module:OptionsData.update_title","link":"update_title"},{"title":"module:OptionsSlider","link":"OptionsSlider"},{"title":"module:OptionsSlider.init","link":"init"},{"title":"module:OptionsSlider.onKeyEvent","link":"onKeyEvent"},{"title":"module:OptionsSlider.setFields","link":"setFields"},{"title":"module:OverviewDialog","link":"OverviewDialog"},{"title":"module:OverviewDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:OverviewDialog.setOverview","link":"setOverview"},{"title":"module:OverviewDialog.setTitle","link":"setTitle"},{"title":"module:PersonData","link":"PersonData"},{"title":"module:PersonData.setFields","link":"setFields"},{"title":"module:PersonData.setPoster","link":"setPoster"},{"title":"module:PersonDetails","link":"PersonDetails"},{"title":"module:PersonDetails.createDialogPallete","link":"createDialogPallete"},{"title":"module:PersonDetails.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:PersonDetails.dscrShowFocus","link":"dscrShowFocus"},{"title":"module:PersonDetails.init","link":"init"},{"title":"module:PersonDetails.loadPerson","link":"loadPerson"},{"title":"module:PersonDetails.onButtonGroupEscaped","link":"onButtonGroupEscaped"},{"title":"module:PersonDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:PersonDetails.setFavoriteColor","link":"setFavoriteColor"},{"title":"module:PersonDetails.shortDate","link":"shortDate"},{"title":"module:PhotoData","link":"PhotoData"},{"title":"module:PhotoData.setFields","link":"setFields"},{"title":"module:PhotoData.setPoster","link":"setPoster"},{"title":"module:PhotoDetails","link":"PhotoDetails"},{"title":"module:PhotoDetails.OnScreenHidden","link":"OnScreenHidden","description":"

JFScreen hook.\nUsed to ensure tasks are stopped

"},{"title":"module:PhotoDetails.init","link":"init"},{"title":"module:PhotoDetails.isRandomChanged","link":"isRandomChanged","description":"

isRandom component field has changed

"},{"title":"module:PhotoDetails.isSlideshowChanged","link":"isSlideshowChanged","description":"

isSlideshow component field has changed

"},{"title":"module:PhotoDetails.isValidToContinue","link":"isValidToContinue"},{"title":"module:PhotoDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:PhotoDetails.nextSlide","link":"nextSlide"},{"title":"module:PhotoDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:PhotoDetails.onPhotoLoaded","link":"onPhotoLoaded"},{"title":"module:PhotoDetails.statusUpdate","link":"statusUpdate"},{"title":"module:PlaybackDialog","link":"PlaybackDialog"},{"title":"module:PlaybackDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:PlayedCheckmark","link":"PlayedCheckmark"},{"title":"module:PlayedCheckmark.init","link":"init"},{"title":"module:PlaylistData","link":"PlaylistData"},{"title":"module:PlaylistData.setFields","link":"setFields"},{"title":"module:PlaylistData.setPoster","link":"setPoster"},{"title":"module:PlaylistView","link":"PlaylistView"},{"title":"module:PlaylistView.adjustScreenForNoOverview","link":"adjustScreenForNoOverview","description":"

Adjust scene by removing overview node and showing more songs

"},{"title":"module:PlaylistView.createDialogPallete","link":"createDialogPallete"},{"title":"module:PlaylistView.createFullDscrDlg","link":"createFullDscrDlg"},{"title":"module:PlaylistView.init","link":"init"},{"title":"module:PlaylistView.onDoneLoading","link":"onDoneLoading"},{"title":"module:PlaylistView.onKeyEvent","link":"onKeyEvent"},{"title":"module:PlaylistView.pageContentChanged","link":"pageContentChanged","description":"

Set values for displayed values on screen

"},{"title":"module:PlaylistView.setOnScreenTextValues","link":"setOnScreenTextValues","description":"

Populate on screen text variables

"},{"title":"module:PlaylistView.setPosterImage","link":"setPosterImage","description":"

Set poster image on screen

"},{"title":"module:PlaylistView.setScreenTitle","link":"setScreenTitle","description":"

Set screen's title text

"},{"title":"module:PlaylistView.setupMainNode","link":"setupMainNode"},{"title":"module:PlaystateTask","link":"PlaystateTask"},{"title":"module:PlaystateTask.PlaystateDefaults","link":"PlaystateDefaults"},{"title":"module:PlaystateTask.PlaystateUpdate","link":"PlaystateUpdate"},{"title":"module:PlaystateTask.init","link":"init"},{"title":"module:PostTask","link":"PostTask"},{"title":"module:PostTask.asyncPost","link":"asyncPost","description":"

Post data and wait for response code

"},{"title":"module:PostTask.empty","link":"empty","description":"

Revert PostTask to default state

"},{"title":"module:PostTask.init","link":"init"},{"title":"module:PostTask.postItems","link":"postItems","description":"

Main function for PostTask.\nPosts either an array of data\nor a string of data to an API endpoint.\nSaves the response information

"},{"title":"module:ProgramDetails","link":"ProgramDetails"},{"title":"module:ProgramDetails.channelUpdated","link":"channelUpdated"},{"title":"module:ProgramDetails.focusChanged","link":"focusChanged","description":"

Show view channel button when item has Focus

"},{"title":"module:ProgramDetails.getDurationStringFromSeconds","link":"getDurationStringFromSeconds","description":"

Get program duration string (e.g. 1h 20m)

"},{"title":"module:ProgramDetails.getRelativeDayName","link":"getRelativeDayName","description":"

Get relative date name for a date (yesterday, today, tomorrow, or otherwise weekday name )

"},{"title":"module:ProgramDetails.init","link":"init"},{"title":"module:ProgramDetails.onAnimationComplete","link":"onAnimationComplete"},{"title":"module:ProgramDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:ProgramDetails.programUpdated","link":"programUpdated"},{"title":"module:ProgramDetails.setupLabels","link":"setupLabels","description":"

Set up Live and Repeat label sizes

"},{"title":"module:ProgramDetails.updateLabels","link":"updateLabels"},{"title":"module:PublicUserData","link":"PublicUserData"},{"title":"module:PublicUserData.init","link":"init"},{"title":"module:QueueManager","link":"QueueManager"},{"title":"module:QueueManager.clear","link":"clear","description":"

Clear all content from play queue

"},{"title":"module:QueueManager.clearHold","link":"clearHold","description":"

Clear all hold content

"},{"title":"module:QueueManager.deleteAtIndex","link":"deleteAtIndex","description":"

Delete item from play queue at passed index

"},{"title":"module:QueueManager.getCount","link":"getCount","description":"

Return the number of items in the play queue

"},{"title":"module:QueueManager.getCurrentItem","link":"getCurrentItem","description":"

Return the item currently in focus from the play queue

"},{"title":"module:QueueManager.getHold","link":"getHold","description":"

Return the items in the hold

"},{"title":"module:QueueManager.getIsShuffled","link":"getIsShuffled","description":"

Return whether or not shuffle is enabled

"},{"title":"module:QueueManager.getItemByIndex","link":"getItemByIndex","description":"

Return the item in the passed index from the play queue

"},{"title":"module:QueueManager.getItemType","link":"getItemType","description":"

getItemType: Returns the media type of the passed item

"},{"title":"module:QueueManager.getPosition","link":"getPosition","description":"

Returns current playback position within the queue

"},{"title":"module:QueueManager.getQueue","link":"getQueue","description":"

Return the current play queue

"},{"title":"module:QueueManager.getQueueTypes","link":"getQueueTypes","description":"

Return the types of items in current play queue

"},{"title":"module:QueueManager.getQueueUniqueTypes","link":"getQueueUniqueTypes","description":"

Return the unique types of items in current play queue

"},{"title":"module:QueueManager.getUnshuffledQueue","link":"getUnshuffledQueue","description":"

Return original, unshuffled queue

"},{"title":"module:QueueManager.hold","link":"hold","description":"

Hold an item

"},{"title":"module:QueueManager.init","link":"init"},{"title":"module:QueueManager.isPrerollActive","link":"isPrerollActive","description":"

Return isPrerollActive status

"},{"title":"module:QueueManager.moveBack","link":"moveBack","description":"

Move queue position back one

"},{"title":"module:QueueManager.moveForward","link":"moveForward","description":"

Move queue position ahead one

"},{"title":"module:QueueManager.peek","link":"peek","description":"

Return item at end of play queue without removing

"},{"title":"module:QueueManager.playQueue","link":"playQueue","description":"

Play items in queue

"},{"title":"module:QueueManager.pop","link":"pop","description":"

Remove item at end of play queue

"},{"title":"module:QueueManager.push","link":"push","description":"

Push new items to the play queue

"},{"title":"module:QueueManager.resetQueueItemOrder","link":"resetQueueItemOrder","description":"

Reset queue items back to original, unshuffled order

"},{"title":"module:QueueManager.resetShuffle","link":"resetShuffle","description":"

Reset shuffle to off state

"},{"title":"module:QueueManager.set","link":"set","description":"

Replace play queue with passed array

"},{"title":"module:QueueManager.setPosition","link":"setPosition","description":"

Set the queue position

"},{"title":"module:QueueManager.setPrerollStatus","link":"setPrerollStatus","description":"

Set prerollActive status

"},{"title":"module:QueueManager.setTopStartingPoint","link":"setTopStartingPoint","description":"

Set starting point for top item in the queue

"},{"title":"module:QueueManager.shuffleQueueItems","link":"shuffleQueueItems","description":"

Save a copy of the original queue and randomize order of queue items

"},{"title":"module:QueueManager.toggleShuffle","link":"toggleShuffle","description":"

Toggle shuffleEnabled state

"},{"title":"module:QueueManager.top","link":"top","description":"

Return the fitst item in the play queue

"},{"title":"module:QuickConnect","link":"QuickConnect"},{"title":"module:QuickConnect.init","link":"init"},{"title":"module:QuickConnect.monitorQuickConnect","link":"monitorQuickConnect"},{"title":"module:QuickConnectDialog","link":"QuickConnectDialog"},{"title":"module:QuickConnectDialog.OnAuthenticated","link":"OnAuthenticated"},{"title":"module:QuickConnectDialog.init","link":"init"},{"title":"module:QuickConnectDialog.onButtonSelected","link":"onButtonSelected"},{"title":"module:QuickConnectDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:QuickConnectDialog.quickConnectClosed","link":"quickConnectClosed"},{"title":"module:QuickConnectDialog.quickConnectStatus","link":"quickConnectStatus"},{"title":"module:RadioDialog","link":"RadioDialog"},{"title":"module:RadioDialog.init","link":"init"},{"title":"module:RadioDialog.moveScrollBar","link":"moveScrollBar","description":"

Move the popup's scroll bar

"},{"title":"module:RadioDialog.onButtonSelected","link":"onButtonSelected","description":"

Event handler for when user selected a button

"},{"title":"module:RadioDialog.onContentDataChanged","link":"onContentDataChanged"},{"title":"module:RadioDialog.onItemFocused","link":"onItemFocused","description":"

Event handler for when user's cursor highlights an option in the option list

"},{"title":"module:RadioDialog.onItemSelected","link":"onItemSelected","description":"

Once user selected an item, move cursor down to OK button

"},{"title":"module:RadioDialog.onKeyEvent","link":"onKeyEvent"},{"title":"module:RadioDialog.onScrollBarFocus","link":"onScrollBarFocus","description":"

If somehow the scrollbar gains focus, set focus back to the option list

"},{"title":"module:RecordProgramTask","link":"RecordProgramTask"},{"title":"module:RecordProgramTask.RecordOrCancelProgram","link":"RecordOrCancelProgram"},{"title":"module:RecordProgramTask.init","link":"init"},{"title":"module:RecordingData","link":"RecordingData"},{"title":"module:RecordingData.setFields","link":"setFields"},{"title":"module:RecordingData.setPoster","link":"setPoster"},{"title":"module:SceneManager","link":"SceneManager"},{"title":"module:SceneManager.clearPreviousScene","link":"clearPreviousScene","description":"

Clear previous scene from group stack

"},{"title":"module:SceneManager.clearScenes","link":"clearScenes","description":"

Clear all content from group stack

"},{"title":"module:SceneManager.deleteSceneAtIndex","link":"deleteSceneAtIndex","description":"

Delete scene from group stack at passed index

"},{"title":"module:SceneManager.dismissDialog","link":"dismissDialog","description":"

Close currently displayed dialog

"},{"title":"module:SceneManager.getActiveScene","link":"getActiveScene","description":"

Return group at top of stack without removing

"},{"title":"module:SceneManager.init","link":"init"},{"title":"module:SceneManager.isDialogOpen","link":"isDialogOpen","description":"

Returns bool indicating if dialog is currently displayed

"},{"title":"module:SceneManager.optionClosed","link":"optionClosed","description":"

Return button the user selected

"},{"title":"module:SceneManager.optionDialog","link":"optionDialog","description":"

Display dialog to user with an OK button

"},{"title":"module:SceneManager.optionSelected","link":"optionSelected","description":"

Return button the user selected

"},{"title":"module:SceneManager.popScene","link":"popScene","description":"

Remove the current group and load the last group from the stack

"},{"title":"module:SceneManager.pushScene","link":"pushScene","description":"

Push a new group onto the stack, replacing the existing group on the screen

"},{"title":"module:SceneManager.radioDialog","link":"radioDialog","description":"

Display dialog to user with an OK button

"},{"title":"module:SceneManager.registerOverhangData","link":"registerOverhangData","description":"

Register observers for overhang data

"},{"title":"module:SceneManager.resetTime","link":"resetTime","description":"

Reset time

"},{"title":"module:SceneManager.settings","link":"settings","description":"

Display user/device settings screen

"},{"title":"module:SceneManager.standardDialog","link":"standardDialog","description":"

Display dialog to user with an OK button

"},{"title":"module:SceneManager.unregisterOverhangData","link":"unregisterOverhangData","description":"

Remove observers for overhang data

"},{"title":"module:SceneManager.updateOptions","link":"updateOptions","description":"

Update options availability

"},{"title":"module:SceneManager.updateOverhangTitle","link":"updateOverhangTitle","description":"

Update overhang title

"},{"title":"module:SceneManager.updateOverhangVisible","link":"updateOverhangVisible","description":"

Update whether the overhang is visible or not

"},{"title":"module:SceneManager.updateUser","link":"updateUser","description":"

Update username in overhang

"},{"title":"module:SceneManager.userMessage","link":"userMessage","description":"

Display dialog to user with an OK button

"},{"title":"module:ScheduleProgramData","link":"ScheduleProgramData"},{"title":"module:ScheduleProgramData.setFields","link":"setFields"},{"title":"module:ScheduleProgramData.setPoster","link":"setPoster"},{"title":"module:SearchBox","link":"SearchBox"},{"title":"module:SearchBox.init","link":"init"},{"title":"module:SearchBox.searchMedias","link":"searchMedias"},{"title":"module:SearchData","link":"SearchData"},{"title":"module:SearchData.setFields","link":"setFields"},{"title":"module:SearchData.setPoster","link":"setPoster"},{"title":"module:SearchResults","link":"SearchResults"},{"title":"module:SearchResults.init","link":"init"},{"title":"module:SearchResults.loadResults","link":"loadResults"},{"title":"module:SearchResults.onKeyEvent","link":"onKeyEvent"},{"title":"module:SearchResults.searchMedias","link":"searchMedias"},{"title":"module:SearchRow","link":"SearchRow"},{"title":"module:SearchRow.addRow","link":"addRow"},{"title":"module:SearchRow.getData","link":"getData"},{"title":"module:SearchRow.init","link":"init"},{"title":"module:SearchRow.updateSize","link":"updateSize"},{"title":"module:SearchTask","link":"SearchTask"},{"title":"module:SearchTask.init","link":"init"},{"title":"module:SearchTask.search","link":"search"},{"title":"module:SeriesData","link":"SeriesData"},{"title":"module:SeriesData.setFields","link":"setFields"},{"title":"module:SeriesData.setPoster","link":"setPoster"},{"title":"module:ServerDiscoveryTask","link":"ServerDiscoveryTask"},{"title":"module:ServerDiscoveryTask.AddServer","link":"AddServer"},{"title":"module:ServerDiscoveryTask.ProcessClientDiscoveryResponse","link":"ProcessClientDiscoveryResponse"},{"title":"module:ServerDiscoveryTask.ProcessSSDPResponse","link":"ProcessSSDPResponse"},{"title":"module:ServerDiscoveryTask.SendClientDiscoveryBroadcast","link":"SendClientDiscoveryBroadcast"},{"title":"module:ServerDiscoveryTask.SendSSDPBroadcast","link":"SendSSDPBroadcast"},{"title":"module:ServerDiscoveryTask.execute","link":"execute"},{"title":"module:ServerDiscoveryTask.init","link":"init","description":"

Task used to discover jellyfin servers on the local network

"},{"title":"module:SetServerScreen","link":"SetServerScreen"},{"title":"module:SetServerScreen.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook called when the screen is displayed by the screen manager

"},{"title":"module:SetServerScreen.ScanForServers","link":"ScanForServers"},{"title":"module:SetServerScreen.ScanForServersComplete","link":"ScanForServersComplete"},{"title":"module:SetServerScreen.ShowKeyboard","link":"ShowKeyboard"},{"title":"module:SetServerScreen.clearErrorMessage","link":"clearErrorMessage"},{"title":"module:SetServerScreen.init","link":"init"},{"title":"module:SetServerScreen.onDialogButton","link":"onDialogButton"},{"title":"module:SetServerScreen.onKeyEvent","link":"onKeyEvent"},{"title":"module:ShowScenes","link":"ShowScenes"},{"title":"module:ShowScenes.CreateAlbumView","link":"CreateAlbumView","description":"

Shows details on selected album. Description text, image, and list of available songs

"},{"title":"module:ShowScenes.CreateArtistView","link":"CreateArtistView","description":"

Shows details on selected artist. Bio, image, and list of available albums

"},{"title":"module:ShowScenes.CreateHomeGroup","link":"CreateHomeGroup"},{"title":"module:ShowScenes.CreateItemGrid","link":"CreateItemGrid"},{"title":"module:ShowScenes.CreateMovieDetailsGroup","link":"CreateMovieDetailsGroup"},{"title":"module:ShowScenes.CreateMovieLibraryView","link":"CreateMovieLibraryView"},{"title":"module:ShowScenes.CreateMusicLibraryView","link":"CreateMusicLibraryView"},{"title":"module:ShowScenes.CreatePersonView","link":"CreatePersonView"},{"title":"module:ShowScenes.CreatePlaylistView","link":"CreatePlaylistView","description":"

Shows details on selected playlist. Description text, image, and list of available items

"},{"title":"module:ShowScenes.CreateSearchPage","link":"CreateSearchPage"},{"title":"module:ShowScenes.CreateSeasonDetailsGroup","link":"CreateSeasonDetailsGroup"},{"title":"module:ShowScenes.CreateSeasonDetailsGroupByID","link":"CreateSeasonDetailsGroupByID"},{"title":"module:ShowScenes.CreateSeriesDetailsGroup","link":"CreateSeriesDetailsGroup"},{"title":"module:ShowScenes.CreateServerGroup","link":"CreateServerGroup"},{"title":"module:ShowScenes.CreateSigninGroup","link":"CreateSigninGroup"},{"title":"module:ShowScenes.CreateUserSelectGroup","link":"CreateUserSelectGroup"},{"title":"module:ShowScenes.CreateVideoPlayerGroup","link":"CreateVideoPlayerGroup"},{"title":"module:ShowScenes.DeleteFromServerList","link":"DeleteFromServerList"},{"title":"module:ShowScenes.LoginFlow","link":"LoginFlow"},{"title":"module:ShowScenes.SaveServerList","link":"SaveServerList"},{"title":"module:ShowScenes.SendPerformanceBeacon","link":"SendPerformanceBeacon","description":"

Roku Performance monitoring

"},{"title":"module:ShowScenes.playbackOptionDialog","link":"playbackOptionDialog","description":"

Opens dialog asking user if they want to resume video or start playback over only on the home screen

"},{"title":"module:SlideOutButton","link":"SlideOutButton"},{"title":"module:SlideOutButton.init","link":"init"},{"title":"module:SlideOutButton.onBackgroundChanged","link":"onBackgroundChanged"},{"title":"module:SlideOutButton.onFocusChanged","link":"onFocusChanged"},{"title":"module:SlideOutButton.onHeightChanged","link":"onHeightChanged"},{"title":"module:SlideOutButton.onHighlightChanged","link":"onHighlightChanged"},{"title":"module:SlideOutButton.onIconChanged","link":"onIconChanged"},{"title":"module:SlideOutButton.onKeyEvent","link":"onKeyEvent"},{"title":"module:SlideOutButton.onPaddingChanged","link":"onPaddingChanged"},{"title":"module:SlideOutButton.onTextChanged","link":"onTextChanged"},{"title":"module:SlideOutButton.onWidthChanged","link":"onWidthChanged"},{"title":"module:SlideOutButton.setIconSize","link":"setIconSize"},{"title":"module:SongItem","link":"SongItem"},{"title":"module:SongItem.focusChanged","link":"focusChanged"},{"title":"module:SongItem.init","link":"init"},{"title":"module:SongItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:Spinner","link":"Spinner"},{"title":"module:Spinner.init","link":"init"},{"title":"module:StandardDialog","link":"StandardDialog"},{"title":"module:StandardDialog.init","link":"init"},{"title":"module:StandardDialog.onContentDataChanged","link":"onContentDataChanged"},{"title":"module:Subtitles","link":"Subtitles"},{"title":"module:Subtitles.availSubtitleTrackIdx","link":"availSubtitleTrackIdx","description":"

Roku translates the info provided in subtitleTracks into availableSubtitleTracks\nIncluding ignoring tracks, if they are not understood, thus making indexing unpredictable.\nThis function translates between our internel selected subtitle index\nand the corresponding index in availableSubtitleTracks.

"},{"title":"module:Subtitles.changeSubtitleDuringPlayback","link":"changeSubtitleDuringPlayback"},{"title":"module:Subtitles.defaultSubtitleTrack","link":"defaultSubtitleTrack","description":"

Identify the default subtitle track\nif "requires_text" is true, only return a track if it is textual\nThis allows forcing text subs, since roku requires transcoding of non-text subs\nreturns the server-side track index for the appriate subtitle

"},{"title":"module:Subtitles.defaultSubtitleTrackFromVid","link":"defaultSubtitleTrackFromVid","description":"

Identify the default subtitle track for a given video id\nreturns the server-side track index for the appriate subtitle

"},{"title":"module:Subtitles.getSubtitleLanguages","link":"getSubtitleLanguages"},{"title":"module:Subtitles.getSubtitleSelIdxFromSubIdx","link":"getSubtitleSelIdxFromSubIdx","description":"

The subtitle index on the server differs from the index we track locally\nThis function converts the former into the latter

"},{"title":"module:Subtitles.selectSubtitleTrack","link":"selectSubtitleTrack"},{"title":"module:Subtitles.selectSubtitleTrackDialog","link":"selectSubtitleTrackDialog","description":"

Present Dialog to user to select subtitle track

"},{"title":"module:Subtitles.setupSubtitle","link":"setupSubtitle","description":"

Given a set of subtitles, and a subtitle index (the index on the server, not in the list provided)\nthis will set all relevant settings for roku (mainly closed captions) and return the index of the\nsubtitle track specified, but indexed based on the provided list of subtitles

"},{"title":"module:Subtitles.sortSubtitles","link":"sortSubtitles","description":"

Checks available subtitle tracks and puts subtitles in forced, default, and non-default/forced but preferred language at the top

"},{"title":"module:Subtitles.turnoffSubtitles","link":"turnoffSubtitles"},{"title":"module:TVEpisode","link":"TVEpisode"},{"title":"module:TVEpisode.setFields","link":"setFields"},{"title":"module:TVEpisode.setPoster","link":"setPoster"},{"title":"module:TVEpisodeData","link":"TVEpisodeData"},{"title":"module:TVEpisodeData.setFields","link":"setFields"},{"title":"module:TVEpisodeData.setPoster","link":"setPoster"},{"title":"module:TVEpisodeRow","link":"TVEpisodeRow"},{"title":"module:TVEpisodeRow.init","link":"init"},{"title":"module:TVEpisodeRow.onItemSelected","link":"onItemSelected"},{"title":"module:TVEpisodeRow.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVEpisodeRow.setData","link":"setData"},{"title":"module:TVEpisodeRow.setupRows","link":"setupRows"},{"title":"module:TVEpisodeRow.updateSize","link":"updateSize"},{"title":"module:TVEpisodeRowWithOptions","link":"TVEpisodeRowWithOptions"},{"title":"module:TVEpisodeRowWithOptions.SetUpAudioOptions","link":"SetUpAudioOptions","description":"

List of audio tracks to choose from

"},{"title":"module:TVEpisodeRowWithOptions.SetUpVideoOptions","link":"SetUpVideoOptions","description":"

List of video versions to choose from

"},{"title":"module:TVEpisodeRowWithOptions.audioOptionsClosed","link":"audioOptionsClosed"},{"title":"module:TVEpisodeRowWithOptions.init","link":"init"},{"title":"module:TVEpisodeRowWithOptions.onItemSelected","link":"onItemSelected"},{"title":"module:TVEpisodeRowWithOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVEpisodeRowWithOptions.rowsDoneLoading","link":"rowsDoneLoading"},{"title":"module:TVEpisodeRowWithOptions.setupRows","link":"setupRows"},{"title":"module:TVEpisodeRowWithOptions.videoOptionsClosed","link":"videoOptionsClosed"},{"title":"module:TVEpisodes","link":"TVEpisodes"},{"title":"module:TVEpisodes.OnScreenShown","link":"OnScreenShown","description":"

OnScreenShown: Callback function when view is presented on screen

"},{"title":"module:TVEpisodes.getFocusedItem","link":"getFocusedItem","description":"

get the currently focused item

"},{"title":"module:TVEpisodes.init","link":"init"},{"title":"module:TVEpisodes.onItemSelected","link":"onItemSelected"},{"title":"module:TVEpisodes.onKeyEvent","link":"onKeyEvent","description":"

Handle navigation input from the remote and act on it

"},{"title":"module:TVEpisodes.setExtraButtonVisibility","link":"setExtraButtonVisibility","description":"

Updates the visibility of the Extras button based on if this season has any extra features

"},{"title":"module:TVEpisodes.setSeasonLoading","link":"setSeasonLoading"},{"title":"module:TVEpisodes.updateSeason","link":"updateSeason"},{"title":"module:TVListDetails","link":"TVListDetails"},{"title":"module:TVListDetails.DisplayAudioAvailable","link":"DisplayAudioAvailable","description":"

Adds "+N" (e.g. +1) if there is more than one audio track to choose from

"},{"title":"module:TVListDetails.DisplayVideoAvailable","link":"DisplayVideoAvailable","description":"

Adds "+N" (e.g. +1) if there is more than one video version to choose from

"},{"title":"module:TVListDetails.SetupAudioDisplay","link":"SetupAudioDisplay","description":"

Display current audio_codec and check if there is more than one audio track to choose from...

"},{"title":"module:TVListDetails.focusChanged","link":"focusChanged"},{"title":"module:TVListDetails.getEndTime","link":"getEndTime"},{"title":"module:TVListDetails.getRuntime","link":"getRuntime"},{"title":"module:TVListDetails.init","link":"init"},{"title":"module:TVListDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:TVListOptions","link":"TVListOptions"},{"title":"module:TVListOptions.buttonFocusChanged","link":"buttonFocusChanged","description":"

Switch menu shown when button focus changes

"},{"title":"module:TVListOptions.init","link":"init"},{"title":"module:TVListOptions.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVListOptions.optionsSet","link":"optionsSet"},{"title":"module:TVSeasonData","link":"TVSeasonData"},{"title":"module:TVSeasonData.setFields","link":"setFields"},{"title":"module:TVSeasonData.setPoster","link":"setPoster"},{"title":"module:TVSeasonRow","link":"TVSeasonRow"},{"title":"module:TVSeasonRow.getData","link":"getData"},{"title":"module:TVSeasonRow.init","link":"init"},{"title":"module:TVSeasonRow.updateSize","link":"updateSize"},{"title":"module:TVShowDescription","link":"TVShowDescription"},{"title":"module:TVShowDescription.getEndTime","link":"getEndTime"},{"title":"module:TVShowDescription.getHistory","link":"getHistory"},{"title":"module:TVShowDescription.getRuntime","link":"getRuntime"},{"title":"module:TVShowDescription.init","link":"init"},{"title":"module:TVShowDescription.itemContentChanged","link":"itemContentChanged"},{"title":"module:TVShowDescription.round","link":"round"},{"title":"module:TVShowDescription.setFieldText","link":"setFieldText"},{"title":"module:TVShowDetails","link":"TVShowDetails"},{"title":"module:TVShowDetails.getEndTime","link":"getEndTime"},{"title":"module:TVShowDetails.getHistory","link":"getHistory"},{"title":"module:TVShowDetails.getRuntime","link":"getRuntime"},{"title":"module:TVShowDetails.init","link":"init"},{"title":"module:TVShowDetails.itemContentChanged","link":"itemContentChanged"},{"title":"module:TVShowDetails.onKeyEvent","link":"onKeyEvent"},{"title":"module:TVShowDetails.onShuffleEpisodeDataLoaded","link":"onShuffleEpisodeDataLoaded"},{"title":"module:TVShowDetails.round","link":"round"},{"title":"module:TVShowDetails.setFieldText","link":"setFieldText"},{"title":"module:TextSizeTask","link":"TextSizeTask"},{"title":"module:TextSizeTask.getTextSize","link":"getTextSize"},{"title":"module:TextSizeTask.init","link":"init"},{"title":"module:UserData","link":"UserData"},{"title":"module:UserData.getPreference","link":"getPreference"},{"title":"module:UserData.loadFromJSON","link":"loadFromJSON"},{"title":"module:UserData.loadFromRegistry","link":"loadFromRegistry"},{"title":"module:UserData.removeFromRegistry","link":"removeFromRegistry"},{"title":"module:UserData.saveToRegistry","link":"saveToRegistry"},{"title":"module:UserData.setDataFromJSON","link":"setDataFromJSON"},{"title":"module:UserData.setPreference","link":"setPreference"},{"title":"module:UserData.setServer","link":"setServer"},{"title":"module:UserItem","link":"UserItem"},{"title":"module:UserItem.init","link":"init"},{"title":"module:UserItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:UserLibrary","link":"UserLibrary"},{"title":"module:UserLibrary.MarkItemFavorite","link":"MarkItemFavorite"},{"title":"module:UserLibrary.MarkItemWatched","link":"MarkItemWatched"},{"title":"module:UserLibrary.UnmarkItemFavorite","link":"UnmarkItemFavorite"},{"title":"module:UserLibrary.UnmarkItemWatched","link":"UnmarkItemWatched"},{"title":"module:UserRow","link":"UserRow"},{"title":"module:UserRow.init","link":"init"},{"title":"module:UserRow.onKeyEvent","link":"onKeyEvent"},{"title":"module:UserRow.setData","link":"setData"},{"title":"module:UserRow.setUser","link":"setUser"},{"title":"module:UserRow.updateSize","link":"updateSize"},{"title":"module:UserSelect","link":"UserSelect"},{"title":"module:UserSelect.OnScreenShown","link":"OnScreenShown","description":"

JFScreen hook called when the screen is displayed by the screen manager

"},{"title":"module:UserSelect.init","link":"init"},{"title":"module:UserSelect.itemContentChanged","link":"itemContentChanged"},{"title":"module:UserSelect.onKeyEvent","link":"onKeyEvent"},{"title":"module:UserSelect.redraw","link":"redraw"},{"title":"module:VideoData","link":"VideoData"},{"title":"module:VideoData.setFields","link":"setFields"},{"title":"module:VideoData.setPoster","link":"setPoster"},{"title":"module:VideoPlayer","link":"VideoPlayer"},{"title":"module:VideoPlayer.AddVideoContent","link":"AddVideoContent"},{"title":"module:VideoPlayer.GetPlaybackInfo","link":"GetPlaybackInfo","description":"

Returns an array of playback info to be displayed during playback.\nIn the future, with a custom playback info view, we can return an associated array.

"},{"title":"module:VideoPlayer.GetTranscodingStats","link":"GetTranscodingStats"},{"title":"module:VideoPlayer.PlayIntroVideo","link":"PlayIntroVideo"},{"title":"module:VideoPlayer.VideoPlayer","link":"VideoPlayer"},{"title":"module:VideoPlayer.autoPlayNextEpisode","link":"autoPlayNextEpisode"},{"title":"module:VideoPlayer.directPlaySupported","link":"directPlaySupported"},{"title":"module:VideoPlayer.getAudioFormat","link":"getAudioFormat"},{"title":"module:VideoPlayer.getAudioInfo","link":"getAudioInfo"},{"title":"module:VideoPlayer.getContainerType","link":"getContainerType"},{"title":"module:VideoPlayer.getDisplayBitrate","link":"getDisplayBitrate"},{"title":"module:VideoPlayer.getTranscodeReasons","link":"getTranscodeReasons","description":"

Extract array of Transcode Reasons from the content URL

"},{"title":"module:VideoPlayer.havePlaybackInfo","link":"havePlaybackInfo"},{"title":"module:VideoPlayer.startPlayBackOver","link":"startPlayBackOver","description":"

Opens dialog asking user if they want to resume video or start playback over only on the home screen

"},{"title":"module:VideoPlayerView","link":"VideoPlayerView"},{"title":"module:VideoPlayerView.ReportPlayback","link":"ReportPlayback","description":"

Report playback to server

"},{"title":"module:VideoPlayerView.availSubtitleTrackIdx","link":"availSubtitleTrackIdx","description":"

availSubtitleTrackIdx: Returns Roku's index for requested subtitle track

"},{"title":"module:VideoPlayerView.bufferCheck","link":"bufferCheck","description":"

Check the the buffering has not hung

"},{"title":"module:VideoPlayerView.checkTimeToDisplayNextEpisode","link":"checkTimeToDisplayNextEpisode","description":"

Checks if we need to display the Next Episode button

"},{"title":"module:VideoPlayerView.getCurrentChapterIndex","link":"getCurrentChapterIndex","description":"

getCurrentChapterIndex: Finds current chapter index

"},{"title":"module:VideoPlayerView.handleChapterListAction","link":"handleChapterListAction","description":"

handleChapterListAction: Handles action to show chapter list

"},{"title":"module:VideoPlayerView.handleChapterSkipAction","link":"handleChapterSkipAction","description":"

handleChapterSkipAction: Handles user command to skip chapters in playing video

"},{"title":"module:VideoPlayerView.handleHideAction","link":"handleHideAction","description":"

handleHideAction: Handles action to hide OSD menu

"},{"title":"module:VideoPlayerView.handleItemSkipAction","link":"handleItemSkipAction","description":"

handleItemSkipAction: Handles user command to skip items

"},{"title":"module:VideoPlayerView.handleShowAudioMenuAction","link":"handleShowAudioMenuAction","description":"

handleShowAudioMenuAction: Handles action to show audio selection menu

"},{"title":"module:VideoPlayerView.handleShowSubtitleMenuAction","link":"handleShowSubtitleMenuAction","description":"

handleShowSubtitleMenuAction: Handles action to show subtitle selection menu

"},{"title":"module:VideoPlayerView.handleShowVideoInfoPopupAction","link":"handleShowVideoInfoPopupAction","description":"

handleShowVideoInfoPopupAction: Handles action to show video info popup

"},{"title":"module:VideoPlayerView.handleVideoPlayPauseAction","link":"handleVideoPlayPauseAction","description":"

handleVideoPlayPauseAction: Handles action to either play or pause the video content

"},{"title":"module:VideoPlayerView.hideNextEpisodeButton","link":"hideNextEpisodeButton","description":"

Runs hide Next Episode button animation and sets focus back to video

"},{"title":"module:VideoPlayerView.init","link":"init"},{"title":"module:VideoPlayerView.loadCaption","link":"loadCaption","description":"

Set caption url to server subtitle track

"},{"title":"module:VideoPlayerView.onAllowCaptionsChange","link":"onAllowCaptionsChange","description":"

Only setup caption items if captions are allowed

"},{"title":"module:VideoPlayerView.onAudioIndexChange","link":"onAudioIndexChange","description":"

Event handler for when audioIndex changes

"},{"title":"module:VideoPlayerView.onContentChange","link":"onContentChange","description":"

Event handler for when video content field changes

"},{"title":"module:VideoPlayerView.onKeyEvent","link":"onKeyEvent"},{"title":"module:VideoPlayerView.onNextEpisodeDataLoaded","link":"onNextEpisodeDataLoaded"},{"title":"module:VideoPlayerView.onOSDAction","link":"onOSDAction","description":"

onOSDAction: Process action events from OSD to their respective handlers

"},{"title":"module:VideoPlayerView.onPlaybackErrorButtonSelected","link":"onPlaybackErrorButtonSelected"},{"title":"module:VideoPlayerView.onPlaybackErrorDialogClosed","link":"onPlaybackErrorDialogClosed"},{"title":"module:VideoPlayerView.onPositionChanged","link":"onPositionChanged","description":"

When Video Player state changes

"},{"title":"module:VideoPlayerView.onState","link":"onState","description":"

When Video Player state changes

"},{"title":"module:VideoPlayerView.onSubtitleChange","link":"onSubtitleChange","description":"

Event handler for when selectedSubtitle changes

"},{"title":"module:VideoPlayerView.onVideoContentLoaded","link":"onVideoContentLoaded"},{"title":"module:VideoPlayerView.populateChapterMenu","link":"populateChapterMenu","description":"

populateChapterMenu: ' Parse chapter data from API and appeand to chapter list menu

"},{"title":"module:VideoPlayerView.showNextEpisodeButton","link":"showNextEpisodeButton","description":"

Runs Next Episode button animation and sets focus to button

"},{"title":"module:VideoPlayerView.showPlaybackErrorDialog","link":"showPlaybackErrorDialog"},{"title":"module:VideoPlayerView.stateAllowsOSD","link":"stateAllowsOSD","description":"

stateAllowsOSD: Check if current video state allows showing the OSD

"},{"title":"module:VideoPlayerView.toggleCaption","link":"toggleCaption","description":"

Toggles visibility of custom subtitles and sets captionTask's player state

"},{"title":"module:VideoPlayerView.updateCaption","link":"updateCaption","description":"

Removes old subtitle lines and adds new subtitle lines

"},{"title":"module:VideoPlayerView.updateCount","link":"updateCount","description":"

Update count down text

"},{"title":"module:VideoTrackListItem","link":"VideoTrackListItem"},{"title":"module:VideoTrackListItem.focusChanged","link":"focusChanged","description":"

Scroll description if focused

"},{"title":"module:VideoTrackListItem.init","link":"init"},{"title":"module:VideoTrackListItem.itemContentChanged","link":"itemContentChanged"},{"title":"module:ViewCreator","link":"ViewCreator"},{"title":"module:ViewCreator.CreateAudioPlayerView","link":"CreateAudioPlayerView"},{"title":"module:ViewCreator.CreateVideoPlayerView","link":"CreateVideoPlayerView","description":"

Play Video

"},{"title":"module:ViewCreator.availSubtitleTrackIdx","link":"availSubtitleTrackIdx","description":"

Roku translates the info provided in subtitleTracks into availableSubtitleTracks\nIncluding ignoring tracks, if they are not understood, thus making indexing unpredictable.\nThis function translates between our internel selected subtitle index\nand the corresponding index in availableSubtitleTracks.

"},{"title":"module:ViewCreator.onPlaybackInfoLoaded","link":"onPlaybackInfoLoaded","description":"

The playback info task has returned data

"},{"title":"module:ViewCreator.onSelectAudioPressed","link":"onSelectAudioPressed","description":"

onSelectAudioPressed: Display audio selection dialog

"},{"title":"module:ViewCreator.onSelectPlaybackInfoPressed","link":"onSelectPlaybackInfoPressed","description":"

User requested playback info

"},{"title":"module:ViewCreator.onSelectSubtitlePressed","link":"onSelectSubtitlePressed","description":"

User requested subtitle selection popup

"},{"title":"module:ViewCreator.onSelectionMade","link":"onSelectionMade","description":"

User has selected something from the radioDialog popup

"},{"title":"module:ViewCreator.onStateChange","link":"onStateChange","description":"

Playback state change event handlers

"},{"title":"module:ViewCreator.processAudioSelection","link":"processAudioSelection","description":"

processAudioSelection: Audio track selection handler

"},{"title":"module:ViewCreator.processSubtitleSelection","link":"processSubtitleSelection"},{"title":"module:WhatsNewDialog","link":"WhatsNewDialog"},{"title":"module:WhatsNewDialog.init","link":"init"},{"title":"module:WhatsNewDialog.setPalette","link":"setPalette"},{"title":"module:baserequest","link":"baserequest"},{"title":"module:baserequest.APIRequest","link":"APIRequest"},{"title":"module:baserequest.authRequest","link":"authRequest","description":"

Takes and returns a roUrlTransfer object after adding a Jellyfin "Authorization" header

"},{"title":"module:baserequest.buildAuthHeader","link":"buildAuthHeader","description":"

Returns a string containing the "Authorization" header payload

"},{"title":"module:baserequest.buildParams","link":"buildParams"},{"title":"module:baserequest.buildURL","link":"buildURL"},{"title":"module:baserequest.deleteVoid","link":"deleteVoid"},{"title":"module:baserequest.getJson","link":"getJson"},{"title":"module:baserequest.getString","link":"getString"},{"title":"module:baserequest.getVoid","link":"getVoid"},{"title":"module:baserequest.get_url","link":"get_url"},{"title":"module:baserequest.headVoid","link":"headVoid"},{"title":"module:baserequest.postJson","link":"postJson"},{"title":"module:baserequest.postString","link":"postString"},{"title":"module:baserequest.postVoid","link":"postVoid"},{"title":"module:baserequest.setCertificateAuthority","link":"setCertificateAuthority","description":"

sets the certificate authority by file path on the passed node

"},{"title":"module:captionTask","link":"captionTask"},{"title":"module:captionTask.fetchCaption","link":"fetchCaption"},{"title":"module:captionTask.init","link":"init"},{"title":"module:captionTask.isTime","link":"isTime"},{"title":"module:captionTask.newLayoutGroup","link":"newLayoutGroup"},{"title":"module:captionTask.newRect","link":"newRect"},{"title":"module:captionTask.newlabel","link":"newlabel"},{"title":"module:captionTask.parseVTT","link":"parseVTT"},{"title":"module:captionTask.setFont","link":"setFont"},{"title":"module:captionTask.toMs","link":"toMs"},{"title":"module:captionTask.updateCaption","link":"updateCaption"},{"title":"module:conditional","link":"conditional"},{"title":"module:conditional.printRegistry","link":"printRegistry","description":"

Print out all of the registry contents to the debug log

"},{"title":"module:config","link":"config"},{"title":"module:config.GetConfigTree","link":"GetConfigTree","description":"

Read config tree from json config file and return

"},{"title":"module:config.RegistryReadAll","link":"RegistryReadAll","description":"

Return all data found inside a registry section

"},{"title":"module:config.findConfigTreeKey","link":"findConfigTreeKey","description":"

Recursivly search the config tree for entry with settingname equal to key

"},{"title":"module:config.getRegistrySections","link":"getRegistrySections","description":"

Return an array of all the registry section keys

"},{"title":"module:config.getSavedUsers","link":"getSavedUsers","description":"

Returns an array of saved users from the registry\nthat belong to the active server

"},{"title":"module:config.get_setting","link":"get_setting","description":"

"Jellyfin" registry accessors for the default global settings

"},{"title":"module:config.get_user_setting","link":"get_user_setting","description":"

User registry accessors for the currently active user

"},{"title":"module:config.registry_delete","link":"registry_delete"},{"title":"module:config.registry_read","link":"registry_read","description":"

Generic registry accessors

"},{"title":"module:config.registry_write","link":"registry_write"},{"title":"module:config.set_setting","link":"set_setting"},{"title":"module:config.set_user_setting","link":"set_user_setting"},{"title":"module:config.unset_setting","link":"unset_setting"},{"title":"module:config.unset_user_setting","link":"unset_user_setting"},{"title":"module:deviceCapabilities","link":"deviceCapabilities"},{"title":"module:deviceCapabilities.GetBitRateLimit","link":"GetBitRateLimit"},{"title":"module:deviceCapabilities.GetDirectPlayProfiles","link":"GetDirectPlayProfiles"},{"title":"module:deviceCapabilities.canPlay4k","link":"canPlay4k","description":"

does the connected display support playing 4k video?

"},{"title":"module:deviceCapabilities.getCodecProfiles","link":"getCodecProfiles"},{"title":"module:deviceCapabilities.getContainerProfiles","link":"getContainerProfiles"},{"title":"module:deviceCapabilities.getDeviceCapabilities","link":"getDeviceCapabilities","description":"

Returns the Device Capabilities for Roku.\nAlso prints out the device profile for debugging

"},{"title":"module:deviceCapabilities.getDeviceProfile","link":"getDeviceProfile"},{"title":"module:deviceCapabilities.getMaxHeightArray","link":"getMaxHeightArray"},{"title":"module:deviceCapabilities.getMaxWidthArray","link":"getMaxWidthArray"},{"title":"module:deviceCapabilities.getSubtitleProfiles","link":"getSubtitleProfiles"},{"title":"module:deviceCapabilities.getTranscodingProfiles","link":"getTranscodingProfiles"},{"title":"module:deviceCapabilities.printDeviceProfile","link":"printDeviceProfile","description":"

Print out the deviceProfile for debugging

"},{"title":"module:deviceCapabilities.removeDecimals","link":"removeDecimals","description":"

Remove all decimals from a string

"},{"title":"module:deviceCapabilities.setPreferredCodec","link":"setPreferredCodec","description":"

Takes and returns a comma delimited string of codecs.\nMoves the preferred codec to the front of the string

"},{"title":"module:deviceCapabilities.updateProfileArray","link":"updateProfileArray","description":"

Recieves and returns an assArray of supported profiles and levels for each video codec

"},{"title":"module:globals","link":"globals"},{"title":"module:globals.SaveAppToGlobal","link":"SaveAppToGlobal","description":"

Save information from roAppInfo to m.global.app

"},{"title":"module:globals.SaveDeviceToGlobal","link":"SaveDeviceToGlobal","description":"

Save information from roDeviceInfo to m.global.device

"},{"title":"module:globals.setConstants","link":"setConstants"},{"title":"module:migrations","link":"migrations"},{"title":"module:migrations.CLIENT_VERSION_REQUIRING_BASE_MIGRATION","link":"CLIENT_VERSION_REQUIRING_BASE_MIGRATION"},{"title":"module:migrations.runGlobalMigrations","link":"runGlobalMigrations","description":"

Run all necessary registry mirations on the "global" Jellyfin registry section

"},{"title":"module:migrations.runRegistryUserMigrations","link":"runRegistryUserMigrations"},{"title":"module:misc","link":"misc"},{"title":"module:misc.AssocArrayEqual","link":"AssocArrayEqual"},{"title":"module:misc.arrayHasValue","link":"arrayHasValue","description":"

Check if a specific value is inside of an array

"},{"title":"module:misc.createLogoPoster","link":"createLogoPoster","description":"

Create and return a Jellyfin logo poster node

"},{"title":"module:misc.createOverhangUser","link":"createOverhangUser"},{"title":"module:misc.createSeperator","link":"createSeperator","description":"

Create and return a rectangle node used as a seperator in the overhang

"},{"title":"module:misc.div_ceiling","link":"div_ceiling"},{"title":"module:misc.findNodeBySubtype","link":"findNodeBySubtype"},{"title":"module:misc.formatTime","link":"formatTime","description":"

Format time as 12 or 24 hour format based on system clock setting

"},{"title":"module:misc.getButton","link":"getButton"},{"title":"module:misc.getMinutes","link":"getMinutes","description":"

Converts ticks to minutes

"},{"title":"module:misc.getMsgPicker","link":"getMsgPicker"},{"title":"module:misc.get_dialog_result","link":"get_dialog_result","description":"

Returns the item selected or -1 on backpress or other unhandled closure of dialog.

"},{"title":"module:misc.inArray","link":"inArray","description":"

Search string array for search value. Return if it's found

"},{"title":"module:misc.inferServerUrl","link":"inferServerUrl","description":"

take an incomplete url string and use it to make educated guesses about\nthe complete url. then tests these guesses to see if it can find a jf server\nreturns the url of the server it found, or an empty string

"},{"title":"module:misc.isAllValid","link":"isAllValid","description":"

Returns whether or not all items in passed array are valid

"},{"title":"module:misc.isChainValid","link":"isChainValid","description":"

isChainValid: Returns whether or not all the properties in the passed property chain are valid.\nStops evaluating at first found false value

"},{"title":"module:misc.isJellyfinServer","link":"isJellyfinServer","description":"

accepts the raw json string of /system/info/public and returns\na boolean indicating if ProductName is "Jellyfin Server"

"},{"title":"module:misc.isLocalhost","link":"isLocalhost","description":"

Returns true if the string is a loopback, such as 'localhost' or '127.0.0.1'

"},{"title":"module:misc.isNodeEvent","link":"isNodeEvent"},{"title":"module:misc.isValid","link":"isValid","description":"

Returns whether or not passed value is valid

"},{"title":"module:misc.isValidAndNotEmpty","link":"isValidAndNotEmpty","description":"

Returns whether or not passed value is valid and not empty\nAccepts a string, or any countable type (arrays and lists)

"},{"title":"module:misc.lastFocusedChild","link":"lastFocusedChild"},{"title":"module:misc.leftPad","link":"leftPad"},{"title":"module:misc.message_dialog","link":"message_dialog"},{"title":"module:misc.option_dialog","link":"option_dialog"},{"title":"module:misc.parseUrl","link":"parseUrl","description":"

Returns an array from a url = [ url, proto, host, port, subdir+params ]\nIf port or subdir are not found, an empty string will be added to the array\nProto must be declared or array will be empty

"},{"title":"module:misc.roundNumber","link":"roundNumber","description":"

Rounds number to nearest integer

"},{"title":"module:misc.secondsToEndTime","link":"secondsToEndTime"},{"title":"module:misc.secondsToHuman","link":"secondsToHuman"},{"title":"module:misc.setFieldTextValue","link":"setFieldTextValue"},{"title":"module:misc.show_dialog","link":"show_dialog"},{"title":"module:misc.shuffleArray","link":"shuffleArray","description":"

Takes an array of data, shuffles the order, then returns the array\nuses the Fisher-Yates shuffling algorithm

"},{"title":"module:misc.startLoadingSpinner","link":"startLoadingSpinner","description":"

startLoadingSpinner: Start a loading spinner and attach it to the main JFScene.\nDisplays an invisible ProgressDialog node by default to disable keypresses while loading.

"},{"title":"module:misc.stopLoadingSpinner","link":"stopLoadingSpinner"},{"title":"module:misc.ticksToHuman","link":"ticksToHuman"},{"title":"module:misc.toBoolean","link":"toBoolean","description":"

convert value to boolean and return value

"},{"title":"module:misc.toString","link":"toString"},{"title":"module:misc.urlCandidates","link":"urlCandidates","description":"

this is the "educated guess" logic for inferServerUrl that generates a list of complete url's as candidates\nfor the tests in inferServerUrl. takes an incomplete url as an arg and returns a list of extrapolated\nfull urls.

"},{"title":"module:misc.versionChecker","link":"versionChecker","description":"

Returns whether or not a version number (e.g. 10.7.7) is greater or equal\nto some minimum version allowed (e.g. 10.8.0)

"},{"title":"module:quickplay","link":"quickplay"},{"title":"module:schedule","link":"schedule"},{"title":"module:schedule.channelFilterSet","link":"channelFilterSet"},{"title":"module:schedule.channelsearchTermSet","link":"channelsearchTermSet","description":"

Voice Search set

"},{"title":"module:schedule.focusProgramDetails","link":"focusProgramDetails","description":"

Move the TV Guide Grid down or up depending whether details are selected

"},{"title":"module:schedule.init","link":"init"},{"title":"module:schedule.onChannelsLoaded","link":"onChannelsLoaded","description":"

Initial list of channels loaded

"},{"title":"module:schedule.onGridScrolled","link":"onGridScrolled","description":"

As user scrolls grid, check if more data requries to be loaded

"},{"title":"module:schedule.onKeyEvent","link":"onKeyEvent"},{"title":"module:schedule.onProgramDetailsLoaded","link":"onProgramDetailsLoaded","description":"

Update the Program Details with full information

"},{"title":"module:schedule.onProgramFocused","link":"onProgramFocused"},{"title":"module:schedule.onProgramSelected","link":"onProgramSelected"},{"title":"module:schedule.onRecordChannelSelected","link":"onRecordChannelSelected","description":"

Handle user selecting "Record Channel" from Program Details

"},{"title":"module:schedule.onRecordOperationDone","link":"onRecordOperationDone"},{"title":"module:schedule.onRecordSeriesChannelSelected","link":"onRecordSeriesChannelSelected","description":"

Handle user selecting "Record Series" from Program Details

"},{"title":"module:schedule.onScheduleLoaded","link":"onScheduleLoaded","description":"

When LoadScheduleTask completes (initial or more data) and we have a schedule to display

"},{"title":"module:schedule.onWatchChannelSelected","link":"onWatchChannelSelected","description":"

Handle user selecting "Watch Channel" from Program Details

"},{"title":"module:section","link":"section"},{"title":"module:section.init","link":"init"},{"title":"module:section.onFocusChange","link":"onFocusChange"},{"title":"module:section.onIDChange","link":"onIDChange"},{"title":"module:section.onTranslationChange","link":"onTranslationChange"},{"title":"module:section.scrollDownToOnDeck","link":"scrollDownToOnDeck"},{"title":"module:section.scrollOffBottom","link":"scrollOffBottom"},{"title":"module:section.scrollOffOnDeck","link":"scrollOffOnDeck"},{"title":"module:section.scrollOffTop","link":"scrollOffTop"},{"title":"module:section.scrollUpToOnDeck","link":"scrollUpToOnDeck"},{"title":"module:section.showFromBottom","link":"showFromBottom"},{"title":"module:section.showFromTop","link":"showFromTop"},{"title":"module:sectionScroller","link":"sectionScroller"},{"title":"module:sectionScroller.displayedIndexChanged","link":"displayedIndexChanged"},{"title":"module:sectionScroller.init","link":"init"},{"title":"module:sectionScroller.onFocusChange","link":"onFocusChange"},{"title":"module:settings","link":"settings"},{"title":"module:settings.LoadMenu","link":"LoadMenu"},{"title":"module:settings.OnScreenHidden","link":"OnScreenHidden","description":"

JFScreen hook that gets ran as needed.\nAssumes settings were changed and they affect the device profile.\nPosts a new device profile to the server using the task thread

"},{"title":"module:settings.boolSettingChanged","link":"boolSettingChanged"},{"title":"module:settings.init","link":"init"},{"title":"module:settings.isFormInFocus","link":"isFormInFocus","description":"

Returns true if any of the data entry forms are in focus

"},{"title":"module:settings.onKeyEvent","link":"onKeyEvent"},{"title":"module:settings.onKeyGridEscape","link":"onKeyGridEscape"},{"title":"module:settings.onKeyGridSubmit","link":"onKeyGridSubmit"},{"title":"module:settings.postFinished","link":"postFinished","description":"

Triggered by m.postTask after completing a post.\nEmpty the task data when finished.

"},{"title":"module:settings.radioSettingChanged","link":"radioSettingChanged"},{"title":"module:settings.settingFocused","link":"settingFocused"},{"title":"module:settings.settingSelected","link":"settingSelected"},{"title":"module:userauth","link":"userauth"},{"title":"module:userauth.AboutMe","link":"AboutMe"},{"title":"module:userauth.AuthenticateViaQuickConnect","link":"AuthenticateViaQuickConnect"},{"title":"module:userauth.AvailableUsers","link":"AvailableUsers"},{"title":"module:userauth.GetPublicUsers","link":"GetPublicUsers"},{"title":"module:userauth.LoadUserAbilities","link":"LoadUserAbilities"},{"title":"module:userauth.ServerInfo","link":"ServerInfo"},{"title":"module:userauth.SignOut","link":"SignOut"},{"title":"module:userauth.checkQuickConnect","link":"checkQuickConnect"},{"title":"module:userauth.get_token","link":"get_token"},{"title":"module:userauth.initQuickConnect","link":"initQuickConnect"},{"title":"quickplay","link":"quickplay"},{"title":"quickplay.album","link":"album","description":"

A music album.\nPlay the entire album starting with track 1.

"},{"title":"quickplay.artist","link":"artist","description":"

A music artist.\nShuffle play all songs by artist.

"},{"title":"quickplay.audio","link":"audio","description":"

A single audio file.

"},{"title":"quickplay.boxset","link":"boxset","description":"

A boxset.\nPlay all items inside.

"},{"title":"quickplay.collectionFolder","link":"collectionFolder","description":"

Quick Play A CollectionFolder.\nShuffle play the items inside\nwith some differences based on collectionType.

"},{"title":"quickplay.folder","link":"folder","description":"

Quick Play A folder.\nShuffle play all items found

"},{"title":"quickplay.multipleSeries","link":"multipleSeries","description":"

More than one TV Show Series.\nShuffle play all watched episodes

"},{"title":"quickplay.musicVideo","link":"musicVideo","description":"

A single music video file.

"},{"title":"quickplay.person","link":"person","description":"

Quick Play A Person.\nShuffle play all videos found

"},{"title":"quickplay.photo","link":"photo","description":"

A single photo.

"},{"title":"quickplay.photoAlbum","link":"photoAlbum","description":"

A photo album.

"},{"title":"quickplay.playlist","link":"playlist","description":"

Quick Play A Playlist.\nPlay the first unwatched episode.\nIf none, play the whole season starting with episode 1.

"},{"title":"quickplay.program","link":"program","description":"

Quick Play A Live Program

"},{"title":"quickplay.pushToQueue","link":"pushToQueue","description":"

Takes an array of items and adds to global queue.\nAlso shuffles the playlist if asked

"},{"title":"quickplay.season","link":"season","description":"

A TV Show Season.\nPlay the first unwatched episode.\nIf none, play the whole season starting with episode 1.

"},{"title":"quickplay.series","link":"series","description":"

A TV Show Series.\nPlay the first unwatched episode.\nIf none, shuffle play the whole series.

"},{"title":"quickplay.tvChannel","link":"tvChannel","description":"

Quick Play A TVChannel

"},{"title":"quickplay.userView","link":"userView","description":"

Quick Play A UserView.\nPlay logic depends on "collectionType".

"},{"title":"quickplay.video","link":"video","description":"

A single video file.

"},{"title":"quickplay.videoContainer","link":"videoContainer","description":"

A container with some kind of videos inside of it

"}]} \ No newline at end of file diff --git a/docs/api/module-Items.html b/docs/api/module-Items.html index ab686b7fa..bb57e0068 100644 --- a/docs/api/module-Items.html +++ b/docs/api/module-Items.html @@ -1,3 +1,3 @@ Module: Items
On this page

Methods

(static) AppearsOnList(id) → {dynamic}

Get list of albums an artist appears on

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) ArtistOverview(name) → {dynamic}

Music Artist Data

Parameters:
NameTypeDescription
namestring
Returns:
Type: 
dynamic

(static) AudioItem(id) → {dynamic}

Get Songs that are on an Album

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) AudioStream(id) → {dynamic}

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) BackdropImage(id) → {dynamic}

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) CreateArtistMix(id) → {dynamic}

Get Instant Mix based on item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) CreateInstantMix(id) → {dynamic}

Get Instant Mix based on item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) GetIntroVideos(id) → {dynamic}

Get Intro Videos for an item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) GetSongsByArtist(id, paramsopt) → {dynamic}

Get list of songs belonging to an artist

Parameters:
NameTypeAttributesDefaultDescription
idstring
paramsobject<optional>
{}
Returns:
Type: 
dynamic

(static) ItemGetPlaybackInfo(id, startTimeTicksopt) → {dynamic}

Parameters:
NameTypeAttributesDefaultDescription
idstring
startTimeTickslonginteger<optional>
0
Returns:
Type: 
dynamic

(static) ItemMetaData(id) → {dynamic}

MetaData about an item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) ItemPostPlaybackInfo(id, mediaSourceIdopt, audioTrackIndexopt, subtitleTrackIndexopt, startTimeTicksopt) → {dynamic}

Parameters:
NameTypeAttributesDefaultDescription
idstring
mediaSourceIdstring<optional>
""
audioTrackIndexinteger<optional>
-1
subtitleTrackIndexinteger<optional>
-1
startTimeTickslonginteger<optional>
0
Returns:
Type: 
dynamic

(static) MusicAlbumList(id) → {dynamic}

Get list of albums belonging to an artist

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) MusicSongList(id) → {dynamic}

Get Songs that are on an Album

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) PlaylistItemList(id) → {dynamic}

Get Items that are under the provided item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) TVEpisodeShuffleList(show_id) → {dynamic}

Parameters:
NameTypeDescription
show_idstring
Returns:
Type: 
dynamic

(static) TVEpisodes(showId, seasonId) → {dynamic}

Returns a list of TV Shows for a given TV Show and season Accepts strings for the TV Show Id and the season Id

Parameters:
NameTypeDescription
showIdstring
seasonIdstring
Returns:
Type: 
dynamic

(static) TVSeasonExtras(seasonId) → {dynamic}

Returns a list of extra features for a TV Show season Accepts a string that is a TV Show season id

Parameters:
NameTypeDescription
seasonIdstring
Returns:
Type: 
dynamic

(static) TVSeasons(id) → {dynamic}

Seasons for a TV Show

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) searchMedia(query) → {dynamic}

Search across all libraries

Parameters:
NameTypeDescription
querystring
Returns:
Type: 
dynamic

(static) useTranscodeAudioStream(playbackInfo) → {dynamic}

Parameters:
NameTypeDescription
playbackInfodynamic
Returns:
Type: 
dynamic
jellyfin-roku Code Documentation
\ No newline at end of file +
On this page

Methods

(static) AppearsOnList(id) → {dynamic}

Get list of albums an artist appears on

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) ArtistOverview(name) → {dynamic}

Music Artist Data

Parameters:
NameTypeDescription
namestring
Returns:
Type: 
dynamic

(static) AudioItem(id) → {dynamic}

Get Songs that are on an Album

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) AudioStream(id) → {dynamic}

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) BackdropImage(id) → {dynamic}

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) CreateArtistMix(id) → {dynamic}

Get Instant Mix based on item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) CreateInstantMix(id) → {dynamic}

Get Instant Mix based on item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) GetIntroVideos(id) → {dynamic}

Get Intro Videos for an item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) GetSongsByArtist(id, paramsopt) → {dynamic}

Get list of songs belonging to an artist

Parameters:
NameTypeAttributesDefaultDescription
idstring
paramsobject<optional>
{}
Returns:
Type: 
dynamic

(static) ItemGetPlaybackInfo(id, startTimeTicksopt) → {dynamic}

Parameters:
NameTypeAttributesDefaultDescription
idstring
startTimeTickslonginteger<optional>
0
Returns:
Type: 
dynamic

(static) ItemMetaData(id) → {dynamic}

MetaData about an item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) ItemPostPlaybackInfo(id, mediaSourceIdopt, audioTrackIndexopt, subtitleTrackIndexopt, startTimeTicksopt, forceMp3opt) → {dynamic}

Parameters:
NameTypeAttributesDefaultDescription
idstring
mediaSourceIdstring<optional>
""
audioTrackIndexinteger<optional>
-1
subtitleTrackIndexinteger<optional>
-1
startTimeTickslonginteger<optional>
0
forceMp3boolean<optional>
false
Returns:
Type: 
dynamic

(static) MusicAlbumList(id) → {dynamic}

Get list of albums belonging to an artist

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) MusicSongList(id) → {dynamic}

Get Songs that are on an Album

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) PlaylistItemList(id) → {dynamic}

Get Items that are under the provided item

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) TVEpisodeShuffleList(show_id) → {dynamic}

Parameters:
NameTypeDescription
show_idstring
Returns:
Type: 
dynamic

(static) TVEpisodes(showId, seasonId) → {dynamic}

Returns a list of TV Shows for a given TV Show and season Accepts strings for the TV Show Id and the season Id

Parameters:
NameTypeDescription
showIdstring
seasonIdstring
Returns:
Type: 
dynamic

(static) TVSeasonExtras(seasonId) → {dynamic}

Returns a list of extra features for a TV Show season Accepts a string that is a TV Show season id

Parameters:
NameTypeDescription
seasonIdstring
Returns:
Type: 
dynamic

(static) TVSeasons(id) → {dynamic}

Seasons for a TV Show

Parameters:
NameTypeDescription
idstring
Returns:
Type: 
dynamic

(static) forceMp3Audio(deviceProfile) → {void}

updates the device profile we send the server to force mp3 audio transcoding instead of the default aac

Parameters:
NameTypeDescription
deviceProfileobject
Returns:
Type: 
void

(static) searchMedia(query) → {dynamic}

Search across all libraries

Parameters:
NameTypeDescription
querystring
Returns:
Type: 
dynamic

(static) useTranscodeAudioStream(playbackInfo) → {dynamic}

Parameters:
NameTypeDescription
playbackInfodynamic
Returns:
Type: 
dynamic
jellyfin-roku Code Documentation
\ No newline at end of file diff --git a/docs/api/source_api_Items.bs.html b/docs/api/source_api_Items.bs.html index a7bfe263d..ea81fa0ea 100644 --- a/docs/api/source_api_Items.bs.html +++ b/docs/api/source_api_Items.bs.html @@ -15,7 +15,7 @@ return getJson(resp) end function -function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = -1 as integer, startTimeTicks = 0 as longinteger) +function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioTrackIndex = -1 as integer, subtitleTrackIndex = -1 as integer, startTimeTicks = 0 as longinteger, forceMp3 = false as boolean) params = { "UserId": m.global.session.user.id, "StartTimeTicks": startTimeTicks, @@ -51,24 +51,14 @@ ' TODO: Remove this after server adds support for transcoding AAC from one profile to another if selectedAudioStream.Codec <> invalid and LCase(selectedAudioStream.Codec) = "aac" if selectedAudioStream.Profile <> invalid and LCase(selectedAudioStream.Profile) = "main" or LCase(selectedAudioStream.Profile) = "he-aac" - for each rule in deviceProfile.TranscodingProfiles - if rule.Container = "ts" or rule.Container = "mp4" - if rule.AudioCodec = "aac" - rule.AudioCodec = "mp3" - else if rule.AudioCodec.Left(4) = "aac," - rule.AudioCodec = mid(rule.AudioCodec, 5) - - if rule.AudioCodec.Left(3) <> "mp3" - rule.AudioCodec = "mp3," + rule.AudioCodec - end if - end if - end if - end for + forceMp3 = true end if end if end if end if + if forceMp3 then forceMp3Audio(deviceProfile) + req = APIRequest(Substitute("Items/{0}/PlaybackInfo", id), params) req.SetRequest("POST") return postJson(req, FormatJson({ "DeviceProfile": deviceProfile })) @@ -540,4 +530,21 @@ return data end function + +' updates the device profile we send the server to force mp3 audio transcoding instead of the default aac +sub forceMp3Audio(deviceProfile as object) + for each rule in deviceProfile.TranscodingProfiles + if rule.Container = "ts" or rule.Container = "mp4" + if rule.AudioCodec = "aac" + rule.AudioCodec = "mp3" + else if rule.AudioCodec.Left(4) = "aac," + rule.AudioCodec = mid(rule.AudioCodec, 5) + + if rule.AudioCodec.Left(3) <> "mp3" + rule.AudioCodec = "mp3," + rule.AudioCodec + end if + end if + end if + end for +end sub
jellyfin-roku Code Documentation
\ No newline at end of file From eaf2e11d2d18f665ccff8660151d9d5bcd5a1892 Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Tue, 26 Nov 2024 12:22:56 +0000 Subject: [PATCH 29/29] Update API docs --- .../components_video_VideoPlayerView.bs.html | 84 ++++++++----------- 1 file changed, 35 insertions(+), 49 deletions(-) diff --git a/docs/api/components_video_VideoPlayerView.bs.html b/docs/api/components_video_VideoPlayerView.bs.html index 2320be3fc..c10000d4e 100644 --- a/docs/api/components_video_VideoPlayerView.bs.html +++ b/docs/api/components_video_VideoPlayerView.bs.html @@ -441,13 +441,9 @@ populateChapterMenu() - if m.LoadMetaDataTask.isIntro - ' Disable trackplay bar for intro videos - m.top.enableTrickPlay = false - else - ' Allow custom captions for non intro videos - m.top.allowCaptions = true - end if + + ' Allow custom captions for all videos including intro videos + m.top.allowCaptions = true ' Allow default subtitles m.top.unobserveField("selectedSubtitle") @@ -839,62 +835,52 @@ if not press then return false if key = "down" and not m.top.trickPlayBar.visible - if not m.LoadMetaDataTask.isIntro - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) - return true - end if + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true else if key = "up" and not m.top.trickPlayBar.visible - if not m.LoadMetaDataTask.isIntro - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) - return true - end if + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true else if key = "OK" and not m.top.trickPlayBar.visible - if not m.LoadMetaDataTask.isIntro - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true - - ' Show OSD, but don't pause video - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) - return true - end if + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - return false + ' Show OSD, but don't pause video + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true end if ' Disable OSD for intro videos - if not m.LoadMetaDataTask.isIntro - if key = "play" and not m.top.trickPlayBar.visible - - ' Don't allow user to open menu prior to video loading - if not stateAllowsOSD() then return true + if key = "play" and not m.top.trickPlayBar.visible - ' If video is paused, resume it and don't show OSD - if m.top.state = "paused" - m.top.control = "resume" - return true - end if + ' Don't allow user to open menu prior to video loading + if not stateAllowsOSD() then return true - ' Pause video and show OSD - m.top.control = "pause" - m.osd.visible = true - m.osd.hasFocus = true - m.osd.setFocus(true) + ' If video is paused, resume it and don't show OSD + if m.top.state = "paused" + m.top.control = "resume" return true end if + + ' Pause video and show OSD + m.top.control = "pause" + m.osd.visible = true + m.osd.hasFocus = true + m.osd.setFocus(true) + return true end if if key = "back"