Tôi đang gặp sự cố khi tôi ghi âm thanh + video bằng cách sử dụng AVCaptureVideoDataOutput và AVCaptureAudioDataOutput. Đôi khi, video bị chặn trong vài phần nghìn giây, đôi khi âm thanh không đồng bộ với video.Các vấn đề về hiệu năng khi sử dụng AVCaptureVideoDataOutput và AVCaptureAudioDataOutput
Tôi đã chèn một số nhật ký và quan sát thấy đầu tiên tôi nhận được nhiều bộ đệm video trong lệnh gọi thu lại, và sau một thời gian tôi nhận được bộ đệm âm thanh (đôi khi tôi không nhận được bộ đệm âm thanh và video kết quả là không có âm thanh). Nếu tôi nhận xét mã xử lý các bộ đệm video, tôi sẽ nhận được bộ đệm âm thanh mà không gặp sự cố.
Đây là mã Tôi đang sử dụng:
-(void)initMovieOutput:(AVCaptureSession *)captureSessionLocal
{
AVCaptureVideoDataOutput *dataOutput = [[AVCaptureVideoDataOutput alloc] init];
self._videoOutput = dataOutput;
[dataOutput release];
self._videoOutput.alwaysDiscardsLateVideoFrames = NO;
self._videoOutput.videoSettings = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange]
forKey:(id)kCVPixelBufferPixelFormatTypeKey
];
AVCaptureAudioDataOutput *audioOutput = [[AVCaptureAudioDataOutput alloc] init];
self._audioOutput = audioOutput;
[audioOutput release];
[captureSessionLocal addOutput:self._videoOutput];
[captureSessionLocal addOutput:self._audioOutput];
// Setup the queue
dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[self._videoOutput setSampleBufferDelegate:self queue:queue];
[self._audioOutput setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);
}
Ở đây tôi thiết lập các nhà văn:
-(BOOL) setupWriter:(NSURL *)videoURL session:(AVCaptureSession *)captureSessionLocal
{
NSError *error = nil;
self._videoWriter = [[AVAssetWriter alloc] initWithURL:videoURL fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(self._videoWriter);
// Add video input
NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:640], AVVideoWidthKey,
[NSNumber numberWithInt:480], AVVideoHeightKey,
nil];
self._videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];
NSParameterAssert(self._videoWriterInput);
self._videoWriterInput.expectsMediaDataInRealTime = YES;
self._videoWriterInput.transform = [self returnOrientation];
// Add the audio input
AudioChannelLayout acl;
bzero(&acl, sizeof(acl));
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
NSDictionary* audioOutputSettings = nil;
// Both type of audio inputs causes output video file to be corrupted.
// should work on any device requires more space
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 ];
self._audioWriterInput = [AVAssetWriterInput
assetWriterInputWithMediaType: AVMediaTypeAudio
outputSettings: audioOutputSettings ];
self._audioWriterInput.expectsMediaDataInRealTime = YES;
// add input
[self._videoWriter addInput:_videoWriterInput];
[self._videoWriter addInput:_audioWriterInput];
return YES;
}
Và đây là callback:
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
if(!CMSampleBufferDataIsReady(sampleBuffer))
{
NSLog(@"sample buffer is not ready. Skipping sample");
return;
}
if(_videoWriter.status != AVAssetWriterStatusCompleted)
{
if(_videoWriter.status != AVAssetWriterStatusWriting )
{
CMTime lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
[_videoWriter startWriting];
[_videoWriter startSessionAtSourceTime:lastSampleTime];
}
if(captureOutput == _videoOutput)
{
if([self._videoWriterInput isReadyForMoreMediaData])
{
[self newVideoSample:sampleBuffer];
}
}
else if(captureOutput == _audioOutput)
{
if([self._audioWriterInput isReadyForMoreMediaData])
{
[self newAudioSample:sampleBuffer];
}
}
}
}
-(void) newAudioSample:(CMSampleBufferRef)sampleBuffer
{
if(_videoWriter.status > AVAssetWriterStatusWriting)
{
[self NSLogPrint:[NSString stringWithFormat:@"Audio:Warning: writer status is %d", _videoWriter.status]];
if(_videoWriter.status == AVAssetWriterStatusFailed)
[self NSLogPrint:[NSString stringWithFormat:@"Audio:Error: %@", _videoWriter.error]];
return;
}
if(![_audioWriterInput appendSampleBuffer:sampleBuffer])
[self NSLogPrint:[NSString stringWithFormat:@"Unable to write to audio input"]];
}
-(void) newVideoSample:(CMSampleBufferRef)sampleBuffer
{
if(_videoWriter.status > AVAssetWriterStatusWriting)
{
[self NSLogPrint:[NSString stringWithFormat:@"Video:Warning: writer status is %d", _videoWriter.status]];
if(_videoWriter.status == AVAssetWriterStatusFailed)
[self NSLogPrint:[NSString stringWithFormat:@"Video:Error: %@", _videoWriter.error]];
return;
}
if(![_videoWriterInput appendSampleBuffer:sampleBuffer])
[self NSLogPrint:[NSString stringWithFormat:@"Unable to write to video input"]];
}
Có một cái gì đó sai trong mã của tôi, tại sao video bị lag? (Tôi đang thử nghiệm trên Iphone 4 ios 4.2.1)
Cảm ơn. Đây là một trợ giúp lớn. – Liron
Tôi biết câu trả lời này là cũ, nhưng bạn có thể đưa ra một ví dụ về cách làm điều đó không? Tôi đã cố gắng riêng biệt (mới) hàng đợi nối tiếp, mà không làm việc và tôi đã cố gắng thiết lập một hàng đợi với DISPATCH_QUEUE_CONCURRENT, mà cũng không giúp đỡ. –
Xây dựng trên nhận xét cuối cùng của tôi: Khi tôi sử dụng hai hàng đợi riêng biệt, tôi khiến người chia sẻ của tôi thất bại –