我使用 AVCaptureSession 使用 AVAssetWriter 写入 mov 文件。同样的代码在 iOS 13 之前的设备上不会出现裂纹。在所有 iOS 13 设备上,无论 iPhone/iPad 型号如何,都会出现爆裂声。
我已将此作为错误提交给 Apple,但我担心我错过了一些简单的事情。还有其他人经历过这种情况吗?我可以更改设置的任何想法吗?
我尝试过的事情
- 更改了 mov -> mpeg
- 尝试了多种音频编解码器(特别是 AppleLossless 和 AAC)
- 推送到主队列而不是指定的 captureQueue
- 尝试了 AVCaptureMovieFileOutput,不存在裂纹。问题特定于 AVAssetWriter
- AVCaptureSession 始终以 44100 提供音频,因此我在 AVAssetWriter 中将其重新采样为 48000。裂纹仍然存在。
任何想法都会有帮助!
Setup
self.session = [[AVCaptureSession alloc] init];
[self.session setSessionPreset:AVCaptureSessionPresetiFrame1280x720];
NSError *error;
AVCaptureDevice *inputVideoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *deviceVideoInput = [AVCaptureDeviceInput deviceInputWithDevice:inputVideoDevice error:&error];
if ([self.session canAddInput:deviceVideoInput]) {
[self.session addInput:deviceVideoInput];
}
AVCaptureDevice* mic = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
AVCaptureDeviceInput* micinput = [AVCaptureDeviceInput deviceInputWithDevice:mic error:nil];
if ([self.session canAddInput:micinput]) {
[self.session addInput:micinput];
}
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
output.videoSettings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) };
[output setSampleBufferDelegate:self queue:_captureQueue];
[self.session addOutput:output];
AVCaptureAudioDataOutput* audioout = [[AVCaptureAudioDataOutput alloc] init];
[audioout setSampleBufferDelegate:self queue:_captureQueue];
[self.session addOutput:audioout];
[self setCameraPosition:NO];
[self.session startRunning];
self.preview = [AVCaptureVideoPreviewLayer layerWithSession:_session];
self.preview.videoGravity = AVLayerVideoGravityResizeAspect;
AVAssetWriter 初始化
_path = path;
[[NSFileManager defaultManager] removeItemAtPath:_path error:nil];
NSURL *url = [NSURL fileURLWithPath:self.path];
_writer = [AVAssetWriter assetWriterWithURL:url fileType:AVFileTypeQuickTimeMovie error:nil];
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithFloat: frameSize.width], AVVideoWidthKey,
[NSNumber numberWithFloat: frameSize.height], AVVideoHeightKey,
nil];
_videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings];
_videoInput.expectsMediaDataInRealTime = YES;
[_writer addInput:_videoInput];
AudioChannelLayout acl;
bzero( &acl, sizeof(acl));
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
settings = [NSDictionary dictionaryWithObjectsAndKeys:
[ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[ NSNumber numberWithInt:(int)channels], AVNumberOfChannelsKey,
[ NSNumber numberWithFloat:sampleRate], AVSampleRateKey,
[ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey,
nil];
_audioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:settings];
_audioInput.expectsMediaDataInRealTime = YES;
[_writer addInput:_audioInput];
[_writer startWriting];
更新::
iPhone 11+ 设备没有爆裂声,似乎是他们在底层使用编解码器进行了更改,导致“旧”设备出现问题。
我已向 Apple 提交了错误并使用了技术支持。技术支持已证实 iPhone 11 没有问题,而较旧的设备则存在问题。
对错误单的响应为零。
如果您可以在可预见的将来远离 AVAssetWriter。