如何使用AVFoundation设置逐帧生成video的方向?
我正在编写一个iPhone应用程序,它从摄像头获取video,通过一些OpenGL着色器代码运行它,然后使用AVFoundation
将输出写入video文件。 该应用程序运行在lanscape方向(任一),因此所有录制的video应该是风景。
在开始录制以获得正确的video之前,我使用的当前代码是:
[[self videoWriterInput] setTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI), -1.0, 1.0)];
videoWriterInput是AVAssetWriterInput的一个实例,其目的是为了补偿OpenGL的景观模式和反思方向。
这会产生在Quicktime播放器上下载和播放时播放正确的video。 但是,如果将录制的video添加到iPhone照片库中,则缩略图可以正确显示,但如果手机处于横向模式,video将播放旋转90度。 如果手机处于肖像状态,video将正确播放,但会水平裁剪以适应纵向尺寸。
根据这个Apple技术笔记 ,我用于处理video帧的AVCaptureVideoDataOutput
的捕获输出不支持设置video方向。
有没有人成功地logging了景观生成的video,可以添加到iPhone库,并在横向上正确播放,如果是这样的话?
您的文章打开了我的眼睛关于苹果video应用程序如何播放video。 我用这个设备在四个方向上logging了几个项目。 他们都打得很好。 我只是注意到,video应用程序不支持在像册应用程序中的播放器旋转。 video应用程序希望您保持设备(至less我的iPod touch)横向。 我做了一些肖像录音,将它们添加到iTunes中,包括使用Apple相机应用程序创build的所有内容都不会在将设备旋转到纵向时旋转。
无论如何…
我的应用程序是一个时间stream逝的应用程序,不会像你正在做的任何额外的处理框架,所以下面的YMMV。 我有我的应用程序设置,以便它不旋转设备旋转窗口。 这样我总是处理设备的一个方向。 我使用AVFoundation从videostream中抓取每一个第N帧,并写出来。
当我开始录制时,我做了以下工作。
inputWriterBuffer = [AVAssetWriterInput assetWriterInputWithMediaType: AVMediaTypeVideo outputSettings: outputSettings]; // I call this explicitly before recording starts. Video plays back the right way up. [self detectOrientation]; inputWriterBuffer.transform = playbackTransform;
detectOrientation调用以下方法。 这里我已经减less了实际的代码。 在我的应用程序中,我也旋转一些button,所以注意他们没有得到相同的转换。 要注意的是我如何设置playbackTransform伊娃。
-(void) detectOrientation { CGAffineTransform buttonTransform; switch ([[UIDevice currentDevice] orientation]) { case UIDeviceOrientationUnknown: NULL; case UIDeviceOrientationFaceUp: NULL; case UIDeviceOrientationFaceDown: NULL; break; case UIDeviceOrientationPortrait: [UIButton beginAnimations: @"myButtonTwist" context: nil]; [UIButton setAnimationDuration: 0.25]; buttonTransform = CGAffineTransformMakeRotation( ( 0 * M_PI ) / 180 ); recordingStarStop.transform = buttonTransform; [UIButton commitAnimations]; playbackTransform = CGAffineTransformMakeRotation( ( 90 * M_PI ) / 180 ); break; case UIDeviceOrientationLandscapeLeft: [UIButton beginAnimations: @"myButtonTwist" context: nil]; [UIButton setAnimationDuration: 0.25]; buttonTransform = CGAffineTransformMakeRotation( ( 90 * M_PI ) / 180 ); recordingStarStop.transform = buttonTransform; [UIButton commitAnimations]; // Transform depends on which camera is supplying video if (theProject.backCamera == YES) playbackTransform = CGAffineTransformMakeRotation( 0 / 180 ); else playbackTransform = CGAffineTransformMakeRotation( ( -180 * M_PI ) / 180 ); break; case UIDeviceOrientationLandscapeRight: [UIButton beginAnimations: @"myButtonTwist" context: nil]; [UIButton setAnimationDuration: 0.25]; buttonTransform = CGAffineTransformMakeRotation( ( -90 * M_PI ) / 180 ); recordingStarStop.transform = buttonTransform; [UIButton commitAnimations]; // Transform depends on which camera is supplying video if (theProject.backCamera == YES) playbackTransform = CGAffineTransformMakeRotation( ( -180 * M_PI ) / 180 ); else playbackTransform = CGAffineTransformMakeRotation( 0 / 180 ); break; case UIDeviceOrientationPortraitUpsideDown: [UIButton beginAnimations: @"myButtonTwist" context: nil]; [UIButton setAnimationDuration: 0.25]; buttonTransform = CGAffineTransformMakeRotation( ( 180 * M_PI ) / 180 ); recordingStarStop.transform = buttonTransform; [UIButton commitAnimations]; playbackTransform = CGAffineTransformMakeRotation( ( -90 * M_PI ) / 180 ); break; default: playbackTransform = CGAffineTransformMakeRotation( 0 / 180 ); // Use the default, although there are likely other issues if we get here. break; } }
作为一个方面说明,因为我想要的方法调用时,设备旋转,我已经closures自动旋转,我有我的viewDidLoad方法中的以下内容。
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(detectOrientation) name:@"UIDeviceOrientationDidChangeNotification" object:nil];
这是我在这个SOF问答中发现的一个提示。
简单得多
在你的顶点着色器中:
统一浮动preferredRotation; 。 。 。 cos(优选旋转),-sin(优选旋转),0.0,0.0,sin(优选旋转),cos(优选旋转) ;
/* 90-degrees mat4 rotationMatrix = mat4( cos(preferredRotation), -sin(preferredRotation), (1.0 - cos(preferredRotation)) - sin(preferredRotation), 0.0, -sin(preferredRotation), cos(preferredRotation), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
在调用着色器的视图或视图控制器中:
if([videoTrack statusOfValueForKey:@“preferredTransform”error:nil == AVKeyValueStatusLoaded){CGAffineTransform preferredTransform = [videoTrack preferredTransform]; self.playerView.preferredRotation = -1 * atan2(preferredTransform.b,preferredTransform.a);
…等等…