How to detect if a video file was recorded in portrait orientation, or landscape in iOS

George C. picture George C. · Jan 7, 2011 · Viewed 26.3k times · Source

I am using AlAssetsGroup enumerateAssetsAtIndexes to list the assets in the Photos (Camera) app. For a given video asset I want to determine whether it was shot in portrait or landscape mode.

In the following code, asset is an AlAsset and I have tested to see if it is a video asset [asset valueForProperty:ALAssetPropertyType] is AlAssetTypeVideo, then:

int orientation = [[asset valueForProperty:ALAssetPropertyOrientation] intValue];

In this case orientation is always 0 which is ALAssetOrientationUp. Maybe this is to be expected, all videos are up right, but a portrait video is represented in MPEG-4 as a landscape video turned 90 degrees (i.e. all videos are actually landscape, try the MediaInfo app on the mac if you don't believe me).

Where within the file and/or how do I access the information that tells me it was actually recorded while holding the phone in portrait orientation?

I have also tried this, given the url of the asset:

AVURLAsset *avAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
CGSize size = [avAsset naturalSize];
NSLog(@"size.width = %f size.height = %f", size.width, size.height);
CGAffineTransform txf = [avAsset preferredTransform];
NSLog(@"txf.a = %f txf.b = %f  txf.c = %f  txf.d = %f  txf.tx = %f  txf.ty = %f",
            txf.a, txf.b, txf.c, txf.d, txf.tx, txf.ty);

Which always yields a width > height so for iPhone 4, width=1280 height=720 and the transform a and d values are 1.0, the others are 0.0, regardless of the capture orientation.

I have looked at the meta data using MediaInfo app on the Mac, I have done a Hexdump and so far have not found any difference between a landscape and portrait video. But QuickTime knows and displays portrait videos vertically, and the phone knows by rotating a portrait video if you are holding the phone in landscape orientation on playback and correctly displaying it if holding it in portrait.

BTW I can't use ffmpeg (can't live with the license restrictions). Is there an iPhone SDK native way to do this?

Answer

George picture George · May 18, 2011

Based on the previous answer, you can use the following to determine the video orientation:

+ (UIInterfaceOrientation)orientationForTrack:(AVAsset *)asset
{
    AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    CGSize size = [videoTrack naturalSize];
    CGAffineTransform txf = [videoTrack preferredTransform];

    if (size.width == txf.tx && size.height == txf.ty)
        return UIInterfaceOrientationLandscapeRight;
    else if (txf.tx == 0 && txf.ty == 0)
        return UIInterfaceOrientationLandscapeLeft;
    else if (txf.tx == 0 && txf.ty == size.width)
        return UIInterfaceOrientationPortraitUpsideDown;
    else
        return UIInterfaceOrientationPortrait;
}