update prefered codecs and maxAudioChannel logic
This commit is contained in:
parent
adc769c625
commit
9c6201b25e
|
@ -52,47 +52,63 @@ function getDeviceProfile() as object
|
||||||
playAv1 = m.global.session.user.settings["playback.av1"]
|
playAv1 = m.global.session.user.settings["playback.av1"]
|
||||||
di = CreateObject("roDeviceInfo")
|
di = CreateObject("roDeviceInfo")
|
||||||
|
|
||||||
transContainers = ["mp4", "hls", "mkv", "ism", "dash", "ts"]
|
' TRANSCODING
|
||||||
supportedVideoCodecs = {}
|
' use strings to preserve order
|
||||||
supportedAudioCodecs = {}
|
mp4AudioCodecs = "aac"
|
||||||
addH264Profile = false
|
mp4VideoCodecs = "h264"
|
||||||
addHevcProfile = false
|
tsAudioCodecs = "aac"
|
||||||
addMpeg2Profile = false
|
tsVideoCodecs = "h264"
|
||||||
addAv1Profile = false
|
' profileSupport["mp4"]["hevc"]["profile name"]["profile level"]
|
||||||
addVp9Profile = false
|
profileSupport = {
|
||||||
|
mp4: {},
|
||||||
|
ts: {}
|
||||||
|
}
|
||||||
|
|
||||||
maxAudioChannels = "2"
|
|
||||||
di = CreateObject("roDeviceInfo")
|
' does the users setup support surround sound?
|
||||||
|
maxAudioChannels = "2" ' jellyfin expects this as a string
|
||||||
|
' in order of preference from left to right
|
||||||
|
' aac will be highest priority unless surroundSoundCodec <> "aac"
|
||||||
|
audioCodecs = ["mp3", "vorbis", "opus", "flac", "alac", "ac4", "pcm", "wma", "wmapro"]
|
||||||
|
surroundSoundCodecs = ["aac", "eac3", "ac3", "vorbis", "dts"]
|
||||||
|
surroundSoundCodec = invalid
|
||||||
if di.GetAudioOutputChannel() = "5.1 surround"
|
if di.GetAudioOutputChannel() = "5.1 surround"
|
||||||
maxAudioChannels = "6"
|
maxAudioChannels = "6"
|
||||||
eightChannelCodecs = ["ac3", "eac3", "dts"]
|
for each codec in surroundSoundCodecs
|
||||||
for each eightChannelCodec in eightChannelCodecs
|
if di.CanDecodeAudio({ Codec: codec, ChCnt: 6 }).Result
|
||||||
if di.CanDecodeAudio({ Codec: eightChannelCodec, ChCnt: 8 }).Result
|
surroundSoundCodec = codec
|
||||||
|
if di.CanDecodeAudio({ Codec: codec, ChCnt: 8 }).Result
|
||||||
maxAudioChannels = "8"
|
maxAudioChannels = "8"
|
||||||
|
end if
|
||||||
exit for
|
exit for
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
end if
|
end if
|
||||||
|
|
||||||
' AVC / h264
|
' VIDEO CODECS
|
||||||
|
'
|
||||||
|
' AVC / h264 / MPEG4 AVC
|
||||||
h264Profiles = ["main", "high"]
|
h264Profiles = ["main", "high"]
|
||||||
h264Levels = ["4.1", "4.2"]
|
h264Levels = ["4.1", "4.2"]
|
||||||
|
for each container in profileSupport
|
||||||
for each container in transContainers
|
|
||||||
for each profile in h264Profiles
|
for each profile in h264Profiles
|
||||||
for each level in h264Levels
|
for each level in h264Levels
|
||||||
if di.CanDecodeVideo({ Codec: "h264", Container: container, Profile: profile, Level: level }).Result
|
if di.CanDecodeVideo({ Codec: "h264", Container: container, Profile: profile, Level: level }).Result
|
||||||
addH264Profile = true
|
profileSupport[container] = updateProfileArray(profileSupport[container], "h264", profile, level)
|
||||||
if supportedVideoCodecs[container] = invalid
|
|
||||||
supportedVideoCodecs[container] = {}
|
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["h264"] = invalid
|
if di.CanDecodeVideo({ Codec: "mpeg4 avc", Container: container, Profile: profile, Level: level }).Result
|
||||||
supportedVideoCodecs[container]["h264"] = {}
|
profileSupport[container] = updateProfileArray(profileSupport[container], "mpeg4 avc", profile, level)
|
||||||
|
if container = "mp4"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if mp4VideoCodecs.Instr(0, ",mpeg4 avc") = -1
|
||||||
|
mp4VideoCodecs = mp4VideoCodecs + ",mpeg4 avc"
|
||||||
|
end if
|
||||||
|
else if container = "ts"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if tsVideoCodecs.Instr(0, ",mpeg4 avc") = -1
|
||||||
|
tsVideoCodecs = tsVideoCodecs + ",mpeg4 avc"
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["h264"][profile] = invalid
|
|
||||||
supportedVideoCodecs[container]["h264"][profile] = []
|
|
||||||
end if
|
end if
|
||||||
supportedVideoCodecs[container]["h264"][profile].push(level)
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
|
@ -101,53 +117,80 @@ function getDeviceProfile() as object
|
||||||
' HEVC / h265
|
' HEVC / h265
|
||||||
hevcProfiles = ["main", "main 10"]
|
hevcProfiles = ["main", "main 10"]
|
||||||
hevcLevels = ["4.1", "5.0", "5.1"]
|
hevcLevels = ["4.1", "5.0", "5.1"]
|
||||||
|
addHevc = false
|
||||||
for each container in transContainers
|
for each container in profileSupport
|
||||||
for each profile in hevcProfiles
|
for each profile in hevcProfiles
|
||||||
for each level in hevcLevels
|
for each level in hevcLevels
|
||||||
if di.CanDecodeVideo({ Codec: "hevc", Container: container, Profile: profile, Level: level }).Result
|
if di.CanDecodeVideo({ Codec: "hevc", Container: container, Profile: profile, Level: level }).Result
|
||||||
addHevcProfile = true
|
addHevc = true
|
||||||
' hevc codec string
|
profileSupport[container] = updateProfileArray(profileSupport[container], "hevc", profile, level)
|
||||||
if supportedVideoCodecs[container] = invalid
|
profileSupport[container] = updateProfileArray(profileSupport[container], "h265", profile, level)
|
||||||
supportedVideoCodecs[container] = {}
|
if container = "mp4"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if mp4VideoCodecs.Instr(0, "h265,") = -1
|
||||||
|
mp4VideoCodecs = "h265," + mp4VideoCodecs
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["hevc"] = invalid
|
if mp4VideoCodecs.Instr(0, "hevc,") = -1
|
||||||
supportedVideoCodecs[container]["hevc"] = {}
|
mp4VideoCodecs = "hevc," + mp4VideoCodecs
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["hevc"][profile] = invalid
|
else if container = "ts"
|
||||||
supportedVideoCodecs[container]["hevc"][profile] = []
|
' check for codec string before adding it
|
||||||
|
if tsVideoCodecs.Instr(0, "h265,") = -1
|
||||||
|
tsVideoCodecs = "h265," + tsVideoCodecs
|
||||||
end if
|
end if
|
||||||
supportedVideoCodecs[container]["hevc"][profile].push(level)
|
if tsVideoCodecs.Instr(0, "hevc,") = -1
|
||||||
' h265 codec string
|
tsVideoCodecs = "hevc," + tsVideoCodecs
|
||||||
if supportedVideoCodecs[container] = invalid
|
|
||||||
supportedVideoCodecs[container] = {}
|
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["h265"] = invalid
|
|
||||||
supportedVideoCodecs[container]["h265"] = {}
|
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["h265"][profile] = invalid
|
|
||||||
supportedVideoCodecs[container]["h265"][profile] = []
|
|
||||||
end if
|
|
||||||
supportedVideoCodecs[container]["h265"][profile].push(level)
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
|
|
||||||
|
' VP9
|
||||||
|
vp9Profiles = ["profile 0", "profile 2"]
|
||||||
|
addVp9 = false
|
||||||
|
for each container in profileSupport
|
||||||
|
for each profile in vp9Profiles
|
||||||
|
if di.CanDecodeAudio({ Codec: "vp9", Container: container, Profile: profile }).Result
|
||||||
|
addVp9 = true
|
||||||
|
profileSupport[container] = updateProfileArray(profileSupport[container], "vp9", profile)
|
||||||
|
|
||||||
|
if container = "mp4"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if mp4VideoCodecs.Instr(0, ",vp9") = -1
|
||||||
|
mp4VideoCodecs = mp4VideoCodecs + ",vp9"
|
||||||
|
end if
|
||||||
|
else if container = "ts"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if tsVideoCodecs.Instr(0, ",vp9") = -1
|
||||||
|
tsVideoCodecs = tsVideoCodecs + ",vp9"
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
|
||||||
' MPEG2
|
' MPEG2
|
||||||
mpeg2Levels = ["main", "high"]
|
mpeg2Profiles = ["main", "high"]
|
||||||
|
addMpeg2 = false
|
||||||
if playMpeg2
|
if playMpeg2
|
||||||
for each container in transContainers
|
for each container in profileSupport
|
||||||
for each level in mpeg2Levels
|
for each profile in mpeg2Profiles
|
||||||
if di.CanDecodeVideo({ Codec: "mpeg2", Container: container, Level: level }).Result
|
if di.CanDecodeVideo({ Codec: "mpeg2", Container: container, Profile: profile }).Result
|
||||||
addMpeg2Profile = true
|
addMpeg2 = true
|
||||||
if supportedVideoCodecs[container] = invalid
|
profileSupport[container] = updateProfileArray(profileSupport[container], "mpeg2", profile)
|
||||||
supportedVideoCodecs[container] = {}
|
if container = "mp4"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if mp4VideoCodecs.Instr(0, ",mpeg2video") = -1
|
||||||
|
mp4VideoCodecs = mp4VideoCodecs + ",mpeg2video"
|
||||||
|
end if
|
||||||
|
else if container = "ts"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if tsVideoCodecs.Instr(0, ",mpeg2video") = -1
|
||||||
|
tsVideoCodecs = tsVideoCodecs + ",mpeg2video"
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["mpeg2video"] = invalid
|
|
||||||
supportedVideoCodecs[container]["mpeg2video"] = []
|
|
||||||
end if
|
end if
|
||||||
supportedVideoCodecs[container]["mpeg2video"].push(level)
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
|
@ -156,153 +199,72 @@ function getDeviceProfile() as object
|
||||||
' AV1
|
' AV1
|
||||||
av1Profiles = ["main", "main 10"]
|
av1Profiles = ["main", "main 10"]
|
||||||
av1Levels = ["4.1", "5.0", "5.1"]
|
av1Levels = ["4.1", "5.0", "5.1"]
|
||||||
|
addAv1 = false
|
||||||
if playAv1
|
if playAv1
|
||||||
for each container in transContainers
|
for each container in profileSupport
|
||||||
for each profile in av1Profiles
|
for each profile in av1Profiles
|
||||||
for each level in av1Levels
|
for each level in av1Levels
|
||||||
if di.CanDecodeVideo({ Codec: "av1", Container: container, Profile: profile, Level: level }).Result
|
if di.CanDecodeVideo({ Codec: "av1", Container: container, Profile: profile, Level: level }).Result
|
||||||
addAv1Profile = true
|
addAv1 = true
|
||||||
' av1 codec string
|
profileSupport[container] = updateProfileArray(profileSupport[container], "av1", profile, level)
|
||||||
if supportedVideoCodecs[container] = invalid
|
if container = "mp4"
|
||||||
supportedVideoCodecs[container] = {}
|
' check for codec string before adding it
|
||||||
|
if mp4VideoCodecs.Instr(0, ",av1") = -1
|
||||||
|
mp4VideoCodecs = mp4VideoCodecs + ",av1"
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["av1"] = invalid
|
else if container = "ts"
|
||||||
supportedVideoCodecs[container]["av1"] = {}
|
' check for codec string before adding it
|
||||||
|
if tsVideoCodecs.Instr(0, ",av1") = -1
|
||||||
|
tsVideoCodecs = tsVideoCodecs + ",av1"
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["av1"][profile] = invalid
|
|
||||||
supportedVideoCodecs[container]["av1"][profile] = []
|
|
||||||
end if
|
end if
|
||||||
supportedVideoCodecs[container]["av1"][profile].push(level)
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
end if
|
end if
|
||||||
|
|
||||||
' VP9
|
' AUDIO CODECS
|
||||||
vp9Profiles = ["profile 0", "profile 2"]
|
for each container in profileSupport
|
||||||
|
for each codec in audioCodecs
|
||||||
for each container in transContainers
|
if di.CanDecodeAudio({ Codec: codec, Container: container }).result
|
||||||
for each profile in vp9Profiles
|
if container = "mp4"
|
||||||
if di.CanDecodeVideo({ Codec: "vp9", Container: container, Profile: profile }).Result
|
' check for codec string before adding it
|
||||||
addVp9Profile = true
|
if mp4VideoCodecs.Instr(0, "," + codec) = -1
|
||||||
' vp9 codec string
|
mp4AudioCodecs = mp4AudioCodecs + "," + codec
|
||||||
if supportedVideoCodecs[container] = invalid
|
end if
|
||||||
supportedVideoCodecs[container] = {}
|
else if container = "ts"
|
||||||
|
' check for codec string before adding it
|
||||||
|
if tsAudioCodecs.Instr(0, "," + codec) = -1
|
||||||
|
tsAudioCodecs = tsAudioCodecs + "," + codec
|
||||||
end if
|
end if
|
||||||
if supportedVideoCodecs[container]["vp9"] = invalid
|
|
||||||
supportedVideoCodecs[container]["vp9"] = []
|
|
||||||
end if
|
end if
|
||||||
supportedVideoCodecs[container]["vp9"].push(profile)
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
end for
|
end for
|
||||||
|
|
||||||
' eac3
|
' HDR SUPPORT
|
||||||
for each container in transContainers
|
h264VideoRangeTypes = "SDR"
|
||||||
if di.CanDecodeAudio({ Codec: "eac3", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("eac3")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
|
|
||||||
' ac3
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "ac3", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("ac3")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
' dts
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "dts", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("dts")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
' opus
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "opus", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("opus")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
' flac
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "flac", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("flac")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
' vorbis
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "vorbis", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("vorbis")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
' aac
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "aac", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("aac")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
' mp3
|
|
||||||
for each container in transContainers
|
|
||||||
if di.CanDecodeAudio({ Codec: "mp3", Container: container }).result
|
|
||||||
if supportedAudioCodecs[container] = invalid
|
|
||||||
supportedAudioCodecs[container] = []
|
|
||||||
end if
|
|
||||||
|
|
||||||
supportedAudioCodecs[container].push("mp3")
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
hevcVideoRangeTypes = "SDR"
|
hevcVideoRangeTypes = "SDR"
|
||||||
vp9VideoRangeTypes = "SDR"
|
vp9VideoRangeTypes = "SDR"
|
||||||
av1VideoRangeTypes = "SDR"
|
av1VideoRangeTypes = "SDR"
|
||||||
|
|
||||||
dp = di.GetDisplayProperties()
|
dp = di.GetDisplayProperties()
|
||||||
if dp.Hdr10 ' or dp.Hdr10Plus?
|
if dp.Hdr10
|
||||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10"
|
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10"
|
||||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10"
|
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10"
|
||||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10"
|
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10"
|
||||||
end if
|
end if
|
||||||
|
if dp.Hdr10Plus
|
||||||
|
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+"
|
||||||
|
end if
|
||||||
if dp.HLG
|
if dp.HLG
|
||||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG"
|
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG"
|
||||||
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG"
|
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG"
|
||||||
av1VideoRangeTypes = av1VideoRangeTypes + "|HLG"
|
av1VideoRangeTypes = av1VideoRangeTypes + "|HLG"
|
||||||
end if
|
end if
|
||||||
if dp.DolbyVision
|
if dp.DolbyVision
|
||||||
|
h264VideoRangeTypes = hevcVideoRangeTypes + "|DOVI"
|
||||||
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI"
|
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI"
|
||||||
'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI
|
'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI
|
||||||
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI"
|
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI"
|
||||||
|
@ -318,18 +280,18 @@ function getDeviceProfile() as object
|
||||||
"TranscodingProfiles": [],
|
"TranscodingProfiles": [],
|
||||||
"ContainerProfiles": [],
|
"ContainerProfiles": [],
|
||||||
"CodecProfiles": [
|
"CodecProfiles": [
|
||||||
{
|
' {
|
||||||
"Type": "VideoAudio",
|
' "Type": "VideoAudio",
|
||||||
"Codec": DirectPlayProfile[1].AudioCodec, ' Use supported MKV Audio list
|
' "Codec": DirectPlayProfile[1].AudioCodec, ' Use supported MKV Audio list
|
||||||
"Conditions": [
|
' "Conditions": [
|
||||||
{
|
' {
|
||||||
"Condition": "LessThanEqual",
|
' "Condition": "LessThanEqual",
|
||||||
"Property": "AudioChannels",
|
' "Property": "AudioChannels",
|
||||||
"Value": maxAudioChannels,
|
' "Value": maxAudioChannels,
|
||||||
"IsRequired": false
|
' "IsRequired": false
|
||||||
}
|
' }
|
||||||
]
|
' ]
|
||||||
}
|
' }
|
||||||
],
|
],
|
||||||
"SubtitleProfiles": [
|
"SubtitleProfiles": [
|
||||||
{
|
{
|
||||||
|
@ -352,92 +314,127 @@ function getDeviceProfile() as object
|
||||||
}
|
}
|
||||||
|
|
||||||
' build TranscodingProfiles
|
' build TranscodingProfiles
|
||||||
' create an audio profile for each audio codec supported by the mp4 container
|
'
|
||||||
for each supportedMp4AudioCodec in supportedAudioCodecs["mp4"]
|
for each audioCodec in mp4AudioCodecs.split(",")
|
||||||
' streaming
|
streamingArray = {
|
||||||
deviceProfile.TranscodingProfiles.push({
|
"Container": audioCodec,
|
||||||
"Container": supportedMp4AudioCodec,
|
|
||||||
"Type": "Audio",
|
"Type": "Audio",
|
||||||
"AudioCodec": supportedMp4AudioCodec,
|
"AudioCodec": audioCodec,
|
||||||
"Context": "Streaming",
|
"Context": "Streaming",
|
||||||
"Protocol": "http",
|
"Protocol": "http",
|
||||||
"MaxAudioChannels": maxAudioChannels
|
"MaxAudioChannels": maxAudioChannels
|
||||||
})
|
}
|
||||||
' static
|
staticArray = {
|
||||||
deviceProfile.TranscodingProfiles.push({
|
"Container": audioCodec,
|
||||||
"Container": supportedMp4AudioCodec,
|
|
||||||
"Type": "Audio",
|
"Type": "Audio",
|
||||||
"AudioCodec": supportedMp4AudioCodec,
|
"AudioCodec": audioCodec,
|
||||||
"Context": "Static",
|
"Context": "Static",
|
||||||
"Protocol": "http",
|
"Protocol": "http",
|
||||||
"MaxAudioChannels": maxAudioChannels
|
"MaxAudioChannels": maxAudioChannels
|
||||||
})
|
|
||||||
end for
|
|
||||||
' create a video profile for each container in transContainers
|
|
||||||
for each container in transContainers
|
|
||||||
audioCodecs = []
|
|
||||||
videoCodecs = []
|
|
||||||
for each codec in supportedAudioCodecs[container]
|
|
||||||
audioCodecs.push(codec)
|
|
||||||
end for
|
|
||||||
for each codec in supportedVideoCodecs[container]
|
|
||||||
videoCodecs.push(codec)
|
|
||||||
end for
|
|
||||||
containerArray = {
|
|
||||||
"Container": container,
|
|
||||||
"Context": "Static",
|
|
||||||
"Type": "Video",
|
|
||||||
"AudioCodec": audioCodecs.join(","),
|
|
||||||
"VideoCodec": videoCodecs.join(","),
|
|
||||||
"MaxAudioChannels": maxAudioChannels
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if container = "ts"
|
' use ts container for aac
|
||||||
containerArray["Context"] = "Streaming"
|
if audioCodec = "aac"
|
||||||
containerArray["Protocol"] = "hls"
|
if di.CanDecodeAudio({ Codec: audioCodec, Container: "ts", ChCnt: maxAudioChannels.trim().ToInt() }).result
|
||||||
containerArray["MinSegments"] = "1"
|
streamingArray["Container"] = "ts"
|
||||||
containerArray["BreakOnNonKeyFrames"] = true
|
staticArray["Container"] = "ts"
|
||||||
else if container = "mp4"
|
|
||||||
containerArray["Context"] = "Static"
|
deviceProfile.TranscodingProfiles.push(streamingArray)
|
||||||
containerArray["Protocol"] = "http"
|
deviceProfile.TranscodingProfiles.push(staticArray)
|
||||||
|
end if
|
||||||
|
else
|
||||||
|
' use audioCodec as container for everything else
|
||||||
|
if di.CanDecodeAudio({ Codec: audioCodec, Container: audioCodec, ChCnt: maxAudioChannels.trim().ToInt() }).result
|
||||||
|
deviceProfile.TranscodingProfiles.push(streamingArray)
|
||||||
|
deviceProfile.TranscodingProfiles.push(staticArray)
|
||||||
|
end if
|
||||||
end if
|
end if
|
||||||
deviceProfile.TranscodingProfiles.push(containerArray)
|
|
||||||
end for
|
end for
|
||||||
|
|
||||||
' build CodecProfiles
|
|
||||||
if addH264Profile
|
tsArray = {
|
||||||
' determine highest level supported
|
"Container": "ts",
|
||||||
h264HighestLevel = 4.2
|
"Context": "Streaming",
|
||||||
h264HighestLevelSupported = 0.0
|
"Protocol": "hls",
|
||||||
for each container in transContainers
|
"Type": "Video",
|
||||||
for each profile in hevcProfiles
|
"AudioCodec": tsAudioCodecs,
|
||||||
for each level in supportedVideoCodecs[container]["h264"][profile]
|
"VideoCodec": tsVideoCodecs,
|
||||||
|
"MaxAudioChannels": maxAudioChannels,
|
||||||
|
"MinSegments": 1,
|
||||||
|
"BreakOnNonKeyFrames": false
|
||||||
|
}
|
||||||
|
mp4Array = {
|
||||||
|
"Container": "mp4",
|
||||||
|
"Context": "Streaming",
|
||||||
|
"Protocol": "hls",
|
||||||
|
"Type": "Video",
|
||||||
|
"AudioCodec": mp4AudioCodecs,
|
||||||
|
"VideoCodec": mp4VideoCodecs,
|
||||||
|
"MaxAudioChannels": maxAudioChannels,
|
||||||
|
"MinSegments": 1,
|
||||||
|
"BreakOnNonKeyFrames": false
|
||||||
|
}
|
||||||
|
|
||||||
|
' surround sound
|
||||||
|
' move preferred surround sound codec to front of string
|
||||||
|
if maxAudioChannels.ToInt() > 2
|
||||||
|
' search codec strings for our preferred codec
|
||||||
|
tsCodecStringPosition = tsArray.AudioCodec.Instr(0, "," + surroundSoundCodec)
|
||||||
|
mp4CodecStringPosition = mp4Array.AudioCodec.Instr(0, "," + surroundSoundCodec)
|
||||||
|
|
||||||
|
if tsCodecStringPosition <> -1
|
||||||
|
' ts supports our prefered codec
|
||||||
|
' remove codec from string
|
||||||
|
tsArray.AudioCodec.Replace("," + surroundSoundCodec, "")
|
||||||
|
' put codec in front of string
|
||||||
|
tsArray.AudioCodec = surroundSoundCodec + "," + tsArray.AudioCodec
|
||||||
|
end if
|
||||||
|
if mp4CodecStringPosition <> -1
|
||||||
|
' mp4 supports our prefered codec
|
||||||
|
' remove codec from string
|
||||||
|
mp4Array.AudioCodec.Replace("," + surroundSoundCodec, "")
|
||||||
|
' put codec in front of string
|
||||||
|
mp4Array.AudioCodec = surroundSoundCodec + "," + mp4Array.AudioCodec
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
||||||
|
deviceProfile.TranscodingProfiles.push(tsArray)
|
||||||
|
deviceProfile.TranscodingProfiles.push(mp4Array)
|
||||||
|
|
||||||
|
' Build CodecProfiles
|
||||||
|
'
|
||||||
|
' H264
|
||||||
|
h264Mp4LevelSupported = 0.0
|
||||||
|
h264TsLevelSupported = 0.0
|
||||||
|
h264AssProfiles = {}
|
||||||
|
h264LevelString = invalid
|
||||||
|
for each container in profileSupport
|
||||||
|
for each profile in profileSupport[container]["h264"]
|
||||||
|
h264AssProfiles.AddReplace(profile, true)
|
||||||
|
for each level in profileSupport[container]["h264"][profile]
|
||||||
levelFloat = level.ToFloat()
|
levelFloat = level.ToFloat()
|
||||||
if levelFloat > h264HighestLevelSupported
|
if container = "mp4"
|
||||||
h264HighestLevelSupported = levelFloat
|
if levelFloat > h264Mp4LevelSupported
|
||||||
|
h264Mp4LevelSupported = levelFloat
|
||||||
end if
|
end if
|
||||||
if h264HighestLevelSupported = h264HighestLevel then exit for
|
else if container = "ts"
|
||||||
end for
|
if levelFloat > h264TsLevelSupported
|
||||||
if h264HighestLevelSupported = h264HighestLevel then exit for
|
h264TsLevelSupported = levelFloat
|
||||||
end for
|
|
||||||
if h264HighestLevelSupported = h264HighestLevel then exit for
|
|
||||||
end for
|
|
||||||
|
|
||||||
h264LevelString = "41"
|
|
||||||
if h264HighestLevelSupported = 4.2
|
|
||||||
h264LevelString = "42"
|
|
||||||
end if
|
end if
|
||||||
|
|
||||||
|
|
||||||
videoProfiles = []
|
|
||||||
for each container in transContainers
|
|
||||||
if supportedVideoCodecs[container]["h264"] <> invalid
|
|
||||||
for each profile in supportedVideoCodecs[container]["h264"]
|
|
||||||
videoProfiles.push(profile)
|
|
||||||
end for
|
|
||||||
exit for
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
|
end for
|
||||||
|
end for
|
||||||
|
|
||||||
|
h264LevelString = h264Mp4LevelSupported
|
||||||
|
if h264TsLevelSupported > h264Mp4LevelSupported
|
||||||
|
h264LevelString = h264TsLevelSupported
|
||||||
|
end if
|
||||||
|
' convert to string
|
||||||
|
h264LevelString = h264LevelString.ToStr()
|
||||||
|
' remove decimals
|
||||||
|
h264LevelString = removeDecimals(h264LevelString)
|
||||||
|
|
||||||
|
|
||||||
codecProfileArray = {
|
codecProfileArray = {
|
||||||
"Type": "Video",
|
"Type": "Video",
|
||||||
|
@ -452,13 +449,13 @@ function getDeviceProfile() as object
|
||||||
{
|
{
|
||||||
"Condition": "EqualsAny",
|
"Condition": "EqualsAny",
|
||||||
"Property": "VideoProfile",
|
"Property": "VideoProfile",
|
||||||
"Value": videoProfiles.join("|"),
|
"Value": h264AssProfiles.Keys().join("|"),
|
||||||
"IsRequired": false
|
"IsRequired": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Condition": "EqualsAny",
|
"Condition": "EqualsAny",
|
||||||
"Property": "VideoRangeType",
|
"Property": "VideoRangeType",
|
||||||
"Value": "SDR",
|
"Value": h264VideoRangeTypes,
|
||||||
"IsRequired": false
|
"IsRequired": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -474,19 +471,16 @@ function getDeviceProfile() as object
|
||||||
codecProfileArray.Conditions.push(bitRateArray)
|
codecProfileArray.Conditions.push(bitRateArray)
|
||||||
end if
|
end if
|
||||||
deviceProfile.CodecProfiles.push(codecProfileArray)
|
deviceProfile.CodecProfiles.push(codecProfileArray)
|
||||||
end if
|
|
||||||
|
|
||||||
if addMpeg2Profile
|
' MPEG2
|
||||||
|
if addMpeg2
|
||||||
mpeg2Levels = []
|
mpeg2Levels = []
|
||||||
for each container in transContainers
|
for each container in profileSupport
|
||||||
if supportedVideoCodecs[container] <> invalid
|
for each level in profileSupport[container]["mpeg2"]
|
||||||
if supportedVideoCodecs[container]["mpeg2"] <> invalid
|
if mpeg2Levels[level] = invalid
|
||||||
for each level in supportedVideoCodecs[container]["mpeg2"]
|
|
||||||
mpeg2Levels.push(level)
|
mpeg2Levels.push(level)
|
||||||
|
end if
|
||||||
end for
|
end for
|
||||||
if mpeg2Levels.count() > 0 then exit for
|
|
||||||
end if
|
|
||||||
end if
|
|
||||||
end for
|
end for
|
||||||
|
|
||||||
codecProfileArray = {
|
codecProfileArray = {
|
||||||
|
@ -508,33 +502,35 @@ function getDeviceProfile() as object
|
||||||
deviceProfile.CodecProfiles.push(codecProfileArray)
|
deviceProfile.CodecProfiles.push(codecProfileArray)
|
||||||
end if
|
end if
|
||||||
|
|
||||||
if addAv1Profile
|
if addAv1
|
||||||
' determine highest level supported
|
av1Mp4LevelSupported = 0.0
|
||||||
av1HighestLevel = 5.1
|
av1TsLevelSupported = 0.0
|
||||||
av1HighestLevelSupported = 0.0
|
av1AssProfiles = []
|
||||||
for each container in transContainers
|
av1HighestLevel = 0.0
|
||||||
for each profile in hevcProfiles
|
for each container in profileSupport
|
||||||
for each level in supportedVideoCodecs[container]["av1"][profile]
|
for each profile in profileSupport[container]["av1"]
|
||||||
|
av1AssProfiles.AddReplace(profile, true)
|
||||||
|
for each level in profileSupport[container]["av1"][profile]
|
||||||
levelFloat = level.ToFloat()
|
levelFloat = level.ToFloat()
|
||||||
if levelFloat > av1HighestLevelSupported
|
if container = "mp4"
|
||||||
av1HighestLevelSupported = levelFloat
|
if levelFloat > av1Mp4LevelSupported
|
||||||
|
av1Mp4LevelSupported = levelFloat
|
||||||
|
end if
|
||||||
|
else if container = "ts"
|
||||||
|
if levelFloat > av1TsLevelSupported
|
||||||
|
av1TsLevelSupported = levelFloat
|
||||||
|
end if
|
||||||
end if
|
end if
|
||||||
if av1HighestLevelSupported = av1HighestLevel then exit for
|
|
||||||
end for
|
end for
|
||||||
if av1HighestLevelSupported = av1HighestLevel then exit for
|
|
||||||
end for
|
end for
|
||||||
if av1HighestLevelSupported = av1HighestLevel then exit for
|
|
||||||
end for
|
end for
|
||||||
|
|
||||||
videoProfiles = []
|
av1HighestLevel = av1Mp4LevelSupported
|
||||||
for each container in transContainers
|
if av1TsLevelSupported > av1Mp4LevelSupported
|
||||||
if supportedVideoCodecs[container]["av1"] <> invalid
|
av1HighestLevel = av1TsLevelSupported
|
||||||
for each profile in supportedVideoCodecs[container]["av1"]
|
|
||||||
videoProfiles.push(profile)
|
|
||||||
end for
|
|
||||||
exit for
|
|
||||||
end if
|
end if
|
||||||
end for
|
|
||||||
|
|
||||||
|
|
||||||
codecProfileArray = {
|
codecProfileArray = {
|
||||||
"Type": "Video",
|
"Type": "Video",
|
||||||
|
@ -543,7 +539,7 @@ function getDeviceProfile() as object
|
||||||
{
|
{
|
||||||
"Condition": "EqualsAny",
|
"Condition": "EqualsAny",
|
||||||
"Property": "VideoProfile",
|
"Property": "VideoProfile",
|
||||||
"Value": videoProfiles.join("|"),
|
"Value": av1AssProfiles.Keys().join("|"),
|
||||||
"IsRequired": false
|
"IsRequired": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -555,7 +551,7 @@ function getDeviceProfile() as object
|
||||||
{
|
{
|
||||||
"Condition": "LessThanEqual",
|
"Condition": "LessThanEqual",
|
||||||
"Property": "VideoLevel",
|
"Property": "VideoLevel",
|
||||||
"Value": (120 * av1HighestLevelSupported).ToStr(),
|
"Value": (120 * av1HighestLevel).ToStr(),
|
||||||
"IsRequired": false
|
"IsRequired": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -567,39 +563,39 @@ function getDeviceProfile() as object
|
||||||
deviceProfile.CodecProfiles.push(codecProfileArray)
|
deviceProfile.CodecProfiles.push(codecProfileArray)
|
||||||
end if
|
end if
|
||||||
|
|
||||||
if addHevcProfile
|
if addHevc
|
||||||
' determine highest level supported
|
hevcMp4LevelSupported = 0.0
|
||||||
hevcHighestLevel = 5.1
|
hevcTsLevelSupported = 0.0
|
||||||
hevcHighestLevelSupported = 0.0
|
hevcAssProfiles = {}
|
||||||
for each container in transContainers
|
hevcHighestLevel = 0.0
|
||||||
for each profile in hevcProfiles
|
for each container in profileSupport
|
||||||
for each level in supportedVideoCodecs[container]["hevc"][profile]
|
for each profile in profileSupport[container]["hevc"]
|
||||||
|
hevcAssProfiles.AddReplace(profile, true)
|
||||||
|
for each level in profileSupport[container]["hevc"][profile]
|
||||||
levelFloat = level.ToFloat()
|
levelFloat = level.ToFloat()
|
||||||
if levelFloat > hevcHighestLevelSupported
|
if container = "mp4"
|
||||||
hevcHighestLevelSupported = levelFloat
|
if levelFloat > hevcMp4LevelSupported
|
||||||
|
hevcMp4LevelSupported = levelFloat
|
||||||
|
end if
|
||||||
|
else if container = "ts"
|
||||||
|
if levelFloat > hevcTsLevelSupported
|
||||||
|
hevcTsLevelSupported = levelFloat
|
||||||
|
end if
|
||||||
end if
|
end if
|
||||||
if hevcHighestLevelSupported = hevcHighestLevel then exit for
|
|
||||||
end for
|
end for
|
||||||
if hevcHighestLevelSupported = hevcHighestLevel then exit for
|
|
||||||
end for
|
end for
|
||||||
if hevcHighestLevelSupported = hevcHighestLevel then exit for
|
|
||||||
end for
|
end for
|
||||||
|
|
||||||
|
hevcHighestLevel = hevcMp4LevelSupported
|
||||||
|
if hevcTsLevelSupported > hevcMp4LevelSupported
|
||||||
|
hevcHighestLevel = hevcTsLevelSupported
|
||||||
|
end if
|
||||||
|
|
||||||
hevcLevelString = "120"
|
hevcLevelString = "120"
|
||||||
if hevcHighestLevelSupported = 5.1
|
if hevcHighestLevel = 5.1
|
||||||
hevcLevelString = "153"
|
hevcLevelString = "153"
|
||||||
end if
|
end if
|
||||||
|
|
||||||
videoProfiles = []
|
|
||||||
for each container in transContainers
|
|
||||||
if supportedVideoCodecs[container]["hevc"] <> invalid
|
|
||||||
for each profile in supportedVideoCodecs[container]["hevc"]
|
|
||||||
videoProfiles.push(profile)
|
|
||||||
end for
|
|
||||||
exit for
|
|
||||||
end if
|
|
||||||
end for
|
|
||||||
|
|
||||||
codecProfileArray = {
|
codecProfileArray = {
|
||||||
"Type": "Video",
|
"Type": "Video",
|
||||||
"Codec": "hevc",
|
"Codec": "hevc",
|
||||||
|
@ -613,7 +609,7 @@ function getDeviceProfile() as object
|
||||||
{
|
{
|
||||||
"Condition": "EqualsAny",
|
"Condition": "EqualsAny",
|
||||||
"Property": "VideoProfile",
|
"Property": "VideoProfile",
|
||||||
"Value": videoProfiles.join("|"),
|
"Value": profileSupport["ts"]["hevc"].Keys().join("|"),
|
||||||
"IsRequired": false
|
"IsRequired": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -630,6 +626,7 @@ function getDeviceProfile() as object
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
bitRateArray = GetBitRateLimit("h265")
|
bitRateArray = GetBitRateLimit("h265")
|
||||||
if bitRateArray.count() > 0
|
if bitRateArray.count() > 0
|
||||||
codecProfileArray.Conditions.push(bitRateArray)
|
codecProfileArray.Conditions.push(bitRateArray)
|
||||||
|
@ -637,16 +634,15 @@ function getDeviceProfile() as object
|
||||||
deviceProfile.CodecProfiles.push(codecProfileArray)
|
deviceProfile.CodecProfiles.push(codecProfileArray)
|
||||||
end if
|
end if
|
||||||
|
|
||||||
if addVp9Profile
|
if addVp9
|
||||||
videoProfiles = []
|
vp9Profiles = []
|
||||||
for each container in transContainers
|
for each container in profileSupport
|
||||||
if supportedVideoCodecs[container]["vp9"] <> invalid
|
for each profile in profileSupport[container]["vp9"]
|
||||||
for each profile in supportedVideoCodecs[container]["vp9"]
|
if vp9Profiles[profile] = invalid
|
||||||
videoProfiles.push(profile)
|
vp9Profiles.push(profile)
|
||||||
end for
|
|
||||||
exit for
|
|
||||||
end if
|
end if
|
||||||
end for
|
end for
|
||||||
|
end for
|
||||||
|
|
||||||
codecProfileArray = {
|
codecProfileArray = {
|
||||||
"Type": "Video",
|
"Type": "Video",
|
||||||
|
@ -654,8 +650,8 @@ function getDeviceProfile() as object
|
||||||
"Conditions": [
|
"Conditions": [
|
||||||
{
|
{
|
||||||
"Condition": "EqualsAny",
|
"Condition": "EqualsAny",
|
||||||
"Property": "VideoProfile",
|
"Property": "VideoLevel",
|
||||||
"Value": videoProfiles.join("|"),
|
"Value": vp9Profiles.join("|"),
|
||||||
"IsRequired": false
|
"IsRequired": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -666,6 +662,7 @@ function getDeviceProfile() as object
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
bitRateArray = GetBitRateLimit("vp9")
|
bitRateArray = GetBitRateLimit("vp9")
|
||||||
if bitRateArray.count() > 0
|
if bitRateArray.count() > 0
|
||||||
codecProfileArray.Conditions.push(bitRateArray)
|
codecProfileArray.Conditions.push(bitRateArray)
|
||||||
|
@ -834,3 +831,35 @@ function GetBitRateLimit(codec as string) as object
|
||||||
end if
|
end if
|
||||||
return {}
|
return {}
|
||||||
end function
|
end function
|
||||||
|
|
||||||
|
' Recieves and returns an assArray of supported profiles and levels for each video codec
|
||||||
|
function updateProfileArray(profileArray as object, videoCodec as string, videoProfile as string, profileLevel = "" as string) as object
|
||||||
|
' validate params
|
||||||
|
if profileArray = invalid then return {}
|
||||||
|
if videoCodec = "" or videoProfile = "" then return profileArray
|
||||||
|
|
||||||
|
if profileArray[videoCodec] = invalid
|
||||||
|
profileArray[videoCodec] = {}
|
||||||
|
end if
|
||||||
|
|
||||||
|
if profileArray[videoCodec][videoProfile] = invalid
|
||||||
|
profileArray[videoCodec][videoProfile] = {}
|
||||||
|
end if
|
||||||
|
|
||||||
|
' add profileLevel if a value was provided
|
||||||
|
if profileLevel <> ""
|
||||||
|
if profileArray[videoCodec][videoProfile][profileLevel] = invalid
|
||||||
|
profileArray[videoCodec][videoProfile].AddReplace(profileLevel, true)
|
||||||
|
end if
|
||||||
|
end if
|
||||||
|
|
||||||
|
' profileSupport[container][codec][profile][level]
|
||||||
|
return profileArray
|
||||||
|
end function
|
||||||
|
|
||||||
|
' Remove all decimals from a string
|
||||||
|
function removeDecimals(value as string) as string
|
||||||
|
r = CreateObject("roRegex", "\.", "")
|
||||||
|
value = r.ReplaceAll(value, "")
|
||||||
|
return value
|
||||||
|
end function
|
||||||
|
|
Loading…
Reference in New Issue
Block a user