我正在尝试在iOS 4.3上使用AVMutableComposition,AVMutableVideoComposition和AVVideoCompositionCoreAnimationTool,将CALayer制作成纵向模式视频(导出).这一切都在景观中起作用.然而,如果我以纵向拍摄视频,则AVVideoCompositionCoreAnimationTool忽略了视频轨道上的变换.也就是说,对于纵向模式视频,我将AVMutableCompositionTrack.preferredTransform设置为原始资源视频轨道的preferredTransform值.只要我不使用AVVideoCompositionCoreAnimationTool,这是有效的,视频以纵向模式出现.然而,一旦添加了AVVideoCompositionCoreAnimationTool和CALayer,文件就会出现. (CALayer正确显示,但其后面的视频在其侧面,文件的宽高比关闭).我已经尝试将变换应用于CALayer,并在ACVideoComposition中设置变换.这两个都不会改变文件的方向(它仍然是480×369,而不是360×480).有没有办法使用AVVideoCompositionCoreAnimationTool渲染纵向模式视频?
首先我设置一个AVMutableComposition和AVMutableVideoComposition
AVMutableComposition *composition = [AVMutableComposition composition]; AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:url options:nil]; CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero,[videoAsset duration]); AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; CGSize videoSize = CGSizeApplyAffineTransform(clipVideoTrack.naturalSize,clipVideoTrack.preferredTransform); videoSize.width = fabs(videoSize.width); videoSize.height = fabs(videoSize.height); CMTime titleDuration = CMTimeMakeWithSeconds(5,600); CMTimeRange titleRange = CMTimeRangeMake(kCMTimeZero,titleDuration); [compositionVideoTrack insertTimeRange:titleRange ofTrack:nil atTime:kCMTimeZero error:nil]; [compositionVideoTrack insertTimeRange:timeRange ofTrack:clipVideoTrack atTime:titleDuration error:nil]; compositionVideoTrack.preferredTransform = clipVideoTrack.preferredTransform; AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; passThroughInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,[composition duration]); AVAssetTrack *videoTrack = [[composition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; passThroughInstruction.layerInstructions = [NSArray arrayWithObject:passThroughLayer]; videoComposition.instructions = [NSArray arrayWithObject:passThroughInstruction]; videoComposition.frameDuration = CMTimeMake(1,30); videoComposition.renderSize = videoSize; videoComposition.renderScale = 1.0;
和一个标题的CALayer
CALayer *animationLayer = [CALayer layer]; animationLayer.bounds = CGRectMake(0,videoSize.width,videoSize.height); CATextLayer *titleLayer = [CATextLayer layer]; titleLayer.string = [effect valueForKey:@"title"]; titleLayer.font = [effect valueForKey:@"font"]; titleLayer.fontSize = 30; titleLayer.alignmentMode = kCAAlignmentCenter; titleLayer.bounds = CGRectMake(0,videoSize.height / 6); [animationLayer addSublayer:titleLayer]; titleLayer.anchorPoint = CGPointMake(0.5,0.5); titleLayer.position = CGPointMake(CGRectGetMidX(layer.bounds),CGRectGetMidY(layer.bounds)); CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; fadeAnimation.fromValue = [NSNumber numberWithFloat:1.0]; fadeAnimation.toValue = [NSNumber numberWithFloat:0.0]; fadeAnimation.additive = NO; fadeAnimation.removedOnCompletion = NO; fadeAnimation.beginTime = 3.5; fadeAnimation.duration = 1.0; fadeAnimation.fillMode = kCAFillModeBoth; [titleLayer addAnimation:fadeAnimation forKey:nil];
最后,我将CALayer添加到AVMutableVideoComposition
CALayer *parentLayer = [CALayer layer]; CALayer *videoLayer = [CALayer layer]; parentLayer.bounds = CGRectMake(0,videoSize.height); parentLayer.anchorPoint = CGPointMake(0,0); parentLayer.position = CGPointMake(0,0); videoLayer.bounds = CGRectMake(0,videoSize.height); [parentLayer addSublayer:videoLayer]; videoLayer.anchorPoint = CGPointMake(0.5,0.5); videoLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds),CGRectGetMidY(parentLayer.bounds)); [parentLayer addSublayer:layer]; animationLayer.anchorPoint = CGPointMake(0.5,0.5); animationLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds),CGRectGetMidY(parentLayer.bounds)); videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
并出口!
AVAssetExportSession *exportSession = [[[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality] autorelease]; exportSession.videoComposition = videoComposition; NSURL *segmentFileURL = //some local URL exportSession.outputFileType = @"com.apple.quicktime-movie"; exportSession.outputURL = segmentFileURL; [exportSession exportAsynchronouslyWithCompletionHandler:^{ switch ([exportSession status]) { case AVAssetExportSessionStatusFailed: Log(@"Export Failed: %@",[exportSession error]); break; case AVAssetExportSessionStatusCancelled: Log(@"Export canceled"); break; case AVAssetExportSessionStatusCompleted: Log(@"Export done"); break; } }];
此代码在横向模式下工作,并且如果我删除行,也以纵向方式.Composition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
解决方法
尝试这样做,并添加您的其他说明.
///turn video 90 degrees AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack]; CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0)); CGAffineTransform rotateTranslate = CGAffineTransformTranslate(rotationTransform,320,0); [passThroughLayer setTransform:rotateTranslate atTime:kCMTimeZero];
让我知道如何去!
MacMike