Как запустить AVPictureInPicture, когда видео приостановленоIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Как запустить AVPictureInPicture, когда видео приостановлено

Сообщение Anonymous »

У меня есть AVPlayer с AVPictureInPictureController. Воспроизведение видео в приложении и изображения «В картинке» работает, за исключением одной ситуации.
Проблема: я приостанавливаю видео в приложении, и при переключении в фоновый режим не активируется PiP. Что я делаю не так?

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

import UIKit
import AVKit
import AVFoundation

class ViewControllerSec: UIViewController,AVPictureInPictureControllerDelegate {
var pipPlayer: AVPlayer!
var avCanvas : UIView!
var pipCanvas: AVPlayerLayer?
var pipController: AVPictureInPictureController!
var mainViewControler : UIViewController!
var playerItem : AVPlayerItem!
var videoAvasset : AVAsset!

public func link(to parentViewController : UIViewController) {
mainViewControler = parentViewController
setup()
}

@objc func appWillResignActiveNotification(application: UIApplication) {
pipController.startPictureInPicture()
}

private func setupAudio() {
do {
let session = AVAudioSession.sharedInstance()
try session.setCategory(.playback, mode: .moviePlayback)
try session.setActive(true)
} catch {
print("Audio session setup failed: \(error.localizedDescription)")
}
}

@objc func playerItemDidFailToPlayToEnd(_ notification: Notification) {
if let error = notification.userInfo?[AVPlayerItemFailedToPlayToEndTimeErrorKey] as? Error {
print("Failed to play to end: \(error.localizedDescription)")
}
}

func setup() {
setupAudio()
// 1. Set up AVPlayer
guard let videoURL = URL(string: "https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.mp4/.m3u8") else { return }
videoAvasset = AVAsset(url: videoURL)
playerItem = AVPlayerItem(asset: videoAvasset)

addPlayerObservers()
pipPlayer = AVPlayer(playerItem: playerItem)

// 2. Set up AVPlayerLayer
avCanvas = UIView(frame: view.bounds)
pipCanvas = AVPlayerLayer(player: pipPlayer)
guard let pipCanvas else { return }
pipCanvas.frame = avCanvas.bounds
//pipCanvas.videoGravity = .resizeAspectFill

mainViewControler.view.addSubview(avCanvas)
avCanvas.layer.addSublayer(pipCanvas)

// 3.  Set up AVPictureInPictureController
if AVPictureInPictureController.isPictureInPictureSupported() {
pipController = AVPictureInPictureController(playerLayer: pipCanvas)
pipController?.delegate = self
pipController?.canStartPictureInPictureAutomaticallyFromInline = true
}

let playButton = UIButton(frame: CGRect(x: 20, y: 50, width: 100, height: 50))
playButton.setTitle("Play", for: .normal)
playButton.backgroundColor = .blue
playButton.addTarget(self, action: #selector(playTapped), for: .touchUpInside)
mainViewControler.view.addSubview(playButton)

let pauseButton = UIButton(frame: CGRect(x: 140, y: 50, width: 100, height: 50))
pauseButton.setTitle("Pause", for: .normal)
pauseButton.backgroundColor = .red
pauseButton.addTarget(self, action: #selector(pauseTapped), for: .touchUpInside)
mainViewControler.view.addSubview(pauseButton)

let pipButton = UIButton(frame: CGRect(x: 260, y: 50, width: 150, height: 50))
pipButton.setTitle("Start PiP", for: .normal)
pipButton.backgroundColor = .green
pipButton.addTarget(self, action: #selector(startPictureInPicture), for: .touchUpInside)
mainViewControler.view.addSubview(pipButton)
print("Error:\(String(describing: pipPlayer.error?.localizedDescription))")

// Observe application state changes
NotificationCenter.default.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { [weak self] _ in
guard let self = self else { return }
if self.pipPlayer.rate == 0 {
self.pipPlayer.play()
pipController?.startPictureInPicture()
}
}

func addPlayerObservers() {
// Observe player item's status
playerItem?.addObserver(self, forKeyPath: "status", options: [.old, .new], context: nil)

// Observe playback completion
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(_:)), name: .AVPlayerItemDidPlayToEndTime, object: playerItem)
}

// Observe player status changes
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status"  {
if let statusNumber = change?[.newKey] as? NSNumber {
let status = AVPlayer.Status(rawValue: statusNumber.intValue)!
switch status {
case .readyToPlay:
print("Player is ready to play")
case .failed:
print("Player failed: \(String(describing: playerItem?.error))")
case .unknown:
print("Player status is unknown")
@unknown default:
fatalError()
}
}
}
}

@objc func playerDidFinishPlaying(_ notification: Notification) {
print("Video finished playing.")
}

deinit {
// Clean up observers
playerItem?.removeObserver(self, forKeyPath: "status")
NotificationCenter.default.removeObserver(self)
}

@objc func playTapped() {
pipPlayer.play()
}

@objc func pauseTapped() {
pipPlayer.pause()
}

@objc func startPictureInPicture() {
if let pipController = pipController, !pipController.isPictureInPictureActive {
pipController.startPictureInPicture()
}
}

@objc func stopPictureInPicture() {
if let pipController = pipController, pipController.isPictureInPictureActive {
pipController.stopPictureInPicture()
}
}

// MARK: - AVPictureInPictureControllerDelegate Methods

func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("PiP will start")
}

func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("PiP did start")
}

func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
print("Failed to start PiP: \(error.localizedDescription)")
if let underlyingError = (error as NSError).userInfo[NSUnderlyingErrorKey] {
print("Underlying error: \(underlyingError)")
}
}

func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("PiP will stop")
}

func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("PiP did stop")
}
}
Я пытаюсь использовать наблюдателей с appWillResignActiveNotification для активации PiP. Это вызов перед приложением наблюдателяDidEnterBackground, но это также не решает мою проблему, я также пытался начать воспроизведение видео в наблюдателях, а затем активировать PiP с тем же результатом.
Я получаю сообщение об ошибке: Не удалось запустить PiP: Не удалось запустить PiP. начать картинку в картинке.

Подробнее здесь: https://stackoverflow.com/questions/792 ... -is-paused
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как запустить AVPictureInPicture, когда видео приостановлено
    Anonymous » » в форуме IOS
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Как запустить AVPictureInPicture, когда видео приостановлено
    Anonymous » » в форуме IOS
    0 Ответы
    18 Просмотры
    Последнее сообщение Anonymous
  • Как определить, было ли видео HTML5 приостановлено для буферизации?
    Anonymous » » в форуме Html
    0 Ответы
    24 Просмотры
    Последнее сообщение Anonymous
  • Видео приостановлено на монтировании страницы, несмотря на автоза
    Anonymous » » в форуме Javascript
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous
  • Мое приложение приостановлено игровой консолью для нарушения товарных знаков [закрыто]
    Anonymous » » в форуме Android
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous

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