From b9e7324a1237eb60c64efb523b45f1d59e891ea9 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Tue, 19 Nov 2024 17:49:44 -0500 Subject: [PATCH] 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