这是我的问题:我有一个摄像头视图控制器,可以在其中拍摄视频并进行视频播放。拍摄视频效果很好,但是当我开始播放时,它会不流畅地循环播放。我正在使用AVPlayerLooper和AVQueuePlayer,当它循环播放时,在循环下一次播放时会有一些延迟。有一个提示是因为它显示了我的背景层(回放playerLayer后面的层)。背景设置为视频的第一帧,这就是为什么blip不会显示为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()
}
}
}
}
}
有other questions种与此有关的东西,但都没有解决我的问题或已成功回答。
感谢您的帮助!