使用AVMutableVideoCompositionLayerInstruction旋转视频

Hun*_*ter 11 iphone video-capture avfoundation ios

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

我正在使用AVFoundation,特别是AVAssetExportSession和AVMutableVideoComposition.基于WWDC视频,当我将视频组合成新的构图时,我必须自己处理"修正"方向.

所以,我创建了一个附加到我的AVMutableVideoCompositionInstruction的AVMutableVideoCompositionLayerInstruction,我使用setTransform:atTime:方法来设置一个用于旋转视频的变换:

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

问题是,当我查看导出的视频时,屏幕上没有任何实际内容.如果我将旋转角度减小到45度,我可以在屏幕上看到部分视频 - 这几乎就像它不是在中心点旋转一样.我在下面包含图片,以便更清楚地说明我在说什么.

视频的自然尺寸为480x360.我已经尝试将其更改为360x480,但它不会影响核心问题.

0度旋转:

在此输入图像描述

45度旋转:

在此输入图像描述

90度旋转只是全绿色.

无论如何,我希望之前做过这件事的人可以指出我正确的方向.我找不到有关AVFoundation合成和导出中某些更高级主题的文档.

Nur*_*zam 11

立足于迄今为止所回答的问题.我发现了一种非常好的调试方法,可以找出变换出了什么问题.使用可用的渐变方法,您可以设置变换的动画,以便更容易地查看变换的作用.

大多数时候,我发现自己的变换似乎什么也没做,直到我意识到仅仅使用视频轨道的preferredTransform属性可能会导致视频输出移出渲染屏幕.

AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];

[videoLayerInstruction setTransformRampFromStartTransform:CGAffineTransformIdentity
toEndTransform:videoTrack.preferredTransform 
timeRange:CMTimeRangeMake(projectClipStart, projectClipDuration)];
Run Code Online (Sandbox Code Playgroud)

最后,我发现在某些情况下我需要应用翻译以将旋转的视频带回渲染屏幕.

CGAffineTransformConcat(videoTrack.preferredTransform, CGAffineTransformMakeTranslation(0, renderSize.height))
Run Code Online (Sandbox Code Playgroud)

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


Ste*_*lin 6

试试这个:

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

本质上,我们的想法是创建一个旋转和平移矩阵.您将其旋转到正确的方向,然后将其转换为视图.当我浏览API时,我没有看到任何指定中心点的方法.