尝试无缝循环 AVPlayer (userCapturedVideo) 时出现问题
Problem when attempting to loop AVPlayer (userCapturedVideo) seamlessly
我已经研究了一段时间如何正确地完成这个任务。我查看了 here and here. And have used the top answer here,尝试完成此操作,但对我来说,录制的视频甚至都没有开始循环播放。第一帧出现了,但没有播放视频,所以我想知道哪里出了问题。
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()
}
}
}
}
上述方法中使用的函数如下。
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()
}
我在上面的函数中尝试了以下操作:
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()
}
})
}
然而,这只会导致视频出现时无法播放。
目标是防止您在循环播放视频时看到 "gap"
更新:
好吧,实际上变量 num 应该在函数之外,这将使 NS 代码成为 运行 但最终会像以前一样冻结视图。
更新二:
到目前为止,我还没有找到解决办法。但可以肯定的是
` 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()
}
})
`
导致视频甚至不循环播放。为什么会发生这种情况?
几年前我用这段代码做了同样的事情:
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")
}
希望这能让您找到所需的功能
我已经研究了一段时间如何正确地完成这个任务。我查看了 here and here. And have used the top answer here,尝试完成此操作,但对我来说,录制的视频甚至都没有开始循环播放。第一帧出现了,但没有播放视频,所以我想知道哪里出了问题。
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()
}
}
}
}
上述方法中使用的函数如下。
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()
}
我在上面的函数中尝试了以下操作:
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()
}
})
}
然而,这只会导致视频出现时无法播放。
目标是防止您在循环播放视频时看到 "gap"
更新:
好吧,实际上变量 num 应该在函数之外,这将使 NS 代码成为 运行 但最终会像以前一样冻结视图。
更新二:
到目前为止,我还没有找到解决办法。但可以肯定的是
` 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()
}
})
` 导致视频甚至不循环播放。为什么会发生这种情况?
几年前我用这段代码做了同样的事情:
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")
}
希望这能让您找到所需的功能