尝试使用AVAssetWriter和AVCaptureVideoDataOutput录制短视频

时间:2014-06-29 18:19:59

标签: ios avfoundation avcapturesession avassetwriter

我正在尝试使用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");
        }

    }];
});
}

0 个答案:

没有答案