使用AVAssetExportSession旋转AVAsset

8

我正在尝试使用AVAssetExportSession将视频旋转到正确的方向,但我总是收到以下错误:

Error Domain=AVFoundationErrorDomain Code=-11841 "The operation couldn’t be completed. (AVFoundationErrorDomain error -11841.)"

这意味着AVErrorInvalidVideoComposition,但我无法找到我的视频合成有任何问题。以下是代码:

AVAssetTrack *sourceVideo = [[avAsset tracksWithMediaType:AVMediaTypeVideo] lastObject];
AVAssetTrack *sourceAudio = [[avAsset tracksWithMediaType:AVMediaTypeAudio] lastObject];
CGAffineTransform preferredTransform = [sourceVideo preferredTransform];

AVMutableComposition *composition = [[AVMutableComposition alloc] init];

AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                            preferredTrackID:kCMPersistentTrackID_Invalid];

AVAssetExportSession *exporter = [[[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality] autorelease];

[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration)
                               ofTrack:sourceVideo
                                atTime:kCMTimeZero
                                 error:nil];

if( !CGAffineTransformIsIdentity(preferredTransform) ) {

    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.renderSize = CGSizeMake([avAsset naturalSize].height, [avAsset naturalSize].width);
    videoComposition.frameDuration = CMTimeMake(1, compositionVideoTrack.naturalTimeScale);

    AVMutableVideoCompositionLayerInstruction *instruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:sourceVideo];
    [instruction setTransform:preferredTransform atTime:kCMTimeZero];

    AVMutableVideoCompositionInstruction *videoTrackInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    videoTrackInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, avAsset.duration);
    videoTrackInstruction.layerInstructions = [NSArray arrayWithObject:instruction];

    [videoComposition setInstructions:[NSArray arrayWithObject:videoTrackInstruction]];

    exporter.videoComposition = videoComposition;
}

AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                            preferredTrackID:kCMPersistentTrackID_Invalid];

[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset.duration)
                               ofTrack:sourceAudio
                                atTime:kCMTimeZero
                                 error:nil];

exporter.outputURL = tempPathUrl;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
[exporter exportAsynchronouslyWithCompletionHandler:^{ }];

这篇文章有什么问题吗?我已经查阅了文档,但目前还没有发现任何问题。


1
你最终找出来为什么会出现那个错误了吗? - shabbirv
好的,看起来赏金的一半将会给GingerBreadMane,而他的回答并没有起作用。似乎在StackOverflow上并没有真正的iOS开发者社区,这很遗憾。 - Gabi Purcaru
在iOS 7.0.3上遇到了类似的问题...我的代码很相似,当我使用刚录制的视频时可以正常工作,但是当我选择库中的视频时就会失败。这对我来说几乎没有意义。如果找到解决方案,我会告诉你的。可能不得不放弃使用AVExportSession。 - DogpatchTech
3个回答

0
我觉得是因为宽度和高度参数的顺序不正确。 你有:
    videoComposition.renderSize = CGSizeMake([avAsset naturalSize].height, [avAsset naturalSize].width);

这不应该是这样吗?

    videoComposition.renderSize = CGSizeMake([avAsset naturalSize].width, [avAsset naturalSize].height);

instead?


0
可能与您的帧持续时间有关。您正在使用 CMTimeMake(1,naturalTimeScale)
您应该检查naturalTimeScale,因为它并不总是等于fps。有关更多信息,请参见{{link1:AVFoundation编程指南}}“时间表示”部分。

你知道如何获取视频资产的FPS吗? - Crashalot

0

错误出在您设置 instruction 的方式上。

... videoCompositionLayerInstructionWithAssetTrack:sourceVideo]

sourceVideo不是合成的成员。在您的情况下,应该是compositionVideoTrack


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