[英]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: 这可能会帮助有类似问题的人:
writerInput.transform = assetTrack.preferredTransform; writerInput.transform = assetTrack.preferredTransform;
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个新问题:
transform
property on AVAssetWriterInput
. 我无法使用AVAssetWriterInput
上的transform
属性使变换工作。 This means that I'm stuck with using a AVMutableVideoCompositionInstruction
and AVAssetExportSession
for the transformation. 这意味着我坚持使用AVMutableVideoCompositionInstruction
和AVAssetExportSession
进行转换。 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.