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)
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.0000002011-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.0000002011-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.0000002011-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
How to Trap on Uiviewalertforunsatisfiableconstraints
Prevent Segue in Prepareforsegue Method
Ios: Keep an App Running Like a Service
Xcode Is Looking for Core Data Entity Names with Dot; Not Compiling
React Native Responsive Font Size
Programmatically Change Rootviewcontroller of Storyboard
How to Use Nslocalizedstring Function with Variables in Swift
iOS Background Audio Not Playing
Converting iPhone Xib to iPad Xib
Uisearchbar Increases Navigation Bar Height in iOS 11
How to Test If a String Is Empty in Objective-C
Where's the Difference Between Setobject:Forkey: and Setvalue:Forkey: in Nsmutabledictionary
Uistackview Hide View Animation
Uitableview and Uiview with Keyboardwillshow
iOS 7 App Icons, Launch Images and Naming Convention While Keeping iOS 6 Icons
Class Amsupporturlconnectiondelegate Is Implemented in Both
How to Implement the Uitapgesturerecognizer into My Application