Flutter iOS «Картинка в картинке» не отображается, когда приложение переходит в фоновый режим (работает только через кноIOS

Программируем под IOS
Ответить
Anonymous
 Flutter iOS «Картинка в картинке» не отображается, когда приложение переходит в фоновый режим (работает только через кно

Сообщение Anonymous »

Я создаю приложение для потоковой передачи видео OTT, используя Flutter и пакет video_player.
Я хочу реализовать функцию «Картинка в картинке» (PiP) на iOS.
Flutter не обеспечивает встроенную поддержку PiP напрямую для iOS, поэтому я реализовал ее с использованием собственного кода Swift через собственный плагин.
Проблема, с которой я сталкиваюсь, заключается в следующем:
Когда я вручную нажимаю на свой собственный плагин Кнопка PiP, PiP запускается успешно и работает нормально.
Но когда я помещаю приложение в фоновый режим (кнопка «Домой» / прокручиваю вверх) и пытаюсь запустить PiP автоматически, PiP не появляется — хотя кажется, что он запускается внутри.
Это мой IosPipManager(swift)
import Foundation
import AVKit
import Flutter
публичный класс IosPipManager: NSObject, FlutterPlugin {
частный var pipController: AVPictureInPictureController?
частный var playerLayer: AVPlayerLayer?
частный var MethodChannel: FlutterMethodChannel?

Код: Выделить всё

public static func register(with registrar: FlutterPluginRegistrar) {
let instance = IosPipManager()
let channel = FlutterMethodChannel(name: "ios_pip_manager", binaryMessenger: registrar.messenger())
instance.methodChannel = channel
registrar.addMethodCallDelegate(instance, channel: channel)

NotificationCenter.default.addObserver(
instance,
selector: #selector(instance.appDidEnterBackground),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
}

@objc private func appDidEnterBackground() {
guard let controller = pipController else {
print("❌ No PiP controller when entering background")
return
}

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if !controller.isPictureInPictureActive {
print("🎥 Starting PiP automatically on background")
controller.startPictureInPicture()
}
}
}

public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "initializePip":
print("🎬 Initializing PiP from Flutter video_player")

guard let viewController = UIApplication.shared.delegate?.window??.rootViewController else {
result(FlutterError(code: "NO_VIEW", message: "No root view controller", details: nil))
return
}

if let playerLayer = findPlayerLayer(in: viewController.view.layer) {
print("✅ Found AVPlayerLayer from Flutter player")
self.playerLayer = playerLayer
self.pipController = AVPictureInPictureController(playerLayer: playerLayer)
result(true)
} else {
print("❌ Couldn’t find AVPlayerLayer from Flutter video player")
result(FlutterError(code: "NO_PLAYER_LAYER", message: "Couldn't find AVPlayerLayer from Flutter video player", details: nil))
}

case "startPip":
print("▶️ startPip called")
startPip(result: result)

case "stopPip":
print("⏹ stopPip called")
stopPip(result: result)

default:
result(FlutterMethodNotImplemented)
}
}

private func startPip(result: @escaping FlutterResult) {
guard let controller = pipController else {
result(FlutterError(code: "NOT_INITIALIZED", message: "PiP controller not initialized", details: nil))
return
}

if !controller.isPictureInPictureActive {
controller.startPictureInPicture()
}
result(true)
}

private func stopPip(result: @escaping FlutterResult) {
guard let controller = pipController else {
result(FlutterError(code: "NOT_INITIALIZED", message: "PiP controller not initialized", details: nil))
return
}

if controller.isPictureInPictureActive {
controller.stopPictureInPicture()
}
result(true)
}

private func findPlayerLayer(in layer: CALayer) ->  AVPlayerLayer? {
if let playerLayer = layer as? AVPlayerLayer {
return playerLayer
}
for sublayer in layer.sublayers ?? [] {
if let found = findPlayerLayer(in: sublayer) {
return found
}
}
return nil
}
расширение IosPipManager: AVPictureInPictureControllerDelegate {
публичная функция imageInPictureControllerDidStartPictureInPicture(_ PictureInPictureController: AVPictureInPictureController) {
methodChannel?.invokeMethod("onPipStarted", аргументы: ноль)

Код: Выделить всё

public func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
methodChannel?.invokeMethod("onPipStopped", arguments: nil)
}

public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
methodChannel?.invokeMethod("onPipError", arguments: error.localizedDescription)
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... d-works-on
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»