iosobjective-cavfoundationavcapturesessionavcapturemoviefileoutput

AVFoundation - How save AVCaptureMovieFileDataOutput to file?


I've been going through the AV Foundation Programming Guide. In particular I've been trying to get the "Putting it all together" part in the "Media Capture" section to work. I've made some minor changes to the code in the tutorial, but nothing that should have much impact. What I'm confused about it how to actually save a movie file from the AVCaptureMovieFileDataOutput. I setup the capture session with the following:

//Create session.
AVCaptureSession *session = [[AVCaptureSession alloc] init];

//Set preset to low.
if ([session canSetSessionPreset:AVCaptureSessionPresetLow]) {
    session.sessionPreset = AVCaptureSessionPresetLow;
}
else {
    // Handle the failure.
}

//Get camera device.
AVCaptureDevice *device =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

NSError *error = nil;
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
    //Handle the error appropriately.
}
[session addInput:input];

//Create output.
AVCaptureMovieFileOutput *output = [[AVCaptureMovieFileOutput alloc] init];
[session addOutput:output];

[session startRunning];

I may just be missing something in the developer docs that I'm not seeing, but I haven't seen how to actually get the session to create a file. Any suggestions? Thank you much!


Solution

  • Keep a reference to the AVCaptureMovieFileOutput. That will come in handy.

    Anyway, there is a method of that class that can be called like so:

    [[self movieFileOutput] startRecordingToOutputFileURL:url recordingDelegate:self];
    

    where url is a file URL on the device, such as the documents directory. This allows it to start recording. You also might want to note that you can stop it by calling [[self movieFileOutput] stopRecording];. You also need to implement the AVCaptureFileOutputRecordingDelegate methods to handle callbacks. These methods are called when recording begins and ends, as so:

    -(void)captureOutput:(AVCaptureFileOutput *)captureOutput 
                   didStartRecordingToOutputFileAtURL:(NSURL *)fileURL 
                   fromConnections:(NSArray *)connections;
    
    -(void)captureOutput:(AVCaptureFileOutput *)captureOutput 
                   didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL 
                   fromConnections:(NSArray *)connections error:(NSError *)error;
    

    You must implement these delegate methods to handle what happens when you begin and end recording. In the didFinishRecording method, you can then mess around with AVAssetURLs, tracks, compositions, and all sorts of things before exporting it as a final movie. Really cool stuff. However it is a decently hard framework and frustrating at times when things seem to be backwards - FYI there are three types of orientations on iOS devices, so the rotation of video will make you want to pull your hair out.

    I could literally go on for days about features and frustrations, though, so just be sure to consult Apple's docs whenever possible. This should get you on the right track!