如何使用AVAssetWriter替代AVAssetExportSession重新编码现有视频

4
我试图在iPad上重新编码视频,这些视频是在该设备上录制的,但方向不正确。这是因为当文件转换为MP4文件并上传到Web服务器以与“video”HTML5标记一起使用时,只有Safari似乎能够正确呈现视频。
基本上,我通过使用AVMutableVideoCompositionLayerInstruction实现了所需的内容,然后使用AVAssetExportSession创建带音频的结果视频。 但是,问题在于,在这样做之后,文件大小会大幅增加,例如,纠正原始文件的4.1MB会导致最终文件大小达到18.5MB!我只是将视频旋转180度!!顺便说一句,我尝试处理的视频实例最初是由UIImagePicker在使用videoQuality = UIImagePickerControllerQualityType640x480 进行“压缩”期间创建的,其实际上在iPad mini上产生了568 x 320的视频。
我尝试了AVAssetExportSession上的各种presetName设置,但无法获得所需的结果。就文件大小而言,我最接近的是使用AVAssetExportPresetMediumQuality,大小为4.1MB(与源完全相同!),但是这也将结果视频的尺寸从我明确设置的568 x 320减小到480 x 272。
这让我想研究其他选项,因此改用AVAssetWriter。 问题是,我找到的任何代码都无法工作!我尝试了在此SO帖子(Video Encoding using AVAssetWriter - CRASHES)上找到的代码,但无法让它工作。首先,对于这行代码,我得到编译错误:
NSDictionary *videoOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey];

编译错误如下:

Undefined symbols for architecture armv7: "_kCVPixelBufferPixelFormatTypeKey"

尝试将AVAssetReaderTrackOutput的outputSettings设置为nil,但仍然有崩溃发生,根据头文件信息,这样做应该是可以的:

值为nil的outputSettings会将输出配置为以指定轨道存储的原始格式出售样本。

然而,在此行发生崩溃:

BOOL result = [videoWriterInput appendSampleBuffer:sampleBuffer];

简而言之,我无法让任何代码与AVAssetWriter配合使用,因此我真的需要帮助。是否有其他方法可以实现我的期望结果?顺便说一句,我使用的是Xcode 4.6,目标是从iOS5开始的所有平台,使用ARC。

2个回答

1

我曾解决过与您问题相关的类似问题。这可能有助于遇到类似问题的人:

  1. 假设writerInput是AVAssetWriterInput对象实例,assetTrack是AVAssetTrack实例,则可以通过以下方式解决变换问题:

writerInput.transform = assetTrack.preferredTransform;

  1. 在附加示例缓冲区后,您必须释放sampleBuffer,因此您可能会有以下内容:

    if (sampleBuffer = [asset_reader_output copyNextSampleBuffer]) { BOOL result = [writerInput appendSampleBuffer:sampleBuffer]; CFRelease(sampleBuffer); // 释放sampleBuffer! }


0
编译错误是由于我没有包含CoreVideo.framework引起的。一旦我包含并导入它,我就可以让代码编译了。此外,代码可以工作并生成一个结果视频,但我发现了两个新问题:
  1. 我无法使用AVAssetWriterInput上的transform属性使变换工作。这意味着我只能使用AVMutableVideoCompositionInstructionAVAssetExportSession进行转换。
  2. 如果我使用AVAssetWriter来处理压缩(因为我在AVAssetExportSession中没有太多选项),我仍然有一个严重的内存泄漏问题。我尝试了我所能想到的一切,从此链接中的解决方案开始(Help Fix Memory Leak release),还尝试在关键点使用@autorelease块。但似乎以下行会导致泄漏,无论我尝试什么:

    CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer];
    

我真的需要一些帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接