I am trying to record video in my iPhone app using AVFoundation. But whenever I click the Record button app crashes with this message
-[AVCaptureMovieFile
I had the same problem while changing videoDevice activeFormat and later wanted to record video. Because I was using best quality video I had to set sessionPreset to high, like following
_session.sessionPreset = AVCaptureSessionPresetHigh;
and it worked for me! :)
Because currently you don't have an active connection to record video to file.
Check connection active status before recording to output file:
AVCaptureConnection *c = [self.movieOutput connectionWithMediaType:AVMediaTypeVideo];
if (c.active) {
//connection is active
} else {
//connection is not active
//try to change self.captureSession.sessionPreset,
//or change videoDevice.activeFormat
}
If connection is not active, try to change captureSession.sessionPreset or videoDevice.activeFormat.
Repeat until you have set a valid format (that means c.active == YES). Then you can record video to output file.
I find the reason of this error. check your session's "setSessionPreset" setting, photo's resolution setting is different from video, for iPhone5, video resolution of the back camera is 1920*1080, the front camere is 1280*720, and photo's max resolution is 3264*2488, so if you set error resolution to video, the connect will not be actived.
Several things are missing in your code :
movieOutput
to your captureSession
audioInput
[_captureSession beginConfiguration]
and [_captureSession commitConfiguration]
AVAudioSession
to the correct category.Here is your code updated :
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord
error:&error];
if(!error)
{
[[AVAudioSession sharedInstance] setActive:YES error:&error];
if(error) NSLog(@"Error while activating AudioSession : %@", error);
}
else
{
NSLog(@"Error while setting category of AudioSession : %@", error);
}
self.captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:nil];
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *stillImageOutputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.stillImageOutput setOutputSettings:stillImageOutputSettings];
self.movieOutput = [[AVCaptureMovieFileOutput alloc] init];
[self.captureSession beginConfiguration];
[self.captureSession addInput:self.videoInput];
[self.captureSession addInput:self.audioInput];
[self.captureSession addOutput:self.movieOutput];
[self.captureSession addOutput:self.stillImageOutput];
[self.captureSession commitConfiguration];
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
previewLayer.frame = CGRectMake(0, 0, 320, 500);
[self.view.layer addSublayer:previewLayer];
[self.captureSession startRunning];
}
- (IBAction)toggleRecording:(id)sender
{
if(!self.movieOutput.isRecording)
{
[self.recordButton setTitle:@"Stop" forState:UIControlStateNormal];
NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"output.mp4"];
NSFileManager *manager = [[NSFileManager alloc] init];
if ([manager fileExistsAtPath:outputPath])
{
[manager removeItemAtPath:outputPath error:nil];
}
[self.movieOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputPath]
recordingDelegate:self];
}
else
{
[self.recordButton setTitle:@"Start recording" forState:UIControlStateNormal];
[self.movieOutput stopRecording];
}
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"Did finish recording, error %@ | path %@ | connections %@", error, [outputFileURL absoluteString], connections);
}
Hope this helps