user2786037
user2786037

Reputation: 505

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?

Upvotes: 7

Views: 1549

Answers (1)

Alex Curylo
Alex Curylo

Reputation: 4770

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

Upvotes: 2

Related Questions