1

我目前正在使用 AVCaptureSession 捕获视频和音频,并已设置管道以使用 AVAssetWriter 将数据写入磁盘。对于短视频,这完全没有问题。

但是,如果录制媒体的长度超过了任意时间,通常约为 2 分钟,则完成写入的调用会失败,但仍会设法生成仅播放大约 50% 内容的视频文件。我在写入过程中不断调用 isReadyForMoreMediaData 和 appendSampleBuffer ,它们总是返回 true。在完成调用之前,我似乎没有收到任何出现问题的通知。

在失败的 finishWriting 调用后 AVAssetWriters 错误设置为以下

Capture failed to end with status 3 and error Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x210b7880 {NSLocalizedFailureReason=An unknown error occurred (268451843), NSUnderlyingError=0x210b1ee0 "The operation couldn’t be completed. (OSStatus error 268451843.)", NSLocalizedDescription=The operation could not be completed}

不是世界上最有用的错误...

紧随其后的是对我设置的 AVCaptureSessionRuntimeErrorNotification 侦听器的调用,其中包含错误

Error Domain=AVFoundationErrorDomain Code=-11819 "Cannot Complete Action" UserInfo=0x21011940 {NSLocalizedRecoverySuggestion=Try again later., NSLocalizedDescription=Cannot Complete Action}

再次不是很有帮助......

这是我用来为音频配置 AVAssetWriter 输入的代码

    //\Configure Audio Writer Input
AudioChannelLayout acl;
bzero(&acl, sizeof(acl));
acl.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

NSDictionary*  audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                      [ NSNumber numberWithInt: 2 ], AVNumberOfChannelsKey,
                                      [ NSNumber numberWithFloat: 44100.0 ], AVSampleRateKey,
                                      [ NSData dataWithBytes: &acl length: sizeof( AudioChannelLayout ) ], AVChannelLayoutKey,
                                      [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey,
                                      nil];


m_audioWriterInput = [[AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings] retain];

这是我用来为视频配置 AVAssetWriterInput 的代码

        videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                     AVVideoCodecH264, AVVideoCodecKey,
                     [NSNumber numberWithInt:640], AVVideoWidthKey,
                     [NSNumber numberWithInt:480], AVVideoHeightKey,
                     nil];


m_videoWriterInput = [[AVAssetWriterInput
                       assetWriterInputWithMediaType:AVMediaTypeVideo
                       outputSettings:videoSettings] retain];

m_videoWriterInput.expectsMediaDataInRealTime = YES;

这是我用来初始化 AVAssetWriter 的代码

    m_audioAndVideoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:outputPath] fileType:AVFileTypeQuickTimeMovie error:&error];

m_audioAndVideoWriter.shouldOptimizeForNetworkUse = YES;
[m_audioAndVideoWriter addInput:m_videoWriterInput];
[m_audioAndVideoWriter addInput:m_audioWriterInput];

有没有人遇到过类似的问题?或者知道可能导致此问题的 finishWriting 调用中发生了什么?或者也许有人知道调试这个问题的一些新方法?

谢谢

4

1 回答 1

0

奇怪的是,设置m_audioAndVideoWriter shouldOptimizeForNetworkUse = NO会解决这个问题。实际上,如果您从文件中获取编码帧然后流式传输它们,我会确保您shouldOptimizeForNetworkUseYES. 我让它工作了,所以我很确定你可以让它工作。

容器生成的最后一步包括编写几个重要的容器原子,例如为编码帧AVCC指定的容器原子,以及其他非常重要的元数据。SPS/PPS

几个想法:

  1. 您在测试 ios 设备上创建了多大的文件?确保您没有用完空间 - 这会使.mov文件创建的最后一步失败。如果文件变得太大太快,我只会调整视频的大小。另外,我会根据您的质量需求使用其中一种预设来AVCaptureSession设置(captureSession.sessionPresetAVCaptureSessionPresetLow或)。AVCaptureSessionPresetMedium另外两个设置AVVideoMaxKeyFrameIntervalKeyAVVideoAverageBitRateKey可以帮助您减小文件大小。我可以给你更多信息,但让我们首先确保文件大小是一个问题:)

  2. 您是否尝试过生成.mp4文件?对于您的assetWriter,只需指定 fileType:kUTTypeMPEG4选项。如果这有什么不同,我会很好奇。

于 2012-06-25T15:53:44.647 回答