旋转videow / AVMutableVideoCompositionLayerInstruction

我正在使用前置摄像头在iPhone 4上拍摄video,并将video与其他媒体资源相结合。 我希望这个video是纵向的 – 所有video的默认方向是横向,在某些情况下,您必须手动pipe理。

我正在使用AVFoundation,特别是AVAssetExportSession AVMutableVideoComposition。 根据WWDC的video,很明显,当我将video合成为新的作品时,我必须自己处理“修复”方向。

所以,我创build了一个AVMutableVideoCompositionLayerInstruction附加到我的AVMutableVideoCompositionInstruction,我使用setTransform:atTime:方法来设置一个转换devise旋转video:

AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; CGAffineTransform portraitRotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0)); [passThroughLayer setTransform:portraitRotationTransform atTime:kCMTimeZero]; 

问题是,当我查看导出的video时,屏幕上没有任何实际的内容。 如果我将旋转angular度减小到45度,我可以在屏幕上看到部分video,就好像它不在中心点旋转一样。 我在下面列出了一些图片,以便更清楚我在说什么。

video的自然大小回到480×360。 我已经尝试将其改为360×480,并且不会影响核心问题。

0度旋转:

在这里输入图像说明

45度旋转:

在这里输入图像说明

90度旋转只是全部绿色。

无论如何,我希望以前做过这个的人能指点我的方向。 我无法findAVFoundation组合和导出中某些更高级主题的任何文档。

尝试这个:

 AVMutableVideoCompositionLayerInstruction *passThroughLayer = AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0)); CGAffineTransform rotateTranslate = CGAffineTransformTranslate(rotateTransform,320,0); [passThroughLayer setTransform:rotateTranslate atTime:kCMTimeZero]; 

基本上这个想法是创build一个旋转和平移matrix。 您将其旋转到正确的方向,然后将其翻译成视图。 我没有看到任何方式来指定一个中心点,而我正在浏览API。

build立在迄今为止所回答的问题上。 我find了一个很好的debugging方法,找出你的变换出了什么问题。 使用可用的斜坡方法,您可以对变换进行animation处理,从而更轻松地查看变换正在进行的操作。

大多数情况下,我发现自己进行了转换,直到我意识到仅仅使用video轨道的preferredTransform属性可能会导致video馈送移出渲染屏幕,我似乎什么也不做。

 AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; [videoLayerInstruction setTransformRampFromStartTransform:CGAffineTransformIdentity toEndTransform:videoTrack.preferredTransform timeRange:CMTimeRangeMake(projectClipStart, projectClipDuration)]; 

最终,我发现在某些情况下,我需要应用翻译才能将旋转的video带回到渲染屏幕。

 CGAffineTransformConcat(videoTrack.preferredTransform, CGAffineTransformMakeTranslation(0, renderSize.height)) 

注意:您的翻译值可能会有所不同。

 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;