在播放来自UIImagePickerController的视频之前,AVPlayer不会播放视频 [英] AVPlayer doesn't play video until a video from UIImagePickerController is played

查看:149
本文介绍了在播放来自UIImagePickerController的视频之前,AVPlayer不会播放视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,我在这里没有看到过这样的帖子.我有一个AVPlayerViewController,可以播放 Firebase数据库(而不是存储)上的基于视频的视频.该视频可以按照我想要的方式完美播放,但是只有在我观看了在应用程序其他位置的UIImagePickerController中单击的视频后,该视频才可以播放.

I'm having a problem which I haven't seen a post like it on here. I have an AVPlayerViewController which plays a video-based off the path from my Firebase Database (not Storage). The video plays perfectly as I want it to, but only once I watch a video that is clicked on in the UIImagePickerController elsewhere in the app.

因此,例如,AVPlayer将显示黑色背景(应用程序中的所有AVPlayer's都会出现此背景),但当我观看UIImagePickerController中的与任何视频无关的视频时除外其他观点.我不知道从哪里开始.感谢您的所有帮助和建议!

So for example, the AVPlayer will show a black background (this occurs with all of the AVPlayer's in the app), except for when I watch a video from the UIImagePickerController which has nothing to do with any of the other views. I have no clue where to start with this. I appreciate all your help and suggestions!

这是我的AVPlayerViewController的示例代码:

import UIKit
import AVFoundation
import AVKit

class VideoView: UIViewController {

private var videoURL: URL
var player: AVPlayer?
var playerController : AVPlayerViewController?

init(videoURL: URL) {
    self.videoURL = videoURL
    super.init(nibName: nil, bundle: nil)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.gray
    player = AVPlayer(url: videoURL)
    playerController = AVPlayerViewController()

    guard player != nil && playerController != nil else {
        return
    }
    playerController!.showsPlaybackControls = false

    playerController!.player = player!
    self.addChild(playerController!)
    self.view.addSubview(playerController!.view)
    playerController!.view.frame = view.frame
    NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.player!.currentItem)

    let cancelButton = UIButton(frame: CGRect(x: 10.0, y: 10.0, width: 30.0, height: 30.0))
    cancelButton.setImage(#imageLiteral(resourceName: "cancel"), for: UIControl.State())
    cancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside)
    view.addSubview(cancelButton)


    // Allow background audio to continue to play
    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
    } catch let error as NSError {
        print(error)
    }

    do {
        try AVAudioSession.sharedInstance().setActive(true)
    } catch let error as NSError {
        print(error)
    }
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    player?.play()
}

@objc func cancel() {
    dismiss(animated: true, completion: nil)
}

@objc fileprivate func playerItemDidReachEnd(_ notification: Notification) {
    if self.player != nil {
        self.player!.seek(to: CMTime.zero)
        self.player!.play()
    }
}

}

推荐答案

问题是,当您的视图出现时,它可能无法播放.要正确处理此问题,您需要对播放器上的KVO进行确认,以确保可以开始播放.

The problem is that when your view appears it might not be ready for playback. What you should do to properly handle this is to KVO on the player to make sure it is ready to play.

在此之前,我已经回答过类似的问题:

I have answered this before here for a similar question:

视频使用HLS视频时,仅在具有AVPlayerViewController和AVPlayer的iOS 13上出现播放问题

playerItem.addObserver(self,
                           forKeyPath: #keyPath(AVPlayerItem.status),
                           options: [.old, .new],
                           context: &playerItemContext)


override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?,
                           change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?) {

    // Only handle observations for the playerItemContext
    guard context == &playerItemContext else {
        super.observeValue(forKeyPath: keyPath,
                           of: object,
                           change: change,
                           context: context)
        return
    }

    if keyPath == #keyPath(AVPlayerItem.status) {
        let status: AVPlayerItemStatus
        if let statusNumber = change?[.newKey] as? NSNumber {
            status = AVPlayerItemStatus(rawValue: statusNumber.intValue)!
        } else {
            status = .unknown
        }

        // Switch over status value
        switch status {
        case .readyToPlay:
            // Player item is ready to play.
        case .failed:
            // Player item failed. See error.
        case .unknown:
            // Player item is not yet ready.
        }
    }
}

您可以在以下位置从Apple找到有关它的文档: https://developer.apple .com/documentation/avfoundation/media_assets_playback_and_editing/responding_to_playback_state_changes

You can find documentation about it from Apple here: https://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/responding_to_playback_state_changes

另一个用法示例在这里:

Another example of usage is here:

        playerItem?.observe(\AVPlayerItem.status, options: [.new, .initial]) { [weak self] item, _ in
            guard let self = self else { return }
            switch status {
        case .readyToPlay:
            // Player item is ready to play.
        case .failed:
            // Player item failed. See error.
        case .unknown:
            // Player item is not yet ready.
        }

这篇关于在播放来自UIImagePickerController的视频之前,AVPlayer不会播放视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆