Problem when attempting to loop AVPlayer (userCapturedVideo) seamlessly

雨燕双飞 提交于 2019-12-02 18:13:34

问题


I have been looking around for a while on how to correctly accomplish this. I have looked here and here. And have used the top answer here, to try and accomplish this however for me the recorded video does not ever even begin to loop. The first frame shows up but does not play the video, thus I am wondering what's wrong.

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    if (error != nil) {
        print("Error recording movie11: \(error!.localizedDescription)")
    } else {
        isSettingThumbnail = false

        let videoRecorded = outputURL! as URL
        playRecordedVideo(video: videoRecorded)

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

The function used in the above method is bellow.

    func playRecordedVideo(video: URL) {
    thumbImage = nil
    playerQueue = AVQueuePlayer(playerItem: AVPlayerItem(url: video))

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

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

    playerItem1 = AVPlayerItem(url: video)

    playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem1)
    self.playerQueue?.play()
}

I have attempted the following in the function above:

        var num = 0
    if num == 0 {
        self.playerQueue?.play()
        num+=1
    } else {
        NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.playerQueue.currentItem, queue: nil, using: { (_) in
            DispatchQueue.main.async {
                self.playerQueue.seek(to: CMTime.zero)
                self.playerQueue.play()
            }
        })

    }

This however just causes the video to not even play when it comes up.

The goal is to prevent the "gap" you see when the video is looped

Update:

Ok so actually the variable num should be outside of the function which then would make the NS code run but that ends up freezing the view like it did before.

Update 2:

I have not been able to find a solution to this as of yet. But what is for certain is that

`            NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: self.playerQueue.currentItem, queue: nil, using: { (_) in
                DispatchQueue.main.async {
                    self.playerQueue.seek(to: CMTime.zero)
                    self.playerQueue.play()
                }
            })

` Causes the video to not even loop. Any reason as to why this happens?


回答1:


I did the same thing a few years back using this piece of code:

var player: AVPlayer!
var playerLayer: AVPlayerLayer!

private func playVideo(name: String) {
    guard let path = Bundle.main.path(forResource: name, ofType:"mp4") else { return }
    player = AVPlayer(url: NSURL(fileURLWithPath: path) as URL)
    playerLayer = AVPlayerLayer(player: player)
    self.playerLayer.frame = SOME_BOUNDS
    self.player!.play()
    NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(note:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
}

@objc func playerDidFinishPlaying(note: NSNotification) {
    print("Video Finished")
    self.playerLayer.removeFromSuperlayer()
    playVideo(name: "SOME_NAME")
}

Hope this points you to your desired functionality



来源:https://stackoverflow.com/questions/53717624/problem-when-attempting-to-loop-avplayer-usercapturedvideo-seamlessly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!