I’m attempting to take images whereas an AVCaptureMovieFileOutput is recording, however the whole lot I’ve tried has both stopped the recording or not been capable of retrieve any frames. I’m working with an iPhone 6s Plus on iOS 12.1.2
I do know that I can use AVAssetWriter+AVCaptureVideoDataOutput, however this can be very unreliable and I wish to keep away from it if doable. Thanks for any assist.
Issues I’ve tried:
- AVCaptureMovieFileOutput+AVCapturePhotoOutput on two separate classes: Stopped the recording
- AVCaptureMovieFileOutput+AVCaptureStillImageOutput on two separate classes: Stopped the recording
- AVCaptureMovieFileOutput+AVCaptureVideoDataOutput on the identical session: Knowledge output delegate callback shouldn’t be known as (it really works on iPhone 13 working iOS 17, however not right here)
- AVCaptureMovieFileOutput+AVCaptureVideoDataOutput on two separate classes: Stopped the recording
Beneath is the code for my check app.
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() {
tremendous.viewDidLoad()
checkPermissions()
session1.startRunning()
session2.startRunning()
sleep(1)
print("begin recording")
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
fileOutput.startRecording(to: documentsURL.appendingPathComponent("check.mp4"), recordingDelegate: self)
// sleep(1)
// print("take picture")
// photoOutput.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
}
func setupCamera(){
device1 = AVCaptureDevice.default(for: .video)
device2 = AVCaptureDevice.default(for: .video)
do {
session1.beginConfiguration()
let input1 = strive AVCaptureDeviceInput(gadget: device1)
session1.addInput(input1)
session1.addOutput(fileOutput)
session1.commitConfiguration()
session2.beginConfiguration()
let input2 = strive AVCaptureDeviceInput(gadget: 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(){
swap AVCaptureDevice.authorizationStatus(for: .video) {
case .approved:
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 as soon as = true
}
extension ViewController: AVCaptureVideoDataOutputSampleBufferDelegate{
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
if as soon as {
as soon as = 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.most important.async {
self.debugImageView.picture = myUIImage
}
}
}
extension ViewController: AVCapturePhotoCaptureDelegate{
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto picture: AVCapturePhoto, error: Error?) {
debugImageView.picture = UIImage(knowledge: picture.fileDataRepresentation()!)
}
}
extension ViewController: AVCaptureFileOutputRecordingDelegate{
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
print("end recording")
}
}