3

更改视频格式的好方法是什么?

我正在做这样的事情来合并多个视频并使用 AVAssetExportSession 导出它们:

AVMutableComposition *mixComposition = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    NSError * error = nil;
    AVURLAsset *assetClip;
    AVAssetTrack *clipVideoTrack;
    AVAssetTrack *clipAudioTrack;
    for (int i = [clipPaths count]-1; i >= 0; i--) {
        assetClip = [AVURLAsset URLAssetWithURL:[clipPaths objectAtIndex:i] options:nil];
        clipVideoTrack = [[assetClip tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        clipAudioTrack = [[assetClip tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

        [compositionVideoTrack insertTimeRange:clipVideoTrack.timeRange ofTrack:clipVideoTrack atTime:kCMTimeZero error:&error];
        [compositionAudioTrack insertTimeRange:clipAudioTrack.timeRange ofTrack:clipAudioTrack atTime:kCMTimeZero error:&error];
    } 

    NSString *cachesFolder = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/"];
    NSString *finalPath = [cachesFolder stringByAppendingPathComponent:[self.currentFileName stringByAppendingString:@".mov"]];

    // Remove video file if it exists 
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if([fileManager fileExistsAtPath:finalPath]) {
        [fileManager removeItemAtPath:finalPath error:&error];
    }

    NSURL *lastURL = [NSURL fileURLWithPath:finalPath];

    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality];
    exporter.outputFileType = AVFileTypeQuickTimeMovie;
    exporter.outputURL = lastURL;
    [exporter exportAsynchronouslyWithCompletionHandler:^(void){
        switch(exporter.status) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"exporting failed"); 
                break;
            case AVAssetExportSessionStatusCompleted:
                NSLog(@"exporting completed"); 
                [[NSNotificationCenter defaultCenter] postNotificationName:@"didCompleteMovieMerging" object:nil];
                break;
            case AVAssetExportSessionStatusCancelled:
                NSLog(@"export cancelled");
                break;
        }
    }];

我看到你可以使用

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

而不是 AVAssetExportSession,但我找不到让这两者一起工作的方法。

4

2 回答 2

3

您可以设置 exporter.videoComposition = videoComposition。我从来没有尝试在没有 layerInstructions 的情况下传递它,但不确定它会如何起作用。

Buuut 即使您更改渲染大小,我认为您也不能用它来裁剪框架,如果这是您想要实现的。从理论上讲,它会将您的框架压缩到该渲染大小中。也许我错了,所以测试一下。

到目前为止,我能找到的最快方法是使用 AVAssetWriter 及其一对键 - [NSString stringWithString:AVVideoScalingModeResizeAspectFill], AVVideoScalingModeKey - 将裁剪为您传递的任何大小,但无需控制裁剪位置

于 2013-09-14T04:01:32.560 回答
0

您没有给出用于在录制视频时预览视频的 AVCaptureVideoPreviewLayer 的框架,但我从问题的标题中猜测它是方形的。您可以使用此值(或您希望视频最终达到的任何尺寸)来计算 CGAffineTransform 以在将其拼接成整体之前应用于每个轨道。

有关此操作的一个很好的示例,请参见:

https://github.com/carsonmcdonald/iOSVideoCameraMultiStitchExample

于 2014-10-07T22:37:58.857 回答