Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVAssetTrack preferredTransform always returns landscape

I having app that records a video.

To handle phone rotation I have the following code:

    // called on phone rotation
    AVCaptureConnection *previewLayerConnection = [[self previewLayer] connection];
    if ([previewLayerConnection isVideoOrientationSupported]) {
        [previewLayerConnection setVideoOrientation:[self getVideoOrientation]];
    }

and getVideoOrientation function:

- (AVCaptureVideoOrientation) getVideoOrientation {
    UIInterfaceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];
    AVCaptureVideoOrientation newOrientation = AVCaptureVideoOrientationPortrait;
    switch (deviceOrientation) {
        case UIInterfaceOrientationPortrait:
            NSLog(@"UIInterfaceOrientationPortrait");
            newOrientation = AVCaptureVideoOrientationPortrait;
            break;
        case UIInterfaceOrientationLandscapeLeft:
            NSLog(@"UIInterfaceOrientationLandscapeRight");
            newOrientation = AVCaptureVideoOrientationLandscapeLeft;
            break;
        case UIInterfaceOrientationLandscapeRight:
            NSLog(@"UIInterfaceOrientationLandscapeLeft");
            newOrientation = AVCaptureVideoOrientationLandscapeRight;
            break;
        default:
            NSLog(@"default");
            newOrientation = AVCaptureVideoOrientationPortrait;
            break;
    }

    return newOrientation;
}

This part of the app works properly (I see video as I should on any device orientation). But when I try to make a thumbnail (or play video) I have problems.

As I've read in other questions I do the following for each track:

        AVAssetTrack* videoTrack    = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        CGAffineTransform txf       = [videoTrack preferredTransform];
        CGFloat videoAngleInDegree  = RadiansToDegrees(atan2(txf.b, txf.a));

        if (txf.a == 0 && txf.b == 1.0 && txf.c == -1.0 && txf.d == 0) {
            thumbOrientation = UIImageOrientationLeft;
        }
        if (txf.a == 0 && txf.b == -1.0 && txf.c == 1.0 && txf.d == 0) {
            thumbOrientation =  UIImageOrientationRight;
        }
        if (txf.a == 1.0 && txf.b == 0 && txf.c == 0 && txf.d == 1.0) {
            thumbOrientation =  UIImageOrientationUp;
        }
        if (txf.a == -1.0 && txf.b == 0 && txf.c == 0 && txf.d == -1.0) {
            thumbOrientation = UIImageOrientationDown;
        }

        UIImage *image = [UIImage imageWithCGImage:im scale:1.0 orientation:thumbOrientation];

I have 2 sample files: 1 - landscape right, 2 - landscape left. I expect they have different orientations in code above, but unexpectedly they have the same (and videoAngleInDegree is the same for both of them).

Are there any workarounds?

like image 977
user2786037 Avatar asked Dec 08 '13 16:12

user2786037


1 Answers

Are you sure it's working properly? The getVideoOrientation there looks wrong -- AVCapture and UIDevice have opposite meanings for landscape left and right.

Here is a correct implementation from this question -- check the discussion there out and see if it helps.

- (void)deviceOrientationDidChange{

    UIDeviceOrientation deviceOrientation = [[UIDevice currentDevice] orientation];

    AVCaptureVideoOrientation newOrientation;

    if (deviceOrientation == UIDeviceOrientationPortrait){
        NSLog(@"deviceOrientationDidChange - Portrait");
        newOrientation = AVCaptureVideoOrientationPortrait;
    }
    else if (deviceOrientation == UIDeviceOrientationPortraitUpsideDown){
        NSLog(@"deviceOrientationDidChange - UpsideDown");
        newOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
    }

    // AVCapture and UIDevice have opposite meanings for landscape left and right (AVCapture orientation is the same as UIInterfaceOrientation)
    else if (deviceOrientation == UIDeviceOrientationLandscapeLeft){
        NSLog(@"deviceOrientationDidChange - LandscapeLeft");
        newOrientation = AVCaptureVideoOrientationLandscapeRight;
    }
    else if (deviceOrientation == UIDeviceOrientationLandscapeRight){
        NSLog(@"deviceOrientationDidChange - LandscapeRight");
        newOrientation = AVCaptureVideoOrientationLandscapeLeft;
    }

    else if (deviceOrientation == UIDeviceOrientationUnknown){
        NSLog(@"deviceOrientationDidChange - Unknown ");
        newOrientation = AVCaptureVideoOrientationPortrait;
    }

    else{
        NSLog(@"deviceOrientationDidChange - Face Up or Down");
        newOrientation = AVCaptureVideoOrientationPortrait;
    }

    [self setOrientation:newOrientation];
}
like image 77
Alex Curylo Avatar answered Oct 07 '22 18:10

Alex Curylo