如何使用AVAssetWriter而不是AVAssetExportSession重新编码现有视频

时间:2014-01-04 16:06:41

标签: ios objective-c ipad video avassetwriter

我正在尝试重新编码iPad上的视频,这些视频是在该设备上录制的,但方向“错误”。这是因为当文件转换为MP4文件并上传到Web服务器以与“视频”HTML5标记一起使用时,只有Safari似乎以正确的方向呈现视频。

基本上,我已成功使用AVMutableVideoCompositionLayerInstruction实现了我想要的功能,然后使用AVAssetExportSession创建带有音频的结果视频。但是,问题是文件大小在执行此操作后会大幅跳跃,例如,更正4.1MB的原始文件会导致最终文件大小为18.5MB!我所做的就是将视频旋转180度!!顺便提一下,我正在尝试处理的视频实例最初是由UIImagePicker在“压缩”期间使用videoQuality = UIImagePickerControllerQualityType640x480创建的,这实际上会在iPad mini上生成568 x 320的视频。

我在presetName上尝试了各种AVAssetExportSession设置,但我无法获得所需的结果。我最接近文件大小的是4.1MB(即与源完全相同!)使用AVAssetExportPresetMediumQuality但是这也将结果视频的尺寸减小到480 x 272而不是我明确设定的568 x 320。

所以,这导致我调查其他选项,因此使用AVAssetWriter代替。问题是,我无法获得我发现的任何代码!我尝试了在这个SO帖子(Video Encoding using AVAssetWriter - CRASHES)上找到的代码,但无法使其工作。首先,我得到了这一行的编译错误:

NSDictionary *videoOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(id)kCVPixelBufferPixelFormatTypeKey];

产生的编译错误是:

Undefined symbols for architecture armv7: "_kCVPixelBufferPixelFormatTypeKey"

除此之外,我尝试使用nil传递AVAssetReaderTrackOutput的outputSettings,根据标题信息应该没问题:

A value of nil for outputSettings configures the output to vend samples in their original format as stored by the specified track.

然而,我在这一行发生了崩溃:

BOOL result = [videoWriterInput appendSampleBuffer:sampleBuffer];

简而言之,我无法使用任何代码与AVAssetWriter一起使用,所以我真的需要一些帮助。有没有其他方法可以达到我想要的效果?顺便说一下,我正在使用Xcode 4.6,我使用ARC来定位iOS5以上的所有内容。

2 个答案:

答案 0 :(得分:1)

我已经解决了与您的问题相关的类似问题。这可能会帮助有类似问题的人:

  1. 假设writerInput是AVAssetWriterInput的对象实例,而assetTrack是AVAssetTrack的实例,那么您的转换问题只需解决:
  2. writerInput.transform = assetTrack.preferredTransform;

    1. 你必须在附加样本缓冲区之后释放sampleBuffer,所以你会有类似的东西:

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

答案 1 :(得分:0)

编译错误是由于我不包括CoreVideo.framework引起的。只要我包含它并导入它,我就可以获得编译代码。此外,代码可以工作并生成结果视频我发现了2个新问题:

  1. 我无法使用transform上的AVAssetWriterInput属性使转换工作。这意味着我很难使用AVMutableVideoCompositionInstructionAVAssetExportSession进行转换。
  2. 如果我使用AVAssetWriter来处理压缩(因为AVAssetExportSession没有很多选项),我的内存泄漏仍然很糟糕。我已经尝试了所有我能想到的东西,从这个链接中的解决方案(Help Fix Memory Leak release)开始,还有关键点的@autorelease块。但无论我尝试什么,似乎以下行都会导致泄漏:

    CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer];
    
  3. 我真的可以帮忙。