From c3afaebf3f7d7faf6d3636b6db4fc8f2cba0c87e Mon Sep 17 00:00:00 2001 From: jellyfin-bot Date: Tue, 8 Oct 2024 16:23:40 +0000 Subject: [PATCH 1/7] 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 f91b82442..bcc572a3c 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # If you want to get_images, you'll also need convert from ImageMagick ########################################################################## -VERSION := 2.1.7 +VERSION := 2.1.8 ## usage diff --git a/manifest b/manifest index 532b80faf..0486a6822 100644 --- a/manifest +++ b/manifest @@ -3,7 +3,7 @@ title=Jellyfin major_version=2 minor_version=1 -build_version=7 +build_version=8 ### Main Menu Icons / Channel Poster Artwork diff --git a/package-lock.json b/package-lock.json index 8cf4e823c..8e69fd219 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jellyfin-roku", - "version": "2.1.7", + "version": "2.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jellyfin-roku", - "version": "2.1.7", + "version": "2.1.8", "hasInstallScript": true, "license": "GPL-2.0", "dependencies": { diff --git a/package.json b/package.json index ff420268c..da1252fdd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jellyfin-roku", "type": "module", - "version": "2.1.7", + "version": "2.1.8", "description": "Roku app for Jellyfin media server", "dependencies": { "@rokucommunity/bslib": "0.1.1", From 2d91603d391e3eab205d9761b95f3c7bec08d1a5 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 15 Oct 2024 07:59:58 -0400 Subject: [PATCH 2/7] Prevent crash when there are no media streams (#1982) --- source/api/Items.bs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/api/Items.bs b/source/api/Items.bs index c7ba49899..3f6319437 100644 --- a/source/api/Items.bs +++ b/source/api/Items.bs @@ -37,8 +37,10 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT params.EnableDirectPlay = false end if - if audioTrackIndex > -1 - selectedAudioStream = m.global.session.video.json.MediaStreams[audioTrackIndex] + myGLobal = m.global + + if audioTrackIndex > -1 and myGLobal.session.video.json.MediaStreams <> invalid + selectedAudioStream = myGLobal.session.video.json.MediaStreams[audioTrackIndex] if selectedAudioStream <> invalid params.AudioStreamIndex = audioTrackIndex @@ -62,7 +64,6 @@ function ItemPostPlaybackInfo(id as string, mediaSourceId = "" as string, audioT end for end if end if - end if end if From c14ec8f59ce12d0b9eb45030c3657f656c1149a3 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 15 Oct 2024 08:00:51 -0400 Subject: [PATCH 3/7] Fix crash when playing HDR on SDR TV. Improve device profile (#1980) --- source/utils/deviceCapabilities.bs | 100 +++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 21 deletions(-) diff --git a/source/utils/deviceCapabilities.bs b/source/utils/deviceCapabilities.bs index 746880cb6..aa580e53a 100644 --- a/source/utils/deviceCapabilities.bs +++ b/source/utils/deviceCapabilities.bs @@ -414,7 +414,14 @@ function getContainerProfiles() as object end function function getCodecProfiles() as object - globalUserSettings = m.global.session.user.settings + myGlobal = m.global + globalUserSettings = myGlobal.session.user.settings + displayMaxBitDepth = myGlobal.device.videoBitDepth + if displayMaxBitDepth = invalid + displayMaxBitDepth = "8" + else + displayMaxBitDepth = displayMaxBitDepth.toStr() + end if codecProfiles = [] profileSupport = { "h264": {}, @@ -556,25 +563,27 @@ function getCodecProfiles() as object vp9VideoRangeTypes = "SDR" av1VideoRangeTypes = "SDR" - dp = di.GetDisplayProperties() - if dp.Hdr10 - hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10" - vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10" - av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10" - end if - if dp.Hdr10Plus - av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+" - end if - if dp.HLG - hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG" - vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG" - av1VideoRangeTypes = av1VideoRangeTypes + "|HLG" - end if - if dp.DolbyVision - h264VideoRangeTypes = h264VideoRangeTypes + "|DOVI" - hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI" - 'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI - av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI" + if canPlay4k() + dp = di.GetDisplayProperties() + if dp.Hdr10 + hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10" + vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10" + av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10" + end if + if dp.Hdr10Plus + av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+" + end if + if dp.HLG + hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG" + vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG" + av1VideoRangeTypes = av1VideoRangeTypes + "|HLG" + end if + if dp.DolbyVision + h264VideoRangeTypes = h264VideoRangeTypes + "|DOVI" + hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI" + 'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI + av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI" + end if end if ' H264 @@ -670,7 +679,13 @@ function getCodecProfiles() as object "Property": "VideoLevel", "Value": mpeg2Levels.join("|"), "IsRequired": false - } + }, + { + "Condition": "LessThanEqual", + "Property": "VideoBitDepth", + "Value": displayMaxBitDepth, + "IsRequired": false + }, ] } @@ -706,6 +721,12 @@ function getCodecProfiles() as object "Type": "Video", "Codec": "av1", "Conditions": [ + { + "Condition": "LessThanEqual", + "Property": "VideoBitDepth", + "Value": displayMaxBitDepth, + "IsRequired": false + }, { "Condition": "EqualsAny", "Property": "VideoProfile", @@ -765,6 +786,12 @@ function getCodecProfiles() as object "Type": "Video", "Codec": "hevc", "Conditions": [ + { + "Condition": "LessThanEqual", + "Property": "VideoBitDepth", + "Value": displayMaxBitDepth, + "IsRequired": false + }, { "Condition": "NotEquals", "Property": "IsAnamorphic", @@ -834,6 +861,12 @@ function getCodecProfiles() as object "Type": "Video", "Codec": "vp9", "Conditions": [ + { + "Condition": "LessThanEqual", + "Property": "VideoBitDepth", + "Value": displayMaxBitDepth, + "IsRequired": false + }, { "Condition": "EqualsAny", "Property": "VideoProfile", @@ -1094,3 +1127,28 @@ function setPreferredCodec(codecString as string, preferredCodec as string) as s return newCodecString end if end function + +' does the connected display support playing 4k video? +function canPlay4k() as boolean + deviceInfo = CreateObject("roDeviceInfo") + hdmiStatus = CreateObject("roHdmiStatus") + + ' Check if the output mode is 2160p or higher + maxVideoHeight = m.global.device.videoHeight + if maxVideoHeight = invalid then return false + if maxVideoHeight.ToInt() < 2160 + return false + end if + + ' Check if HDCP 2.2 is enabled, skip check for TVs + if deviceInfo.GetModelType() = "STB" and hdmiStatus.IsHdcpActive("2.2") <> true + return false + end if + + ' Check if the Roku player can decode 4K 60fps HEVC streams + if deviceInfo.CanDecodeVideo({ Codec: "hevc", Profile: "main", Level: "5.1" }).result <> true + return false + end if + + return true +end function From ee4d7a14650a4d9f50764bedf0a7c24bf1616145 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 15 Oct 2024 09:21:24 -0400 Subject: [PATCH 4/7] Improve direct play support for Dolby Vision --- source/utils/deviceCapabilities.bs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/source/utils/deviceCapabilities.bs b/source/utils/deviceCapabilities.bs index aa580e53a..8960b504b 100644 --- a/source/utils/deviceCapabilities.bs +++ b/source/utils/deviceCapabilities.bs @@ -562,27 +562,44 @@ function getCodecProfiles() as object hevcVideoRangeTypes = "SDR" vp9VideoRangeTypes = "SDR" av1VideoRangeTypes = "SDR" + canPlayDovi = false if canPlay4k() dp = di.GetDisplayProperties() + + if dp.DolbyVision + canPlayDovi = true + + h264VideoRangeTypes = h264VideoRangeTypes + "|DOVI|DOVIWithSDR" + hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI|DOVIWithSDR" + av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI|DOVIWithSDR" + end if + if dp.Hdr10 hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10" vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10" av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10" + + if canPlayDovi + hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVIWithHDR10" + av1VideoRangeTypes = av1VideoRangeTypes + "|DOVIWithHDR10" + end if end if + if dp.Hdr10Plus av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+" end if + if dp.HLG hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG" vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG" av1VideoRangeTypes = av1VideoRangeTypes + "|HLG" - end if - if dp.DolbyVision - h264VideoRangeTypes = h264VideoRangeTypes + "|DOVI" - hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI" - 'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI - av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI" + + if canPlayDovi + hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVIWithHLG" + vp9VideoRangeTypes = vp9VideoRangeTypes + "|DOVIWithHLG" + av1VideoRangeTypes = av1VideoRangeTypes + "|DOVIWithHLG" + end if end if end if From ee2a7b94c40da14eadf02705e09269e12414e5d2 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 15 Oct 2024 11:07:01 -0400 Subject: [PATCH 5/7] correctly detect the displays video bit depth --- source/utils/globals.bs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/utils/globals.bs b/source/utils/globals.bs index dc13af952..b9f924f18 100644 --- a/source/utils/globals.bs +++ b/source/utils/globals.bs @@ -97,11 +97,8 @@ sub SaveDeviceToGlobal() print "ERROR parsing deviceInfo.GetVideoMode()" end if videoWidth = heightToWidth[videoHeight] - if videoHeight = "2160" and extraData = "b10" - bitDepth = 10 - else if videoHeight = "4320" - bitDepth = 12 - end if + if extraData <> invalid and extraData = "b10" then bitDepth = 10 + if videoHeight = "4320" then bitDepth = 12 m.global.addFields({ device: { From 3fbe253d0dd7e8135dae0622bb790399c5d713e8 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 15 Oct 2024 11:16:31 -0400 Subject: [PATCH 6/7] if display reports as 8bit but can play HDR, then tell the server we can play 10bit videos --- source/utils/globals.bs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/utils/globals.bs b/source/utils/globals.bs index b9f924f18..cea2664b8 100644 --- a/source/utils/globals.bs +++ b/source/utils/globals.bs @@ -44,6 +44,7 @@ end sub ' Save information from roDeviceInfo to m.global.device sub SaveDeviceToGlobal() deviceInfo = CreateObject("roDeviceInfo") + displayProperties = deviceInfo.GetDisplayProperties() ' remove special characters regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "") @@ -98,6 +99,7 @@ sub SaveDeviceToGlobal() end if videoWidth = heightToWidth[videoHeight] if extraData <> invalid and extraData = "b10" then bitDepth = 10 + if bitDepth = 8 and displayProperties.HdrSeamless then bitDepth = 10 if videoHeight = "4320" then bitDepth = 12 m.global.addFields({ From 21667359b13e345b8b70d8c3764dfd3a5a0498b7 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 15 Oct 2024 11:36:18 -0400 Subject: [PATCH 7/7] stop restricting videos based on bitdepth --- source/utils/deviceCapabilities.bs | 39 ++---------------------------- source/utils/globals.bs | 2 -- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/source/utils/deviceCapabilities.bs b/source/utils/deviceCapabilities.bs index 8960b504b..384838972 100644 --- a/source/utils/deviceCapabilities.bs +++ b/source/utils/deviceCapabilities.bs @@ -416,12 +416,7 @@ end function function getCodecProfiles() as object myGlobal = m.global globalUserSettings = myGlobal.session.user.settings - displayMaxBitDepth = myGlobal.device.videoBitDepth - if displayMaxBitDepth = invalid - displayMaxBitDepth = "8" - else - displayMaxBitDepth = displayMaxBitDepth.toStr() - end if + codecProfiles = [] profileSupport = { "h264": {}, @@ -631,12 +626,6 @@ function getCodecProfiles() as object "Value": "true", "IsRequired": false }, - { - "Condition": "LessThanEqual", - "Property": "VideoBitDepth", - "Value": "8", - "IsRequired": false - }, { "Condition": "EqualsAny", "Property": "VideoProfile", @@ -696,13 +685,7 @@ function getCodecProfiles() as object "Property": "VideoLevel", "Value": mpeg2Levels.join("|"), "IsRequired": false - }, - { - "Condition": "LessThanEqual", - "Property": "VideoBitDepth", - "Value": displayMaxBitDepth, - "IsRequired": false - }, + } ] } @@ -738,12 +721,6 @@ function getCodecProfiles() as object "Type": "Video", "Codec": "av1", "Conditions": [ - { - "Condition": "LessThanEqual", - "Property": "VideoBitDepth", - "Value": displayMaxBitDepth, - "IsRequired": false - }, { "Condition": "EqualsAny", "Property": "VideoProfile", @@ -803,12 +780,6 @@ function getCodecProfiles() as object "Type": "Video", "Codec": "hevc", "Conditions": [ - { - "Condition": "LessThanEqual", - "Property": "VideoBitDepth", - "Value": displayMaxBitDepth, - "IsRequired": false - }, { "Condition": "NotEquals", "Property": "IsAnamorphic", @@ -878,12 +849,6 @@ function getCodecProfiles() as object "Type": "Video", "Codec": "vp9", "Conditions": [ - { - "Condition": "LessThanEqual", - "Property": "VideoBitDepth", - "Value": displayMaxBitDepth, - "IsRequired": false - }, { "Condition": "EqualsAny", "Property": "VideoProfile", diff --git a/source/utils/globals.bs b/source/utils/globals.bs index cea2664b8..b9f924f18 100644 --- a/source/utils/globals.bs +++ b/source/utils/globals.bs @@ -44,7 +44,6 @@ end sub ' Save information from roDeviceInfo to m.global.device sub SaveDeviceToGlobal() deviceInfo = CreateObject("roDeviceInfo") - displayProperties = deviceInfo.GetDisplayProperties() ' remove special characters regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "") @@ -99,7 +98,6 @@ sub SaveDeviceToGlobal() end if videoWidth = heightToWidth[videoHeight] if extraData <> invalid and extraData = "b10" then bitDepth = 10 - if bitDepth = 8 and displayProperties.HdrSeamless then bitDepth = 10 if videoHeight = "4320" then bitDepth = 12 m.global.addFields({