简体   繁体   English

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

[英]How to use AVAssetWriter instead of AVAssetExportSession to re-encode existing video

I'm trying to re-encode videos on an iPad which were recorded on that device but with the "wrong" orientation. 我正在尝试重新编码iPad上的视频,这些视频记录在该设备上,但方向“错误”。 This is because when the file is converted to an MP4 file and uploaded to a web server for use with the "video" HTML5 tag, only Safari seems to render the video with the correct orientation. 这是因为当文件转换为MP4文件并上传到Web服务器以与“视频”HTML5标记一起使用时,只有Safari似乎以正确的方向呈现视频。

Basically, I've managed to implement what I wanted by using a AVMutableVideoCompositionLayerInstruction , and then using AVAssetExportSession to create the resultant video with audio. 基本上,我已经设法通过使用AVMutableVideoCompositionLayerInstruction实现我想要的,然后使用AVAssetExportSession创建带有音频的结果视频。 However, the problem is that the file sizes jump up considerably after doing this, eg correcting an original file of 4.1MB results in a final file size of 18.5MB! 但是,问题是文件大小在执行此操作后会大幅跳跃,例如,更正4.1MB的原始文件会导致最终文件大小为18.5MB! All I've done is rotate the video through 180 degrees!! 我所做的就是将视频旋转180度!! Incidentally, the video instance that I'm trying to process was originally created by the UIImagePicker during "compression" using videoQuality = UIImagePickerControllerQualityType640x480 , which actually results in videos of 568 x 320 on an iPad mini. 顺便提一下,我正在尝试处理的视频实例最初是由UIImagePicker在“压缩”期间使用videoQuality = UIImagePickerControllerQualityType640x480 ,这实际上会在iPad mini上生成568 x 320的视频。

I experimented with the various presetName settings on AVAssetExportSession but I couldn't get the desired result. 我在AVAssetExportSession上尝试了各种presetName设置,但是我无法获得所需的结果。 The closest I got filesize-wise was 4.1MB (ie exactly the same as source!) by using AVAssetExportPresetMediumQuality , BUT this also reduced the dimensions of the resultant video to 480 x 272 instead of the 568 x 320 that I had explicitly set. 我得到了文件大小明智的最接近的是4.1MB(即完全一样出处!)通过使用AVAssetExportPresetMediumQuality但这也降低了合成视频的尺寸480 * 272,而不是568×320,我已经明确设置。

So, this led me to look into other options, and hence using AVAssetWriter instead. 所以,这导致我调查其他选项,因此使用AVAssetWriter The problem is, I can't get any code that I have found to work! 问题是,我找不到任何我发现的代码! I tried the code found on this SO post ( Video Encoding using AVAssetWriter - CRASHES ), but can't get it to work. 我尝试了在这个SO帖子上找到的代码( 使用AVAssetWriter的视频编码 - CRASHES ),但无法使其工作。 For a start, I get a compilation error for this line: 首先,我得到了这一行的编译错误:

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

The resultant compilation error being: 结果编译错误是:

Undefined symbols for architecture armv7: "_kCVPixelBufferPixelFormatTypeKey"

This aside, I tried passsing in nil for the AVAssetReaderTrackOutput's outputSettings , which should be OK according to header info: 除此之外,我尝试使用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.

However, I then get a crash happening at this line: 但是,然后我在这一行发生了崩溃:

BOOL result = [videoWriterInput appendSampleBuffer:sampleBuffer];

In short, I've not been able to get any code to work with AVAssetWriter , so I REALLY need some help here. 简而言之,我无法使用任何代码来使用AVAssetWriter ,所以我真的需要一些帮助。 Are there any other ways to achieve my desired results? 有没有其他方法可以达到我想要的效果? Incidentally, I'm using Xcode 4.6 and I'm targeting everything from iOS5 upwards, using ARC. 顺便说一句,我正在使用Xcode 4.6,而且我使用ARC来定位iOS5以上的所有内容。

I have solved similar problems related to your questions. 我已经解决了与您的问题相关的类似问题。 This might help someone who has similar problems: 这可能会帮助有类似问题的人:

  1. Assuming writerInput is your object instance of AVAssetWriterInput and assetTrack is the instance of your AVAssetTrack, then your transform problem is solved by simply: 假设writerInput是AVAssetWriterInput的对象实例,而assetTrack是AVAssetTrack的实例,那么您的转换问题可以通过以下方式解决:

writerInput.transform = assetTrack.preferredTransform; writerInput.transform = assetTrack.preferredTransform;

  1. You have to release sampleBuffer after appending your sample buffer, so you would have something like: 你必须在附加样本缓冲区后释放sampleBuffer,所以你会得到类似的东西:

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

The compilation error was caused by me not including the CoreVideo.framework . 编译错误是由于我不包括CoreVideo.framework引起的。 As soon as I had included that and imported it, I could get the code to compile. 只要我包含它并导入它,我就可以获得编译代码。 Also, the code would work and generate a resultant video, but I uncovered 2 new problems: 此外,代码将工作并生成结果视频, 我发现了2个新问题:

  1. I can't get the transform to work using the transform property on AVAssetWriterInput . 我无法使用AVAssetWriterInput上的transform属性使变换工作。 This means that I'm stuck with using a AVMutableVideoCompositionInstruction and AVAssetExportSession for the transformation. 这意味着我坚持使用AVMutableVideoCompositionInstructionAVAssetExportSession进行转换。
  2. If I use AVAssetWriter to just handle compression (seeing as I don't have many options with AVAssetExportSession ), I still have a bad memory leak. 如果我使用AVAssetWriter来处理压缩(因为我没有很多选项与AVAssetExportSession ),我仍然有一个糟糕的内存泄漏。 I've tried everything I can think of, starting with the solution in this link ( Help Fix Memory Leak release ) and also with @autorelease blocks at key points. 我已经尝试了我能想到的一切,从这个链接中的解决方案( 帮助修复内存泄漏版本 )开始,并在关键点使用@autorelease块。 But it seems that the following line will cause a leak, no matter what I try: 但是无论我尝试什么,似乎以下行都会导致泄漏:

     CMSampleBufferRef sampleBuffer = [asset_reader_output copyNextSampleBuffer]; 

I could really do with some help. 我真的可以帮忙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用AVAssetWriter重新编码H264 mov文件-如何设置帧频? - Using AVAssetWriter to re-encode H264 mov file - how to set frame-rate? 如何在视频上添加叠加文字,然后重新编码? - How can I add overlay text on a video, then re-encode it? AVAssetWriter损坏了由AVAssetExportSession修剪的视频 - AVAssetWriter corrupting the video trimmed by AVAssetExportSession 使用AVAssetWriter而不是AVAssetExportSession导出AVMutableVideoComposition - Export a AVMutableVideoComposition using AVAssetWriter instead of AVAssetExportSession 如何同时将 AVAssetReader 和 AVAssetWriter 用于多个轨道(音频和视频)? - How to use AVAssetReader and AVAssetWriter for multiple tracks (audio and video) simultaneously? Swift和AVAssetExportSession:为Chrome和HTML5编码MP4视频 - Swift & AVAssetExportSession : encode MP4 video for Chrome and HTML5 我如何使用AVAssetWriter? - How do I use AVAssetWriter? 如何将视频从AVAssetExportSession保存到相机胶卷? - How to save a video from AVAssetExportSession to Camera Roll? AVAssetExportSession - 如何从视频持续时间中修剪毫秒 - AVAssetExportSession -how to trim millisecond from video duration 如何使用AVAssetWriter为视频添加静态和动态叠加层? - How to add static and dynamic overlays to video with AVAssetWriter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM