From d2e73021b1e4fa2973e330c9e48219565282691b Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Sat, 30 May 2026 20:15:37 +0200 Subject: [PATCH] fix(mpv): apply carried audio/subtitle track after file load Setting sid/aid before loadfile does not stick for embedded tracks, so a carried-over subtitle was silently dropped on a freshly loaded episode. Apply the initial audio/subtitle selection in the MPV_EVENT_FILE_LOADED handler (after tracks are enumerated) for embedded and external alike, on both iOS and Android. --- .../modules/mpvplayer/MPVLayerRenderer.kt | 16 +++++++++---- modules/mpv-player/ios/MPVLayerRenderer.swift | 23 ++++++++++++------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/modules/mpv-player/android/src/main/java/expo/modules/mpvplayer/MPVLayerRenderer.kt b/modules/mpv-player/android/src/main/java/expo/modules/mpvplayer/MPVLayerRenderer.kt index 98debe637..ff45438eb 100644 --- a/modules/mpv-player/android/src/main/java/expo/modules/mpvplayer/MPVLayerRenderer.kt +++ b/modules/mpv-player/android/src/main/java/expo/modules/mpvplayer/MPVLayerRenderer.kt @@ -684,11 +684,19 @@ class MPVLayerRenderer(private val context: Context) : MPVLib.EventObserver { MPVLib.command(arrayOf("sub-add", subUrl, "auto")) } pendingExternalSubtitles = emptyList() - - // Set subtitle after external subs are added - initialSubtitleId?.let { setSubtitleTrack(it) } ?: disableSubtitles() } - + + // Apply the initial audio/subtitle selection now that the file's + // tracks are enumerated. Setting sid/aid before `loadfile` does not + // reliably stick for embedded tracks (the selection is silently + // dropped), so we (re)apply here for embedded and external alike. + // This is what makes a carried-over subtitle show up on the next + // episode without a manual re-selection. + if (initialAudioId != null && initialAudioId > 0) { + setAudioTrack(initialAudioId) + } + initialSubtitleId?.let { setSubtitleTrack(it) } ?: disableSubtitles() + if (!isReadyToSeek) { isReadyToSeek = true mainHandler.post { delegate?.onReadyToSeek() } diff --git a/modules/mpv-player/ios/MPVLayerRenderer.swift b/modules/mpv-player/ios/MPVLayerRenderer.swift index 8c43b9e4e..ebd072f7c 100644 --- a/modules/mpv-player/ios/MPVLayerRenderer.swift +++ b/modules/mpv-player/ios/MPVLayerRenderer.swift @@ -485,8 +485,7 @@ final class MPVLayerRenderer { switch event.event_id { case MPV_EVENT_FILE_LOADED: // Add external subtitles now that the file is loaded - let hadExternalSubs = !pendingExternalSubtitles.isEmpty - if hadExternalSubs, let handle = mpv { + if !pendingExternalSubtitles.isEmpty, let handle = mpv { for (index, subUrl) in pendingExternalSubtitles.enumerated() { print("🔧 Adding external subtitle [\(index)]: \(subUrl)") // Use commandSync to ensure subs are added in exact order (not async) @@ -494,12 +493,20 @@ final class MPVLayerRenderer { commandSync(handle, ["sub-add", subUrl, "auto"]) } pendingExternalSubtitles = [] - // Set subtitle after external subs are added - if let subId = initialSubtitleId { - setSubtitleTrack(subId) - } else { - disableSubtitles() - } + } + // Apply the initial audio/subtitle selection now that the file's + // tracks are enumerated. Setting sid/aid before `loadfile` does not + // reliably stick for embedded tracks (the selection is silently + // dropped), so we (re)apply here for embedded and external alike. + // This is what makes a carried-over subtitle show up on the next + // episode without a manual re-selection. + if let audioId = initialAudioId, audioId > 0 { + setAudioTrack(audioId) + } + if let subId = initialSubtitleId { + setSubtitleTrack(subId) + } else { + disableSubtitles() } if !isReadyToSeek { isReadyToSeek = true