P i
P i

Reputation: 30674

How to record video to screen on a landscape app?

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.

Upvotes: 4

Views: 2948

Answers (1)

P i
P i

Reputation: 30674

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

Upvotes: 2

Related Questions