0

I'm working on an app that allows the user to record video in realtime while some HUD info is displayed in a preview layer.

I've got a lot of this worked out, but one problem I have is that the video itself is rotated right by 90 degrees when the iPad is in landscape mode. When the home button is on the left, the video is rotated 90 degrees CCW, while it goes 90 degrees CW when the home button is to the right. The video should be upright regardless of which landscape mode I'm using. This [SO message] seems to tally pretty closely to what I'm dealing with, but the solution has deprecations included. 1

In my main controller:

[self setCaptureManager:[[[CaptureSessionManager alloc] init] autorelease]];

[[self captureManager] addVideoInput];

[[self captureManager] addVideoPreviewLayer];
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),
        CGRectGetMidY(layerRect))];
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];

CaptureSessionManager.h

#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>


@interface CaptureSessionManager : NSObject {

}

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

- (void)addVideoPreviewLayer;

- (void)addVideoInput;

@end

CaptureSessionManager.m

#import "CaptureSessionManager.h"


@implementation CaptureSessionManager

@synthesize captureSession;
@synthesize previewLayer;

#pragma mark Capture Session Configuration

- (id)init {
    if ((self = [super init])) {
        [self setCaptureSession:[[AVCaptureSession alloc] init]];
        if ([captureSession canSetSessionPreset:AVCaptureSessionPresetHigh]) {
            captureSession.sessionPreset = AVCaptureSessionPresetHigh;
        }
    }
    return self;
}

- (void)addVideoPreviewLayer {
    [self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
    [[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];

}

- (void)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");
}

- (void)dealloc {

    [[self captureSession] stopRunning];

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

    [super dealloc];
}

@end
Community
  • 1
  • 1
David Nedrow
  • 742
  • 1
  • 6
  • 21

2 Answers2

1

If answers in that question you mentioned are not working, then you can achieve it other way around. Use CATransform3DMakeRotation to rotate your preview layer according to the orientation of the device.

For example, for UIDeviceOrientationLandscapeLeft you can rotate your preview layer like this:

preview.transform = CATransform3DMakeRotation(-M_PI/2, 0, 0, 1);
blancos
  • 1,436
  • 2
  • 16
  • 36
1

Found that the videoOrientation attribute of the preview layer connection needed to be set.

Here's the change to my addVideoPreviewLayer method...

- (void)addVideoPreviewLayer {
    [self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
    [[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    [[previewLayer connection] setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
}
David Nedrow
  • 742
  • 1
  • 6
  • 21