2

我正在尝试使用 avassetwriter 获取相机输入并将数据写入磁盘。从代表看来,avassetwriterinputpixelbufferadator 似乎无法附加数据。我不知道为什么

- (NSURL*) assetURL{
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
 NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
 NSString *filePath = [basePath stringByAppendingPathComponent:@"videoOutput"];

 return [NSURL fileURLWithPath:filePath];
}



- (id) init {
 if(![super init]) return nil;

 self.captureSession = [[c alloc] init];
 self.captureSession.sessionPreset = AVCaptureSessionPresetHigh; 

 // HIGH: 640 x 480
 // MEDIUM: 360 x 480
 // LOW: 192 x 144

 [self loadVideoInput];
 [self loadVideoOutput];
 [self loadPreviewLayer];
 [self loadWriter];



 return self;
}
- (void) loadVideoInput{


 AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if (device.position == AVCaptureDevicePositionFront) {
            videoDevice = device;
   break;
        }
    }



 if ( videoDevice ) {
  NSError *error;
  AVCaptureDeviceInput *videoIn = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
  if ( !error ) {
   if ([self.captureSession canAddInput:videoIn]) 
    [self.captureSession addInput:videoIn];
   else NSLog(@"Couldn't add video input");  
  } else NSLog(@"Couldn't create video input");
 } else NSLog(@"Couldn't create video capture device");
}
- (void) loadVideoOutput{

 AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
 output.alwaysDiscardsLateVideoFrames = YES;

 [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

 //dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
 //[output setSampleBufferDelegate:self queue:queue];
 //dispatch_release(queue);


 //output.minFrameDuration = CMTimeMake(15, 1); // If you wish to cap the frame rate to a known value, such as 15 fps, set 
 [output setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; // BGRA is necessary for manual preview



 if ([self.captureSession canAddOutput:videoOut]) 
  [self.captureSession addOutput:videoOut]; 
 else 
  NSLog(@"Couldn't add video output");
 //[self.captureSession addOutput:output];
 [output release];

}
- (void) loadPreviewLayer{
 previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
 previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
}

- (void) loadWriter{



 NSError *error = nil;
 videoWriter = [[AVAssetWriter alloc] initWithURL:[self assetURL] fileType:AVFileTypeQuickTimeMovie error:&error];
 NSParameterAssert(videoWriter);

 NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
           AVVideoCodecH264, AVVideoCodecKey,
           [NSNumber numberWithInt:640], AVVideoWidthKey,
           [NSNumber numberWithInt:480], AVVideoHeightKey,
           nil];
 writerInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings] retain];
 writerInput.expectsMediaDataInRealTime = YES;
 NSParameterAssert(writerInput);
 NSParameterAssert([videoWriter canAddInput:writerInput]);
 [videoWriter addInput:writerInput];

 currentTime = kCMTimeZero;

 adaptor = [[AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput sourcePixelBufferAttributes:nil] retain];


 NSLog(@"Error? %@",error);

}


- (void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

 if(recording){


  CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 
  currentTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);


  // STUFF ISN'T WORKING HERE


  BOOL success = [adaptor appendPixelBuffer:imageBuffer withPresentationTime:currentTime];
  NSLog(@"%@",success ? @"YES" : @"NO");
 }



}


- (void) startRecording{
 [videoWriter startWriting];
 [videoWriter startSessionAtSourceTime:currentTime];
 recording = YES;

}

- (void) stopRecording{
 recording = NO;
 [writerInput markAsFinished];
 [videoWriter endSessionAtSourceTime:currentTime];
 [videoWriter finishWriting];
}
4

2 回答 2

0

您每次都需要删除现有文件(在您的情况下为“filePath”),以尝试录制视频。

于 2010-12-01T16:18:40.227 回答
-1
[adaptor appendPixelBuffer:imageBuffer withPresentationTime:currentTime];

也许您需要自己管理视频时间,您从 sampleBuffer 中获取 currentTime,它不完全是视频时间。尝试在帧前累积捕获时间

于 2011-10-09T16:33:52.587 回答