AVMutableComposition视频创建问题

15

我正在使用AVMutableComposition创建视频,并使用AVAssetExportSession导出,设置预设值为AVAssetExportPresetHighestQuality

当视频的分辨率较小时,视频创建得很好。但是当视频分辨率较大(例如1280×1920)时,视频没有正确创建。会添加绿色叠加层到视频中,如下图所示:

enter image description here

但是当我使用AVAssetExportPresetPassthrough而不是AVAssetExportPresetHighestQuality时,视频创建正常。

有什么想法是为什么会发生这种情况吗?

谢谢!


3
请提供更多细节。关于资产,您是否正在合并资产或类似操作? - Maverick
这个问题是特定于Retina iPad吗? - Sumeet
1
补充一下@Maverick的问题,这些资产是通过编程创建的吗?如果是,是在您自己的应用程序内部创建的,还是从其他地方导入的? - David Cairns
1个回答

2

尝试这段代码:

-(void)convertVideo:(NSString *)videoPath{
        AVURLAsset *firstAsset=[[AVURLAsset alloc]initWithURL:[NSURL URLWithString:    [NSString stringWithFormat:@"%@", videoPath]] options:nil];
        AVMutableComposition* mixComposition = [[AVMutableComposition alloc] init];

        //VIDEO TRACK
        AVMutableCompositionTrack *firstTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

        [firstTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, firstAsset.duration) ofTrack:[[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];

        AVMutableVideoCompositionInstruction * MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
        MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, firstAsset.duration);

        CMTime audioTime = kCMTimeIndefinite;
        CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, firstAsset.duration);

        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
        [audioSession setActive:YES error:nil];

        if (OS_VERSION>=7) {
            if (firstAsset!=NULL) {
                AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

                [compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, firstAsset.duration) ofTrack:[[firstAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
            }
        }
        else{
            AVMutableCompositionTrack *b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
            [b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[firstAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:audioTime error:nil];
        }

        //FIXING ORIENTATION//
        AVMutableVideoCompositionLayerInstruction *FirstlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:firstTrack];

        AVAssetTrack *FirstAssetTrack = [[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        UIImageOrientation FirstAssetOrientation_  = UIImageOrientationUp;
        BOOL  isFirstAssetPortrait_  = NO;
        CGAffineTransform firstTransform = FirstAssetTrack.preferredTransform;

        if(firstTransform.a == 0 && firstTransform.b == 1.0 && firstTransform.c == -1.0 && firstTransform.d == 0){
            FirstAssetOrientation_= UIImageOrientationRight;
            isFirstAssetPortrait_ = YES;
        }
        if(firstTransform.a == 0 && firstTransform.b == -1.0 && firstTransform.c == 1.0 && firstTransform.d == 0){
            FirstAssetOrientation_ =  UIImageOrientationLeft;
            isFirstAssetPortrait_ = YES;
        }
        if(firstTransform.a == 1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == 1.0){
            FirstAssetOrientation_ =  UIImageOrientationUp;
        }
        if(firstTransform.a == -1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == -1.0){
            FirstAssetOrientation_ = UIImageOrientationDown;
        }

        [FirstlayerInstruction setOpacity:0.0 atTime:firstAsset.duration];

        CGFloat FirstAssetScaleToFitRatio = 0;


        MainInstruction.layerInstructions = [NSArray arrayWithObjects:FirstlayerInstruction,nil];

        AVMutableVideoComposition *MainCompositionInst = [AVMutableVideoComposition videoComposition];
        MainCompositionInst.instructions = [NSArray arrayWithObject:MainInstruction];
        MainCompositionInst.frameDuration = CMTimeMake(1, 30);

        /*if(isFirstAssetPortrait_){
            FirstAssetScaleToFitRatio = 0.67;
            CGAffineTransform FirstAssetScaleFactor = CGAffineTransformMakeScale(FirstAssetScaleToFitRatio,FirstAssetScaleToFitRatio);
            [FirstlayerInstruction setTransform:CGAffineTransformConcat(FirstAssetTrack.preferredTransform, FirstAssetScaleFactor) atTime:kCMTimeZero];
            naturalSizeFirst = CGSizeMake(FirstAssetTrack.naturalSize.height, FirstAssetTrack.naturalSize.width);
            }else{

                naturalSizeFirst = FirstAssetTrack.naturalSize;
        }
         */

        CGSize naturalSizeFirst;
        if(isFirstAssetPortrait_){
            FirstAssetScaleToFitRatio = FirstAssetTrack.naturalSize.width/FirstAssetTrack.naturalSize.height;
            CGAffineTransform FirstAssetScaleFactor = CGAffineTransformMakeScale(FirstAssetScaleToFitRatio,FirstAssetScaleToFitRatio);
            [FirstlayerInstruction setTransform:CGAffineTransformConcat(FirstAssetTrack.preferredTransform, FirstAssetScaleFactor) atTime:kCMTimeZero];
            naturalSizeFirst = CGSizeMake(FirstAssetTrack.naturalSize.height, FirstAssetTrack.naturalSize.width);

        }else {
            naturalSizeFirst = FirstAssetTrack.naturalSize;
        }

        MainCompositionInst.renderSize = CGSizeMake(naturalSizeFirst.width, naturalSizeFirst.height);

        NSString *tmpDirectory = NSTemporaryDirectory();
        NSString *fname = [NSString stringWithFormat:@"mergeVideo-%d.mov",arc4random() % 1000];
        NSString *tmpFile = [tmpDirectory stringByAppendingPathComponent:fname];

        NSURL *url = [NSURL fileURLWithPath:tmpFile];

        AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
        exporter.outputURL=url;
        exporter.outputFileType = AVFileTypeQuickTimeMovie;
        exporter.videoComposition = MainCompositionInst;
        exporter.shouldOptimizeForNetworkUse = YES;

        [exporter exportAsynchronouslyWithCompletionHandler:^{

            if (AVAssetExportSessionStatusCompleted == exporter.status) {
                [self.progressStatus setText:@"Converted..."];

                selectedVideo = selectedVideo+1;
            } else if (AVAssetExportSessionStatusFailed == exporter.status) {
                // a failure may happen because of an event out of your control
                // for example, an interruption like a phone call comming in
                // make sure and handle this case appropriately
                //ALog(@"AVAssetExportSessionStatusFailed %@",exporter.error);

            } else {
                //ALog(@"Export Session Status: %d", exporter.status);
            }
        }];
    }
}

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