How to Detect If a Video File Was Recorded in Portrait Orientation, or Landscape in iOS

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

Somebody on apple dev forums suggested getting the transform of the video track, this does the job. You can see from the logs below that for these orientations the results make sense and our web developer is now able to rotate a variety of vids so they all match and composite them into one video.

AVAssetTrack* videoTrack = [[avAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGSize size = [videoTrack naturalSize];
NSLog(@"size.width = %f size.height = %f", size.width, size.height);
CGAffineTransform txf = [videoTrack 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);

Logs using 4 iPhone 4 videos with the normal cam:
(1) landscape cam on right side (home button on left)
(2) landscape left
(3) portrait upside-down
(4) portrait up-right (home button at bottom)

  1. 2011-01-07 20:07:30.024 MySecretApp[1442:307] size.width =
    1280.000000 size.height = 720.000000 2011-01-07 20:07:30.027
    MySecretApp[1442:307] txf.a =
    -1.000000 txf.b = 0.000000 txf.c = 0.000000 txf.d = -1.000000 txf.tx = 1280.000000 txf.ty = 720.000000

  2. 2011-01-07 20:07:45.052 MySecretApp[1442:307] size.width =
    1280.000000 size.height = 720.000000 2011-01-07 20:07:45.056
    MySecretApp[1442:307] txf.a = 1.000000
    txf.b = 0.000000 txf.c = 0.000000

    txf.d = 1.000000 txf.tx = 0.000000

    txf.ty = 0.000000

  3. 2011-01-07 20:07:53.763 MySecretApp[1442:307] size.width =
    1280.000000 size.height = 720.000000 2011-01-07 20:07:53.766
    MySecretApp[1442:307] txf.a = 0.000000
    txf.b = -1.000000 txf.c = 1.000000

    txf.d = 0.000000 txf.tx = 0.000000
    txf.ty = 1280.000000

  4. 2011-01-07 20:08:03.490 MySecretApp[1442:307] size.width =
    1280.000000 size.height = 720.000000 2011-01-07 20:08:03.493
    MySecretApp[1442:307] txf.a = 0.000000
    txf.b = 1.000000 txf.c = -1.000000

    txf.d = 0.000000 txf.tx = 720.000000
    txf.ty = 0.000000

How to get correct Orientation for videos from PhotoLibrary iOS

Only way which solved this issue for me is to capture thumbnail image from the video using method:

- (void)requestThumbnailImagesAtTimes:(NSArray *)playbackTimes timeOption:(MPMovieTimeOption)option

and then adding check on the thumbnail image like :

if (singleFrameImage.size.height > singleFrameImage.size.width) {
// potrait video
} else {
// landscape video
}

This solution is tested on videos captured from iPhone camera and also on a set (8-10) of videos randomly downloaded from internet.

video orientation UIImagePickerController

Found the answer in anther post. AVAsset gives you two properties, [avAsset naturalSize] and [avAsset preferredTransform], that allow you to determine the video orientation.

Here's the related post:

How to detect (iPhone SDK) if a video file was recorded in portrait orientation, or landscape.

iOS - Is video/image on server portrait or landscape?

Your MPMoviePlayerController reports the naturalSize. If the naturalSize.width > naturalSize.height, you've got a landscape video.

Similarly, a UIImage reports a size. If the size.width > size.height, you've got a landscape image.

Portrait video rendered as landscape after exporting with AVMutableVideoComposition

After searching and trying many things i did this to solve the problem, first i check orientation with this function from raywenderlich article.

  func orientationFromTransform(
_ transform: CGAffineTransform
) -> (orientation: UIImage.Orientation, isPortrait: Bool) {
var assetOrientation = UIImage.Orientation.up
var isPortrait = false
let tfA = transform.a
let tfB = transform.b
let tfC = transform.c
let tfD = transform.d

if tfA == 0 && tfB == 1.0 && tfC == -1.0 && tfD == 0 {
assetOrientation = .right
isPortrait = true
} else if tfA == 0 && tfB == -1.0 && tfC == 1.0 && tfD == 0 {
assetOrientation = .left
isPortrait = true
} else if tfA == 1.0 && tfB == 0 && tfC == 0 && tfD == 1.0 {
assetOrientation = .up
} else if tfA == -1.0 && tfB == 0 && tfC == 0 && tfD == -1.0 {
assetOrientation = .down
}
return (assetOrientation, isPortrait)
}

and store it

let firstAssetInfo = orientationFromTransform(firstVideoTrack!.preferredTransform)

then before adding transform instructions i check if it is portrait then transform it to portrait manually and set it's scaling according to and use it's width as height and height as width, and if it's not portrait then do what i was doing before.

    let firstLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: firstTrack!)

if firstAssetInfo.isPortrait {

let rotate = __CGAffineTransformMake(0.0, 1.0, -1.0, 0.0, 0.0, 0.0)
let scale = CGAffineTransform(scaleX: firstPosScale.videoScale.x, y: firstPosScale.videoScale.y)
let move = CGAffineTransform(translationX: firstPosScale.videoLocation.x, y: firstPosScale.videoLocation.y)
let transform = rotate.concatenating(scale).concatenating(move)
firstLayerInstruction.setTransform(transform, at: .zero)

} else {

let scale = CGAffineTransform(scaleX: firstPosScale.videoScale.x, y: firstPosScale.videoScale.y)
let move = CGAffineTransform(translationX: firstPosScale.videoLocation.x, y: firstPosScale.videoLocation.y)
let transform = scale.concatenating(move)
firstLayerInstruction.setTransform(transform, at: .zero)
}

How to extract orientation information from videos?

Since most Cameras store their rotation/orientation within the exif-metadata, i would suggest using exifttool and the a ruby wrapper gem called mini_exiftool which is actively maintained.

Install exiftool:

apt-get exiftool || brew install exiftool || port install exiftool

or use what ever package manager is available

Install mini_exiftool:

gem install mini_exiftool

Try it:

irb>
require 'mini_exiftool'
movie = MiniExiftool.new('test_movie.mov')
movie.orientation #=> 90

cheers

IOS : Video recording using avcam in landscape mode?

Set the current device orientation while start recording the video.

// Update the orientation on the movie file output video connection before starting recording.

[[[self movieFileOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:(AVCaptureVideoOrientation)[UIDevice currentDevice].orientation];


Related Topics



Leave a reply



Submit