如何使用AVFoundation设置逐帧生成的视频的方向? [英] How do I set the orientation for a frame-by-frame-generated video using AVFoundation?

查看:238
本文介绍了如何使用AVFoundation设置逐帧生成的视频的方向?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个iPhone应用程序,它从相机获取视频,通过一些OpenGL着色器代码运行它,然后使用 AVFoundation 将输出写入视频文件。应用程序以lanscape方向运行(任一),因此所有录制的视频都应为横向。

I am writing an iPhone app which takes video from the camera, runs it through some OpenGL shader code and then writes the output to a video file using AVFoundation. The app runs in lanscape orientation (either) and therefore all video recorded should be landscape.

开始录制之前使用的当前代码是正确的:

The current code I use before starting recording to get the video the right way round is:

[[self videoWriterInput] setTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI), -1.0, 1.0)];

其中videoWriterInput是 AVAssetWriterInput 目的是补偿OpenGL的横向模式和倾斜的方向。

where videoWriterInput is an instance of AVAssetWriterInput and the aim is to compensate for the landscape mode and the reveresed orientation of OpenGL.

这产生的视频,当下载和播放在Quicktime播放器正确播放。但是,如果我将录制的视频添加到iPhone照片库,则缩略图会正确显示,但如果手机处于横向模式,则视频会旋转90度。如果手机以纵向显示,则视频播放正确,但会水平裁剪以适合纵向尺寸。

This produces video which when downloaded and played on Quicktime player plays correctly. However, if I add the recorded video to the iPhone photo library, the thumbnail displays correctly but the video plays rotated 90 degrees if the phone is held in landscape. If the phone is held in portrait the video plays correctly but is cropped horizontally to fit the portrait dimensions.

根据这个Apple技术说明捕获输出用于处理视频帧的AVCaptureVideoDataOutput 不支持设置视频方向。

According to this Apple tech note the capture output for AVCaptureVideoDataOutput, which I use for processing the video frames, does not support setting the video orientation.

有没有人成功记录了景观生成的视频,可以添加到iPhone库,并在横向上正常播放,如果是如此?

Has anyone successfully recorded landscape generated video which can be added to the iPhone library and plays correctly in landscape and if so how?

推荐答案

您的帖子揭示了Apples Videos应用程序如何播放视频。我用我的应用程序与设备在四个方向记录了几个项目。他们都打得适当。我刚刚注意到,「影片」应用程式不支援像相簿相簿应用程式中的播放器一样旋转。视频应用程序希望您在横向上持有设备(至少是我的iPod touch)。我做了一些肖像录音,添加到iTunes,所有,包括用苹果的相机应用程序创建的一个,没有旋转时旋转设备到纵向。

Your post opened my eyes about how Apples Videos app plays back video. I recorded several items with my app with the device in the four orientations. They all played back properly oriented. I just noticed that the Videos app doesn't support rotation like the player in the Photos Album app. The Videos app expects you to hold the device (at least my iPod touch) in landscape. I did some portrait recordings, added them to iTunes, and all, including the one created with Apple's camera app, did not rotate when rotating the device to portrait orientation.

...

我的应用程序是一个时间流逝的应用程序,不做任何额外的处理框架像你正在做,所以YMMV以下。我有我的应用程序设置,以便它不会旋转窗口旋转设备。这样我总是处理设备的一个方向。我使用AVFoundation从视频流中抓取每个第N帧,并写出来。

My app is a time lapse app that does not do any extra processing on the frames like you are doing, so YMMV on the following. I have my app set up so that it does not rotate the window as the device is rotated. This way I'm always dealing with one orientation of the device. I use AVFoundation to grab every Nth frame from the video stream and write that out.

在设置录制时,我执行以下操作。

As I set up for recording, I do the following.

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调用以下方法。我已经减少了实际代码为了清晰这里。在我的应用程序,我还旋转一些按钮,所以注意他们不会得到相同的转换。注意的是我如何设置playbackTransform ivar。

That detectOrientation calls the following method. I've reduced the actual code for clarity here. In my app I also rotate some buttons, so notice they do not get the same transformation. The thing to pay attention to is how I'm setting up the playbackTransform ivar.

-(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;
}
}

当我的设备被旋转,我已经关闭自动轮播,我有以下在我的viewDidLoad方法。

As a side note, since I want the method called when ever the device is rotated, and I've turned off automatic rotation, I have the following in my viewDidLoad method.

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(detectOrientation) name:@"UIDeviceOrientationDidChangeNotification" object:nil];

这是我在这个SOF问答

这篇关于如何使用AVFoundation设置逐帧生成的视频的方向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆