如何控制与AVMutableComposition组装的视频方向
我正在装配一大堆在iPhone上纵向模式拍摄的视频剪辑。组装它们,我采取简单的方法如下:如何控制与AVMutableComposition组装的视频方向
AVURLAsset得到的不同的视频,然后顺手把这些成AVMutableCompositionTrack,然后把这个放入其中我出口与AVAssetExportSession
提交的AVMutableComposition握住我的问题是当我在UIWebView中显示视频时,它出现在横向模式下。但是,如果我查看它们在纵向视图中显示的任何组件视图。有谁知道如何理清方向。我试着用AVMutableComposition的自然尺寸来改变周围的宽度和高度,但这只是让我的人看起来很矮很胖! (而在其侧)
预先感谢任何想法/建议
铎
安装视频组合,将处理旋转+规模:
AVMutableVideoComposition* videoComposition = [[AVMutableVideoComposition videoComposition]retain];
videoComposition.renderSize = CGSizeMake(320, 240);
videoComposition.frameDuration = CMTimeMake(1, 30);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30));
AVMutableVideoCompositionLayerInstruction* rotator = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]];
CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation(0,-320);
CGAffineTransform rotateBy90Degrees = CGAffineTransformMakeRotation(M_PI_2);
CGAffineTransform shrinkWidth = CGAffineTransformMakeScale(0.66, 1); // needed because Apple does a "stretch" by default - really, we should find and undo apple's stretch - I suspect it'll be a CALayer defaultTransform, or UIView property causing this
CGAffineTransform finalTransform = CGAffineTransformConcat(shrinkWidth, CGAffineTransformConcat(translateToCenter, rotateBy90Degrees));
[rotator setTransform:finalTransform atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObject: rotator];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
下面是一些代码,调整使用优选变换的旋转:
// our composition, with one video and one audio track
AVMutableComposition* composition = [AVMutableComposition composition];
AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
// loop through all the clips, adding them to our track and inserting composition instructions
NSDictionary* options = @{ AVURLAssetPreferPreciseDurationAndTimingKey: @YES };
CMTime insertionPoint = kCMTimeZero;
NSMutableArray* instructions = [NSMutableArray array];
NSError* error = nil;
for (NSURL* outputFileURL in self.movieFileURLs) {
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:outputFileURL options:options];
// insert this clip's video track into our composition
NSArray *videoAssetTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *videoAssetTrack = (videoAssetTracks.count > 0 ? [videoAssetTracks objectAtIndex:0] : nil);
[videoTrack insertTimeRange:CMTimeRangeFromTimeToTime(kCMTimeZero, asset.duration) ofTrack:videoAssetTrack atTime:insertionPoint error:&error];
// create a layer instruction at the start of this clip to apply the preferred transform to correct orientation issues
AVMutableVideoCompositionLayerInstruction *instruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack];
[instruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];
// create the composition instructions for the range of this clip
AVMutableVideoCompositionInstruction * videoTrackInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
videoTrackInstruction.timeRange = CMTimeRangeMake(insertionPoint, asset.duration);
videoTrackInstruction.layerInstructions = @[instruction];
[instructions addObject:videoTrackInstruction];
// insert this clip's audio track into our composition
NSArray *audioAssetTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack *audioAssetTrack = (audioAssetTracks.count > 0 ? [audioAssetTracks objectAtIndex:0] : nil);
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:audioAssetTrack atTime:insertionPoint error:nil];
// advance the insertion point to the end of the clip
insertionPoint = CMTimeAdd(insertionPoint, asset.duration);
}
// create our video composition which will be assigned to the player item
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.instructions = instructions;
videoComposition.frameDuration = CMTimeMake(1, videoTrack.naturalTimeScale);
videoComposition.renderSize = videoTrack.naturalSize;
_videoComposition = videoComposition;
我一直在尝试在我的应用程序中使用这段代码片段,我将一些视频剪辑合并到一个视频中,并使用'AVAssetExportSession'将其导出。但是,当我将'AVAssetExportSession'的'videoComposition'属性设置为'AVMutableVideoComposition'的实例时,出现错误。你知道如何在导出电影时使用你的代码吗?我在这里提出了一个问题,如果你有时间,你可以看看吗? http://stackoverflow.com/questions/16385017/error-when-using-avassetexportsession-with-video-composition-set – simonbs 2013-05-06 17:09:59
@simonbs是否能够得到它的工作? – 2015-06-15 18:46:13
如果全部你想保存你的视频方向,你可能想分配AVMutableCompositionTrack preferredTransition价值从AVAssetTrack像这样:
AVAssetTrack *videoAssetTrack= [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject];
AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoAssetTrack atTime:kCMTimeZero error:&error];
videoCompositionTrack.preferredTransform = videoAssetTrack.preferredTransform;
任何人甚至知道如何存储原始方向? – Tudor 2010-11-16 18:44:25
资产跟踪中有一个originalTransform属性,您可以在某些情况下设置该属性。 – Hunter 2011-03-08 18:40:37