如何在横向应用程序上将视频录制到屏幕上?

发布于 2024-12-11 13:27:30 字数 2458 浏览 0 评论 0原文

我正在研究

这个示例项目: https://github.com/jj0b/AROverlayExample

这非常有效。唯一的问题是它是一个肖像应用程序。因此,当我将设备旋转到横向时,视频仍然按需要显示,但我的所有标签和 UI 现在都是横向的。

在此处输入图像描述

要解决此问题,我仅在 info.plist 中设置横向

问题是这样的:

在此处输入图像描述

这是我的代码:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) 
    {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        assert( self.autoresizesSubviews );


        CGPoint layerRectCenter = CGPointMake( CGRectGetMidX( frame ),
                                              CGRectGetMidY( frame ) );


        // Initialization code
        self.captureSession = [[[AVCaptureSession alloc] init] autorelease];

        // addVideoInput
        {
            AVCaptureDevice* videoDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];  
            if (videoDevice) 
            {
                NSError *error;
                AVCaptureDeviceInput* videoIn = [AVCaptureDeviceInput deviceInputWithDevice: videoDevice error:&error];
                if ( ! error ) 
                {
                    if ( [self.captureSession canAddInput:videoIn] )
                        [self.captureSession addInput:videoIn];
                    else
                        NSLog(@"Couldn't add video input");     
                }
                else
                    NSLog(@"Couldn't create video input");
            }
            else
                NSLog(@"Couldn't create video capture device");
        }

        // addVideoPreviewLayer 
        {
            self.previewLayer = [[[AVCaptureVideoPreviewLayer alloc] initWithSession: self.captureSession] autorelease];
            self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

            self.previewLayer.frame = CGRectMake(0, 0, 480, 300); 
            self.previewLayer.orientation = AVCaptureVideoOrientationLandscapeRight;


            //self.previewLayer.frame = frame;

            [self.layer addSublayer: self.previewLayer];
        }

        // run!
        [self.captureSession startRunning];

    }
    return self;
}

我无法弄清楚为什么视频横向显示,尽管专门将图层框架设置为横向 CGRectMake( 0, 0, 480, 300) 情况恰恰相反。

This is doing my head in.

I am working from this sample project: https://github.com/jj0b/AROverlayExample

This works perfectly. only problem is it is a portrait app. So when I rotate the device to landscape, the video still displays as wanted, but all of my labels and UI are now sideways.

enter image description here

To fix this I'm setting landscape only in the info.plist

Problem is this:

enter image description here

Here is my code:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) 
    {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

        assert( self.autoresizesSubviews );


        CGPoint layerRectCenter = CGPointMake( CGRectGetMidX( frame ),
                                              CGRectGetMidY( frame ) );


        // Initialization code
        self.captureSession = [[[AVCaptureSession alloc] init] autorelease];

        // addVideoInput
        {
            AVCaptureDevice* videoDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];  
            if (videoDevice) 
            {
                NSError *error;
                AVCaptureDeviceInput* videoIn = [AVCaptureDeviceInput deviceInputWithDevice: videoDevice error:&error];
                if ( ! error ) 
                {
                    if ( [self.captureSession canAddInput:videoIn] )
                        [self.captureSession addInput:videoIn];
                    else
                        NSLog(@"Couldn't add video input");     
                }
                else
                    NSLog(@"Couldn't create video input");
            }
            else
                NSLog(@"Couldn't create video capture device");
        }

        // addVideoPreviewLayer 
        {
            self.previewLayer = [[[AVCaptureVideoPreviewLayer alloc] initWithSession: self.captureSession] autorelease];
            self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;

            self.previewLayer.frame = CGRectMake(0, 0, 480, 300); 
            self.previewLayer.orientation = AVCaptureVideoOrientationLandscapeRight;


            //self.previewLayer.frame = frame;

            [self.layer addSublayer: self.previewLayer];
        }

        // run!
        [self.captureSession startRunning];

    }
    return self;
}

I cannot figure out why the video is displaying sideways and despite specifically setting the layers frame to landscape CGRectMake(0, 0, 480, 300) it is coming out the other way round.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桃酥萝莉 2024-12-18 13:27:30

一个非常巧妙的解决方案是将视图直接添加到窗口。

执行此操作的最佳点是在根视图控制器中:

// need to add the capture view to the window here: can't do it in viewDidLoad as the window is not ready at that point
- (void) viewDidAppear: (BOOL) animated
{
    self.frontCamView = [[[FrontCamView alloc] 
                          initWithFrame: [UIScreen mainScreen].bounds] 
                         autorelease];

    self.view.opaque = NO;
    self.view.backgroundColor = [UIColor clearColor];

    [self.view.window addSubview: self.frontCamView];
    [self.view.window sendSubviewToBack: self.frontCamView];
}

然后是相机视图本身的实现:

@interface FrontCamView ( )

@property (retain) AVCaptureVideoPreviewLayer* previewLayer;
@property (retain) AVCaptureSession* captureSession;

@end

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@implementation FrontCamView

@synthesize captureSession;
@synthesize previewLayer;

// - - - 

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) 
    {
        self.captureSession = [[[AVCaptureSession alloc] init] autorelease];

        // addVideoInput
        {
            AVCaptureDevice* videoDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];  
            if (videoDevice) 
            {
                NSError *error;
                AVCaptureDeviceInput* videoIn = [AVCaptureDeviceInput deviceInputWithDevice: videoDevice error:&error];
                if ( ! error ) 
                {
                    if ( [self.captureSession canAddInput:videoIn] )
                        [self.captureSession addInput:videoIn];
                    else
                        NSLog(@"Couldn't add video input");     
                }
                else
                    NSLog(@"Couldn't create video input");
            }
            else
                NSLog(@"Couldn't create video capture device");
        }

        // addVideoPreviewLayer 
        {
            CGRect screenRect = [UIScreen mainScreen].bounds;

            self.previewLayer = [[[AVCaptureVideoPreviewLayer alloc] initWithSession: self.captureSession] autorelease];

            self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            self.previewLayer.frame = screenRect;  
            self.previewLayer.orientation = AVCaptureVideoOrientationPortrait;         

            [self.layer addSublayer: self.previewLayer];

        }

        // run!
        [self.captureSession startRunning];

    }
    return self;
}

- (void) dealloc 
{
    [self.captureSession stopRunning];

    [previewLayer release], previewLayer = nil;
    [captureSession release], captureSession = nil;


    [super dealloc];
}

@end

A very neat solution is to add the view directly to the window.

The best point to do this is in the root view controller:

// need to add the capture view to the window here: can't do it in viewDidLoad as the window is not ready at that point
- (void) viewDidAppear: (BOOL) animated
{
    self.frontCamView = [[[FrontCamView alloc] 
                          initWithFrame: [UIScreen mainScreen].bounds] 
                         autorelease];

    self.view.opaque = NO;
    self.view.backgroundColor = [UIColor clearColor];

    [self.view.window addSubview: self.frontCamView];
    [self.view.window sendSubviewToBack: self.frontCamView];
}

Then the implementation of the camera view itself:

@interface FrontCamView ( )

@property (retain) AVCaptureVideoPreviewLayer* previewLayer;
@property (retain) AVCaptureSession* captureSession;

@end

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@implementation FrontCamView

@synthesize captureSession;
@synthesize previewLayer;

// - - - 

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) 
    {
        self.captureSession = [[[AVCaptureSession alloc] init] autorelease];

        // addVideoInput
        {
            AVCaptureDevice* videoDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];  
            if (videoDevice) 
            {
                NSError *error;
                AVCaptureDeviceInput* videoIn = [AVCaptureDeviceInput deviceInputWithDevice: videoDevice error:&error];
                if ( ! error ) 
                {
                    if ( [self.captureSession canAddInput:videoIn] )
                        [self.captureSession addInput:videoIn];
                    else
                        NSLog(@"Couldn't add video input");     
                }
                else
                    NSLog(@"Couldn't create video input");
            }
            else
                NSLog(@"Couldn't create video capture device");
        }

        // addVideoPreviewLayer 
        {
            CGRect screenRect = [UIScreen mainScreen].bounds;

            self.previewLayer = [[[AVCaptureVideoPreviewLayer alloc] initWithSession: self.captureSession] autorelease];

            self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            self.previewLayer.frame = screenRect;  
            self.previewLayer.orientation = AVCaptureVideoOrientationPortrait;         

            [self.layer addSublayer: self.previewLayer];

        }

        // run!
        [self.captureSession startRunning];

    }
    return self;
}

- (void) dealloc 
{
    [self.captureSession stopRunning];

    [previewLayer release], previewLayer = nil;
    [captureSession release], captureSession = nil;


    [super dealloc];
}

@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文