0

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 Answers1

0

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

Aryan Sharma
  • 625
  • 2
  • 9
  • 24
  • From my implementation it stiull has teh blip –  Dec 24 '18 at 17:28
  • But i think its just because our asset times are different. So I guess it may work for others –  Dec 24 '18 at 17:29