旋转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;