Как воспроизводить videoPreviewLayer только когда элемент AVPlayer имеет значение «.readyToPlay» - PullRequest
0 голосов
/ 08 декабря 2018

Я пытаюсь достичь того же, что и Snapchat.То есть, когда пользователь заканчивает снимать видео и попадает в режим предварительного просмотра, видео вроде как замораживается на секунду или около того, пока видео не будет готово к воспроизведению, в этот момент оно начинает воспроизводиться.Я пытаюсь достичь того же.Ниже я попробовал сильфон,

            while playerItem1.status == .unknown {
            print("1111121232432431243123241432143243214324321")
            if playerItem1.status == .readyToPlay {

                playerQueue = AVQueuePlayer(playerItem: playerItem1)
                self.playerQueue?.play()

                playerLayer = AVPlayerLayer(player: playerQueue)
                playerLayer.frame = (camPreview?.bounds)!
                playerLayer?.layoutIfNeeded()
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

                camPreview?.layer.insertSublayer(playerLayer, above: previewLayer)

                playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem1)
            }
        }

, однако это привело к краху кода, потому что, кажется, он никогда не заканчивается.Что я не понимаю и учитывая, что в какой-то момент статус должен стать .readyToPlay, поскольку, если я оставлю это в покое, он сделает это.

В основном я хотел бы сделать это, потому что в настоящее время, когда вы отпускаете кнопку захвата в моем коде, экран замирает, затем он переходит.Я хочу, чтобы оно заморозило видео, а не экран захвата.

    extension ViewController: AVCaptureFileOutputRecordingDelegate {
    //MARK: - Protocal stubs
    func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) { print("bruh? MMMM") }

    func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    }

    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

        if (error != nil) {
            print("Error recording movie11: \(error!.localizedDescription)")
        } else {
            newViewVideoPlayback()

            switchIcon.isHidden = true
            switchWhiteUI.isHidden = true
            switchCamButton.isHidden = true
            camWhiteLine.isHidden = true

//            let videoRecorded = outputURL! as URL
//            playerItem1 = AVPlayerItem(url: videoRecorded)


            if !captureSession.isRunning {
                DispatchQueue.global(qos: .background).async {
                    self.startRunningCaptureSession()
                }
            }
        }

    }
    let videoRecorded = outputURL! as URL
    playerItem1 = AVPlayerItem(url: videoRecorded)

    playerItem1.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: AVPlayerItem.Status
            if let statusNumber = change?[.newKey] as? NSNumber {
                status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
            } else {
                status = .unknown
            }

            // Switch over status value
            switch status {
            case .readyToPlay:
            // Player item is ready to play.

                playerQueue = AVQueuePlayer(playerItem: playerItem1)
                self.playerQueue?.play()

                playerLayer = AVPlayerLayer(player: playerQueue)
                playerLayer.frame = (camPreview?.bounds)!
                playerLayer?.layoutIfNeeded()
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

                camPreview?.layer.insertSublayer(playerLayer, above: previewLayer)

                playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem1)

            case .failed: break
            // Player item failed. See error.
            case .unknown: break
                // Player item is not yet ready.
            }
        }
    }

}

1 Ответ

0 голосов
/ 08 декабря 2018

Из Документы

Когда элемент проигрывателя создан, его статус AVPlayerItem.Status.unknown, то есть его носитель не был загружен и еще не был помещен в очередь.для воспроизведения.Связывание элемента проигрывателя с AVPlayer немедленно начинает ставить в очередь медиа-элемент и готовить его к воспроизведению.Когда медиа-элемент проигрывателя загружен и готов к использованию, его статус изменится на AVPlayerItem.Status.readyToPlay.Вы можете наблюдать это изменение с помощью наблюдения значения ключа.

Поэтому вам нужно прослушивать состояние, а не делать цикл while, который может перегружать систему до тех пор, пока состояние не изменится. Это также в Документах.

private var playerItemContext = 0
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.
        }
    }
}

extension ViewController: AVCaptureFileOutputRecordingDelegate {
    //MARK: - Protocal stubs
    func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) { print("bruh? MMMM") }

    func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    }

    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

        if (error != nil) {
            print("Error recording movie11: \(error!.localizedDescription)")
        } else {
            newViewVideoPlayback()

            switchIcon.isHidden = true
            switchWhiteUI.isHidden = true
            switchCamButton.isHidden = true
            camWhiteLine.isHidden = true

             let videoRecorded = outputURL! as URL
             playerItem1 = AVPlayerItem(url: videoRecorded)
              playerItem1.addObserver(self,
              forKeyPath: #keyPath(AVPlayerItem.status),
              options: [.old, .new],
              context: &playerItemContext) 
              playerQueue = AVQueuePlayer(playerItem: playerItem1)

            if !captureSession.isRunning {
                DispatchQueue.global(qos: .background).async {
                    self.startRunningCaptureSession()
                }
            }
        } 
    } 
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: AVPlayerItem.Status
            if let statusNumber = change?[.newKey] as? NSNumber {
                status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
            } else {
                status = .unknown
            }

            // Switch over status value
            switch status {
            case .readyToPlay: 
                playerLayer = AVPlayerLayer(player: playerQueue)
                playerLayer.frame = (camPreview?.bounds)!
                playerLayer?.layoutIfNeeded()
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill 
                camPreview?.layer.insertSublayer(playerLayer, above: previewLayer) 
                playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem1) 
                // Player item is ready to play. 
                self.playerQueue?.play(
            case .failed: break
            // Player item failed. See error.
            case .unknown: break
                // Player item is not yet ready.
            }
        }
   } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...