AVAssetWriter完成写入失败并生成只能观看50%的视频

时间:2012-06-20 08:10:40

标签: objective-c ios avfoundation

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

但是,如果录制媒体的长度超过任意时间,通常大约2分钟,则完成写入的调用失败但仍设法生成仅播放其内容的50%左右的视频文件。我在写作期间不断调用isReadyForMoreMediaData和appendSampleBuffer,它们总是返回true。在finishWriting调用之前,我似乎没有得到任何错误的通知。

在finishWriting调用失败后,AVAssetWriters Error设置为以下

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调用中可能导致此问题的内容是什么?或者有人知道调试这个问题的一些新方法吗?

由于

1 个答案:

答案 0 :(得分:0)

设置m_audioAndVideoWriter shouldOptimizeForNetworkUse = NO会解决此问题,这很奇怪。实际上,如果你从文件中抓取编码的帧然后然后流式传输,我会确保你将shouldOptimizeForNetworkUse设置为YES。我得到了它的工作,所以我很确定你能够让它工作。

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

一些想法:

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

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