diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0cbf868a..98e5ae7f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -789,7 +789,7 @@ repositoryURL = "https://github.com/edde746/MPVKit"; requirement = { kind = revision; - revision = 42dcc3123000361d0be54fbaec981043b77e1e05; + revision = 8da57fe1d3dd82524ea4b2ef6ef8b2d692ada395; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index af20df59..2f9a3501 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -40,7 +40,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/edde746/MPVKit", "state" : { - "revision" : "42dcc3123000361d0be54fbaec981043b77e1e05" + "revision" : "8da57fe1d3dd82524ea4b2ef6ef8b2d692ada395" } }, { diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved index af20df59..2f9a3501 100644 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -40,7 +40,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/edde746/MPVKit", "state" : { - "revision" : "42dcc3123000361d0be54fbaec981043b77e1e05" + "revision" : "8da57fe1d3dd82524ea4b2ef6ef8b2d692ada395" } }, { diff --git a/ios/Runner/MpvPlayer/MpvPlayerPlugin.swift b/ios/Runner/MpvPlayer/MpvPlayerPlugin.swift index 0b0b1b47..9f7d135b 100644 --- a/ios/Runner/MpvPlayer/MpvPlayerPlugin.swift +++ b/ios/Runner/MpvPlayer/MpvPlayerPlugin.swift @@ -188,6 +188,7 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPluginS guard let playerCore = playerCore else { return nil } guard let pip = ensurePipController() else { return nil } pendingInlineRestoreAfterPip = false + playerCore.setPipSubtitleCompositing(true) playerCore.isPipStarting = true pip.syncTimebase(currentTime: playerCore.timePos, isPlaying: !playerCore.isPaused) pip.invalidatePlaybackState() @@ -232,6 +233,7 @@ class MpvPlayerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, MpvPluginS /// Unified cleanup for all PiP exit paths private func cleanupPip(notify: Bool, pause: Bool = false) { + playerCore?.setPipSubtitleCompositing(false) playerCore?.isPipStarting = false playerCore?.isPipActive = false isManualPipRequest = false diff --git a/shared/apple/MpvPlayer/MpvPlayerCoreBase.swift b/shared/apple/MpvPlayer/MpvPlayerCoreBase.swift index d7cb401c..69c2737e 100644 --- a/shared/apple/MpvPlayer/MpvPlayerCoreBase.swift +++ b/shared/apple/MpvPlayer/MpvPlayerCoreBase.swift @@ -426,6 +426,22 @@ class MpvPlayerCoreBase: NSObject { } } + /// PiP presents the AVSampleBufferDisplayLayer directly, so subtitles must + /// be composited into the video samples instead of the inline OSD layer. + func setPipSubtitleCompositing(_ enabled: Bool) { + #if os(iOS) + let value = enabled ? "yes" : "no" + setRawStringPropertyAsync("avfoundation-pip-composite-osd", value: value) { result in + if case .failure(let error) = result { + print( + "[MpvPlayerCore] Failed to set PiP subtitle compositing " + + "to \(value): \(error.localizedDescription)" + ) + } + } + #endif + } + func getPropertyAsync(_ name: String, completion: @escaping (Result) -> Void) { guard let mpv else { completion(.success(nil)) @@ -611,7 +627,7 @@ class MpvPlayerCoreBase: NSObject { private func isManagedRendererProperty(_ name: String) -> Bool { name == "vo" || name == "wid" || name == "gpu-api" || name == "gpu-context" - || name == "avfoundation-composite-osd" + || name == "avfoundation-composite-osd" || name == "avfoundation-pip-composite-osd" } private func updateVideoGravityIfNeeded(name: String, value: String) {