iOS 12中AVCaptureMovieFileOutput录制时拍照的实现问题
在iOS 12.1.2的iPhone 6s Plus上实现录屏同时拍照的问题
我在iPhone 6s Plus(iOS 12.1.2)设备上尝试用AVCaptureMovieFileOutput录制视频的同时拍照,但所有尝试的方法要么导致录制停止,要么无法获取画面帧。我知道可以使用AVAssetWriter+AVCaptureVideoDataOutput方案,但该方案极不稳定,希望尽可能避免。
以下是我尝试过的方法:
- 两个独立Session搭配
AVCaptureMovieFileOutput+AVCapturePhotoOutput:录制停止 - 两个独立Session搭配
AVCaptureMovieFileOutput+AVCaptureStillImageOutput:录制停止 - 同一Session搭配
AVCaptureMovieFileOutput+AVCaptureVideoDataOutput:数据输出代理回调未触发(该方法在iOS17的iPhone13上可正常工作) - 两个独立Session搭配
AVCaptureMovieFileOutput+AVCaptureVideoDataOutput:录制停止
以下是测试应用的代码:
class ViewController: UIViewController { var device1:AVCaptureDevice! var device2:AVCaptureDevice! let session1:AVCaptureSession = AVCaptureSession() let session2:AVCaptureSession = AVCaptureSession() let fileOutput:AVCaptureMovieFileOutput = AVCaptureMovieFileOutput() let dataOutput:AVCaptureVideoDataOutput = AVCaptureVideoDataOutput() // let stillImageOutput:AVCaptureStillImageOutput = AVCaptureStillImageOutput() // let photoOutput:AVCapturePhotoOutput = AVCapturePhotoOutput() @IBOutlet weak var debugImageView:UIImageView! override func viewDidLoad() { super.viewDidLoad() checkPermissions() session1.startRunning() session2.startRunning() sleep(1) print("start recording") let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! fileOutput.startRecording(to: documentsURL.appendingPathComponent("test.mp4"), recordingDelegate: self) // sleep(1) // print("take photo") // photoOutput.capturePhoto(with: AVCapturePhotoSettings(), delegate: self) } func setupCamera(){ device1 = AVCaptureDevice.default(for: .video) device2 = AVCaptureDevice.default(for: .video) do { session1.beginConfiguration() let input1 = try AVCaptureDeviceInput(device: device1) session1.addInput(input1) session1.addOutput(fileOutput) session1.commitConfiguration() session2.beginConfiguration() let input2 = try AVCaptureDeviceInput(device: device1) session2.addInput(input2) dataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue")) session2.addOutput(dataOutput) // session2.addOutput(photoOutput) // session2.addOutput(stillImageOutput) session2.commitConfiguration() } catch { print(error) } } func checkPermissions(){ switch AVCaptureDevice.authorizationStatus(for: .video) { case .authorized: self.setupCamera() case .notDetermined: AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in guard granted else { return } self?.setupCamera() } case .denied: return case .restricted: return @unknown default: return } } var once = true } extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate{ func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { if once { once = false } else { return } let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) let ciImage = CIImage(cvPixelBuffer: imageBuffer!) let context = CIContext() let myUIImage = UIImage(cgImage: context.createCGImage(ciImage, from: ciImage.extent)!) DispatchQueue.main.async { self.debugImageView.image = myUIImage } } } extension ViewController: AVCapturePhotoCaptureDelegate{ func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { debugImageView.image = UIImage(data: photo.fileDataRepresentation()!) } } extension ViewController: AVCaptureFileOutputRecordingDelegate{ func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { print("finish recording") } }
内容的提问来源于stack exchange,提问作者TheJavaNoob
相关产品推荐
相关产品推荐

