Когда цикл AVPlayerLooper зацикливается, возникает всплеск (быстрая задержка)
Вот моя проблема: у меня есть контроллер вида камеры, где я снимаю видео и делаю воспроизведение видео. Съемка видео прекрасно работает, однако, когда я начинаю воспроизведение, оно воспроизводится неравномерно. Я использую AVPlayerLooper и AVQueuePlayer, когда он повторяется, есть небольшая задержка при повторении следующего воспроизведения. Есть всплывающее окно, потому что это показывает мой фоновый слой (слой позади воспроизведения playerLayer). Фон устанавливается в качестве первого кадра видео, поэтому блик не отображается как фон VC, но был бы, если бы я не установил фон для миниатюрного изображения. (SWIFT 4)
Вот соответствующий код:
class CameraViewController: UIViewController {
@IBOutlet weak var camBaseLayer: UIImageView!
private var isSettingThumbnail = false
private var thumbImage: UIImage?
var captureSession = AVCaptureSession()
let movieOutput = AVCaptureMovieFileOutput()
var photoOutput: AVCapturePhotoOutput?
var previewLayer: AVCaptureVideoPreviewLayer?
var image: UIImage!
var activeInput: AVCaptureDeviceInput!
var outputURL: URL!
//For video playback
private var playerQueue: AVQueuePlayer!
private var playerItem1: AVPlayerItem!
private var playerLooper: AVPlayerLooper!
private var playerLayer: AVPlayerLayer!
override func viewDidLoad() {
super.viewDidLoad()
//Setup of camera type stuff
setupCamera()
}
//MARK: Setup UI Elements and more(?,i think)
func setupCamera() {
if setupInputOutput() {
setupCaptureSession()
setupDevice()
startRunningCaptureSession()
setupPreviewLayer()
}
}
//for camera tap
@objc func normalTap(_ sender: UIGestureRecognizer) {
let settings = AVCapturePhotoSettings()
isSettingThumbnail = false
photoOutput?.capturePhoto(with: settings, delegate: self)
print("Photo gesture recognizer recognized ----")
}
//for video hold
@objc func longTap(_ sender: UIGestureRecognizer) {
if sender.state == .ended {
print("UIGestureRecognizerStateEnded")
stopRecording()
self.view.superview?.addSubview(cancelButton) //maybe do newView, then subview
cancelButton.isHidden = false
}
else if sender.state == .began {
print("UIGestureRecognizerStateBegan.")
//Do Whatever You want on Began of Gesture
startCapture()
}
}
func videoQueue() -> DispatchQueue {
return DispatchQueue.main
}
func tempURL() -> URL? {
let directory = NSTemporaryDirectory() as NSString
if directory != "" {
let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
print("\(path) < who is u PATH")
return URL(fileURLWithPath: path)
}
return nil
}
func stopRecording() {
if thumbImage != nil {
switchCamButton.isHidden = true
camWhiteLine.isHidden = true
camBaseLayer.image = thumbImage!
}
previewLayer?.removeFromSuperlayer()
DispatchQueue.main.asyncAfter(deadline: .now(), execute: { //+ 10.0
if self.movieOutput.isRecording == true {
self.movieOutput.stopRecording()
}
})
}
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()
}
}
//Extension for actual photo capture function
extension CameraViewController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
print("you in this !")
if let imageData = photo.fileDataRepresentation() {
print("\(UIImage(data: imageData)!) <-- image")
if isSettingThumbnail {
thumbImage = UIImage(data: imageData)
} else {
image = UIImage(data: imageData)!
}
print("\(image) <-- IMAGE VALUE ddu du ddu du") //it crashes with !
}
}
}
extension CameraViewController: AVCaptureFileOutputRecordingDelegate {
//MARK: - Protocal stubs
func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
isSettingThumbnail = true
photoOutput?.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
}
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()
}
}
}
}
}
Есть и другие вопросы, связанные с этим, но ни один из них не решил мою проблему или не получил успешного ответа.
Спасибо за помощь!