在我的项目中,我需要在视频开始时捕获帧。我从代理中捕获它
"- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
",并使用"appendPixelBuffer:newPixBuffer withPresentationTime:tmpTime"
保存修改后的帧。这些都没关系!但是,当我完成一次录制时,avassetwriter的状态可以更改为已完成,但mp4文件无法保存。
这是我的一些代码:
configueration:
-(void)configRecording:(NSURL*)fileUrl
{ NSError *错误;
_recordingFilePath = fileUrl;
NSDictionary *videoCleanApertureSettings = @{
AVVideoCleanApertureWidthKey: [NSNumber numberWithFloat:SCREEN_WIDTH],
AVVideoCleanApertureHeightKey: [NSNumber numberWithFloat:SCREEN_WIDTH],
AVVideoCleanApertureHorizontalOffsetKey: [NSNumber numberWithInt:10],
AVVideoCleanApertureVerticalOffsetKey: [NSNumber numberWithInt:10],
};
NSDictionary *videoCompressionSettings = @{
AVVideoAverageBitRateKey: [NSNumber numberWithFloat:2000000.0],
AVVideoMaxKeyFrameIntervalKey: [NSNumber numberWithInteger:1],
AVVideoProfileLevelKey: AVVideoProfileLevelH264Baseline30,
AVVideoCleanApertureKey: videoCleanApertureSettings,
};
NSDictionary* videoSetting = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:SCREEN_WIDTH],AVVideoWidthKey,
[NSNumber numberWithInt:SCREEN_WIDTH],AVVideoHeightKey,
videoCompressionSettings,AVVideoCompressionPropertiesKey,
AVVideoScalingModeResizeAspectFill,AVVideoScalingModeKey,
nil];
_avassetWriter = [AVAssetWriter assetWriterWithURL:fileUrl fileType:AVFileTypeMPEG4 error:&error];
// Add the audio input
AudioChannelLayout acl;
bzero( &acl, sizeof(acl));
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
NSDictionary* audioOutputSettings = [ NSDictionary dictionaryWithObjectsAndKeys:
[ NSNumber numberWithInt: kAudioFormatAppleLossless ], AVFormatIDKey,
[ NSNumber numberWithInt: 16 ], AVEncoderBitDepthHintKey,
[ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,
[ NSNumber numberWithInt: 1 ], AVNumberOfChannelsKey,
[ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey,
nil ];
_avassetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSetting];
_avassetWriterInput.expectsMediaDataInRealTime = YES;
_audioWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
_audioWriterInput.expectsMediaDataInRealTime = YES;
_avassetAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:_avassetWriterInput sourcePixelBufferAttributes:videoSetting];
if ([_avassetWriter canAddInput:_avassetWriterInput] ) {
[_avassetWriter addInput:_avassetWriterInput];
}
if ([_avassetWriter canAddInput:_audioWriterInput]) {
[_avassetWriter addInput:_audioWriterInput];
}
BOOL canOutput = [_avassetWriter canApplyOutputSettings:videoSetting forMediaType:AVFileTypeMPEG4];
NSLog(@"can out put := %d", canOutput);
}
这是我的开始录音功能:
[_ avassetWriter startWriting];
[_avassetWriter startSessionAtSourceTime:kCMTimeZero];
3.这是修改框架的方法:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
int faceTrackResult = [faceTracker startFacialTracking:pixelBuffer
startFaceTracking:YES
withFaceRectangle:_faceRect
withRollAngle:_rollAngle];
CVPixelBufferRetain(pixelBuffer);
dispatch_async(dispatch_get_main_queue(), ^{
[_trackerView drawSceneWithBackground:pixelBuffer];
CVPixelBufferRelease(pixelBuffer);
});
if (cameraView.isRecording == YES) {
CMTime tmpTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
[cameraView getLastRecordingTime:tmpTime];
//开始捕捉视频帧
CGImageRef curFrameRef = [cameraView getImageRef:self.trackerView.frame];
CVPixelBufferRef newPixBuffer = [self pixelBufferFromCGImage:curFrameRef];
if (cameraView.avassetWriter.status == AVAssetWriterStatusWriting && cameraView.isRecording == YES) {
BOOL result = [cameraView.avassetAdaptor appendPixelBuffer:newPixBuffer withPresentationTime:tmpTime];
NSLog(@"result := %d; status := %ld", result, (long)cameraView.avassetWriter.status);
}
}
}
这是我的停止录制功能:
- (无效)stopRecording { WS(weakSelf);
[_avassetWriterInput markAsFinished];
[_avassetWriter endSessionAtSourceTime: lastSimple_Time];
if (_avassetWriter.status != AVAssetWriterStatusCompleted) {
NSLog(@"error := %@", _avassetWriter.error);
}
self.isRecording = NO;
[_avassetWriter finishWritingWithCompletionHandler:^{
if (_avassetWriter.status == AVAssetWriterStatusFailed) {
NSLog(@"error := %@", _avassetWriter.error);
}
if (weakSelf.recordDelegate && [weakSelf.recordDelegate respondsToSelector:@selector(finishRecording:)]) {
[weakSelf.recordDelegate finishRecording:weakSelf.recordingFilePath];
}
}];
}