导出时转换不在AVMutableVideoComposition中工作 [英] Transform not working in AVMutableVideoComposition while exporting

查看:168
本文介绍了导出时转换不在AVMutableVideoComposition中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是组合从相机录制的一组剪辑,并以特定的首选尺寸导出它们。当然,在导出之前需要旋转视频方向。

My goal is to compose a set of clips recorded from the camera and export them at a certain preferred size. Of course, the video orientation needs to be rotated before exporting.

我是通过从存储在下面的avAssets中的视频剪辑数组合成AVMutableComposition来实现的。我可以把它们组合好,并将其导出。但是,我在AVMutableVideoComposition上设置的旋转变换不受尊重。如果我使用相同的转换并将其设置在视频轨道的preferredTransform属性上,那么它可以工作。在这两种情况下,视频renderSize都没有被尊重。这就好像导出器完全忽略了videoComposition。有什么想法会发生什么?

I'm doing this by composing an AVMutableComposition from an array of video clips, stored in avAssets below. I am able to compose them fine, and export it. However, the rotation transform I am setting on the AVMutableVideoComposition is not being honored. If I use the same transform and set it on the preferredTransform property of the video track, then it works. In both cases, the video renderSize is not being honored. It's as if the exporter ignores the videoComposition completely. Any ideas what could be happening?

我确实有一个AVCaptureSession正在运行,但我在导出之前将其关闭,这没有任何区别。我对iOS编程很新,所以我可能会遗漏一些基本的东西。 :)

I do have an AVCaptureSession running, but I turned it off before exporting and that didn't make any difference. I am fairly new to iOS programming, so it could be I'm missing something basic. :)

我的代码:

-(void) finalRecord{
NSError *error = nil;

AVMutableComposition *composition = [AVMutableComposition composition];

AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSLog(@"Video track id is %d", [compositionVideoTrack trackID]);

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

// avAssets hold the video clips to be composited
int pieces = [avAssets count];

CGAffineTransform transform = CGAffineTransformMakeRotation( M_PI_2);
//  [compositionVideoTrack setPreferredTransform:transform];

for (int i = 0; i<pieces; i++) {

    AVURLAsset *sourceAsset = [avAssets objectAtIndex:i];

    AVAssetTrack *sourceVideoTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    AVAssetTrack *sourceAudioTrack = [[sourceAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

    [timeRanges addObject:[NSValue valueWithCMTimeRange:CMTimeRangeMake(kCMTimeZero, sourceAsset.duration)]];
    [videoTracks addObject:sourceVideoTrack];
    [audioTracks addObject:sourceAudioTrack];
}

[compositionVideoTrack insertTimeRanges:timeRanges ofTracks:videoTracks atTime:kCMTimeZero error:&error];
[compositionAudioTrack insertTimeRanges:timeRanges ofTracks:audioTracks atTime:kCMTimeZero error:&error];

AVMutableVideoCompositionInstruction *vtemp = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
vtemp.timeRange = CMTimeRangeMake(kCMTimeZero, [composition duration]);
NSLog(@"\nInstruction vtemp's time range is %f %f", CMTimeGetSeconds( vtemp.timeRange.start),
      CMTimeGetSeconds(vtemp.timeRange.duration));

// Also tried videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack    
AVMutableVideoCompositionLayerInstruction *vLayerInstruction = [AVMutableVideoCompositionLayerInstruction
                                                               videoCompositionLayerInstructionWithAssetTrack:composition.tracks[0]];
[vLayerInstruction setTransform:transform atTime:kCMTimeZero];
vtemp.layerInstructions = @[vLayerInstruction];

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.renderSize = CGSizeMake(320.0, 240.0);
videoComposition.frameDuration = CMTimeMake(1,30);

videoComposition.instructions = @[vtemp];

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

NSParameterAssert(exporter != nil);
exporter.videoComposition = videoComposition;
exporter.outputFileType = AVFileTypeQuickTimeMovie;

NSString *rootName = [[self captureManager] tempFileRoot];

NSString *temp = [NSString stringWithFormat:@"%@%@.mov", NSTemporaryDirectory(), rootName];
exporter.outputURL = [NSURL fileURLWithPath:temp ];

[exporter exportAsynchronouslyWithCompletionHandler:^{
    switch ([exporter status]) {
        case AVAssetExportSessionStatusFailed:
            NSLog(@"Export failed: %@", [exporter error]);
            break;
        case AVAssetExportSessionStatusCancelled:
            NSLog(@"Export canceled");
            break;
        case AVAssetExportSessionStatusCompleted:
            NSLog(@"Export successfully");
            [self exportFile:exporter.outputURL];
            [self.delegate recordingEndedWithFile:exporter.outputURL];
            isExporting = FALSE;
            [[[self captureManager] session] startRunning];
            break;
        default:
            break;
    }
    if (exporter.status != AVAssetExportSessionStatusCompleted){
        NSLog(@"Retry export");
    }
}];

}


推荐答案

好的它出来并发布在这里,以帮助其他人不浪费我的时间。

Ok figured it out and posting here to help other people not waste the time that I did.

问题是如果你使用 AVAssetExportPresetPassthrough AVExportSession 上,然后导出器将忽略视频组合指令。我希望它在通过格式等时至少尊重视频合成指令,但显然这不是它的工作原理。填写文档错误后,您可以在 Technical Q& A

The issue is that if you use AVAssetExportPresetPassthrough on an AVExportSession, then the exporter will ignore the video composition instructions. I was expecting it to at least honor the video composition instructions while passing through the format etc. but apparently that isn't how it works. After I have filled a documentation bug, you can find it in Technical Q&A.

这篇关于导出时转换不在AVMutableVideoComposition中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆