我正在尝试使用AVAssetWriter和AVCaptureVideoDataOutput录制简单视频。 我正在使用视频数据输出,因此我可以添加暂停/恢复录制。我看过RosyWriter和其他一些例子,我的建议,我无法弄清楚我做错了什么。我尝试从网址录制录制的视频,并将其保存到相机胶卷,既不会产生视频或错误。
这是我的代码,我缺少什么:
// Called from viewWillAppear
- (void)setupCaptureSession{
// Camera utils
previousSecondTimestamps = [[NSMutableArray alloc] init];
// Capture Session
captureSession = [[AVCaptureSession alloc] init];
captureSession.sessionPreset = AVCaptureSessionPresetMedium;
[self.cameraOverlay setSession:captureSession];
sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL);
writingQueue = dispatch_queue_create("writing queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(sessionQueue, ^{
// Capture Device
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
// Video Input settings
NSError *error = nil;
videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!videoInput) {
// Handle the error appropriately.
}
if ([captureSession canAddInput:videoInput])
{
[captureSession addInput:videoInput];
}
dispatch_async(dispatch_get_main_queue(), ^{
[[(AVCaptureVideoPreviewLayer *)[self.cameraOverlay layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)[self interfaceOrientation]];
});
// Video Output settings
videoOutput = [[AVCaptureVideoDataOutput alloc] init];
[captureSession addOutput:videoOutput];
[videoOutput setAlwaysDiscardsLateVideoFrames:YES];
[videoOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
//output.minFrameDuration = CMTimeMake(1, 15);
// Queue the output
dispatch_queue_t bufferQueue = dispatch_queue_create("buffer session", NULL);
[videoOutput setSampleBufferDelegate:self queue:bufferQueue];
// Starts capture session
[captureSession startRunning];
});
}
// Buffer delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
NSLog(@"connection: %@",connection);
NSLog(@"Video!!");
CFRetain(sampleBuffer);
dispatch_async(writingQueue, ^{
if(self.recording) {
NSLog(@"Source time value: %d",(int)CMSampleBufferGetPresentationTimeStamp(sampleBuffer).value);
if ( writer.status == AVAssetWriterStatusUnknown ) {
if ([writer startWriting]) {
[writer startSessionAtSourceTime:nextPTS];
}
else {
NSLog(@"Error: %@",[writer error]);
}
}
if ( writer.status == AVAssetWriterStatusWriting ) {
if (writerInput.readyForMoreMediaData) {
if ([writerInput appendSampleBuffer:sampleBuffer]) {
NSLog(@"Successful write!!!!");
nextPTS = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
if(nextPTS.value > 0) {
// CMTime pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
// timeOffset = CMTimeAdd(nextPTS, pts);
}
}
else {
NSLog(@"Error: %@",[writer error]);
}
}
}
}
CFRelease(sampleBuffer);
});
}
- (IBAction)record:(id)sender
{
if(!self.recording) {
// Setup asset writer!!
// AVAsset Writer
self.filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"movie" stringByAppendingPathExtension:@"mov"]];
self.url = [[NSURL alloc] initFileURLWithPath:self.filePath];
//if(!debug){
[[NSFileManager defaultManager] removeItemAtURL:self.url error:nil];
//}
dispatch_async(writingQueue, ^{
nextPTS = kCMTimeZero;
writer = [[AVAssetWriter alloc] initWithURL: self.url fileType:AVFileTypeQuickTimeMovie error:nil];
writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:nil];
writerInput.expectsMediaDataInRealTime = YES;
if ([writer canAddInput:writerInput])
[writer addInput:writerInput];
else {
NSLog(@"Couldn't add asset writer video input.");
}
});
}
self.recording = TRUE;
}
- (void)saveMovieToCameraRoll
{
dispatch_async(sessionQueue, ^{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:self.url completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"Error: %@",error);
}
else {
NSLog(@"Successfully saved");
}
}];
});
}