【问题标题】:How to use AVAssetWriter instead of AVAssetExportSession to re-encode existing video如何使用 AVAssetWriter 而不是 AVAssetExportSession 重新编码现有视频
【发布时间】:2014-01-22 06:46:12
【问题描述】:

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

基本上,我已经设法通过使用AVMutableVideoCompositionLayerInstruction 来实现我想要的,然后使用AVAssetExportSession 创建带有音频的结果视频。但是,问题是这样做后文件大小会大幅增加,例如,纠正 4.1MB 的原始文件会导致最终文件大小为 18.5MB!我所做的就是将视频旋转 180 度!!顺便说一句,我尝试处理的视频实例最初是由 UIImagePicker 在“压缩”期间使用videoQuality = UIImagePickerControllerQualityType640x480 创建的,这实际上会在 iPad mini 上生成 568 x 320 的视频。

我在AVAssetExportSession 上尝试了各种presetName 设置,但我无法获得想要的结果。通过使用AVAssetExportPresetMediumQuality,我得到的文件大小最接近的是4.1MB(即与源完全相同!),但是这也将结果视频的尺寸减少到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"

除此之外,我尝试为 AVAssetReaderTrackOutput 的 outputSettings 传递 nil,根据标题信息应该可以:

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,我的目标是 iOS5 以上的所有内容,使用 ARC。

【问题讨论】:

    标签: ios objective-c ipad video avassetwriter


    【解决方案1】:

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

    1. 假设 writerInput 是 AVAssetWriterInput 的对象实例,assetTrack 是 AVAssetTrack 的实例,那么您的转换问题可以通过以下方式解决:

    writerInput.transform =assetTrack.preferredTransform;

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

      if (sampleBuffer = [asset_reader_output copyNextSampleBuffer]) { BOOL 结果 = [writerInput appendSampleBuffer:sampleBuffer]; CFRelease(sampleBuffer); // 释放样本缓冲区! }

    【讨论】:

      【解决方案2】:

      编译错误是我不包括CoreVideo.framework造成的。一旦我包含并导入它,我就可以编译代码。此外,代码可以运行并生成视频,我发现了 2 个新问题:

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

        CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer];
        

      我真的可以得到一些帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-12
        • 1970-01-01
        • 2011-12-23
        相关资源
        最近更新 更多