如何检测视频文件是纵向录制的还是 iOS 横向录制的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4627940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect if a video file was recorded in portrait orientation, or landscape in iOS
提问by George C.
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.
我正在使用AlAssetsGroup enumerateAssetsAtIndexes
在照片(相机)应用程序中列出资产。对于给定的视频资产,我想确定它是以纵向还是横向模式拍摄的。
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:
在下面的代码中,资产是一个AlAsset
,我已经测试过它是否是视频资产[asset valueForProperty:ALAssetPropertyType]
是AlAssetTypeVideo
,然后:
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).
在这种情况下orientation
始终为 0,即ALAssetOrientationUp
。也许这是可以预料的,所有视频都是正确的,但是纵向视频在 MPEG-4 中表示为旋转 90 度的横向视频(即所有视频实际上都是横向的,如果您不这样做,请尝试使用 Mac 上的 MediaInfo 应用程序相信我)。
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.
对于 iPhone 4,它总是产生宽度 > 高度,因此宽度=1280 高度=720 并且变换 a 和 d 值是1.0
,其他值是0.0
,无论捕获方向如何。
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.
我在 Mac 上使用 MediaInfo 应用程序查看了元数据,我做了一个 Hexdump,到目前为止还没有发现横向和纵向视频之间的任何区别。但是 QuickTime 知道并垂直显示纵向视频,如果您在播放时横向拿着手机,手机会通过旋转纵向视频来识别,如果纵向拿着手机,则可以正确显示它。
BTW I can't use ffmpeg
(can't live with the license restrictions). Is there an iPhone SDK native way to do this?
顺便说一句,我不能使用ffmpeg
(不能忍受许可证限制)。是否有 iPhone SDK 本机方式来执行此操作?
采纳答案by George C.
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.
苹果开发论坛上的某个人建议进行视频轨道的转换,这可以完成工作。您可以从下面的日志中看到,对于这些方向,结果是有意义的,我们的 Web 开发人员现在能够旋转各种视频,使它们全部匹配并将它们合成为一个视频。
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)
使用带有普通摄像头的 4 个 iPhone 4 视频记录:(1) 右侧横向摄像头(左侧主页按钮)(2) 横向左侧 (3) 纵向颠倒 (4) 纵向纵向(底部主页按钮)
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
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.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
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]-x0f0t017.x0f00000000000 b = 0.000000 txf.c = 0.000000 txf.d = -1.000000 txf.tx = 1280.000000 txf.ty = 720.000000
2011-01-07 20:07:45.052 MySecretApp[1442:307] size.width = 1280.000000 size.height = 720.000000 2011-01-07 20:07:45.016 MySecretApp[1442:307] = 1280.000000 = 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] = 1280.000000 = -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].x0f0f00000. = 1.000000 txf.c = -1.000000
txf.d = 0.000000 txf.tx = 720.000000 txf.ty = 0.000000
回答by George
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;
}
回答by Michael Waterfall
In my use case I only needed to know if a video is in portrait or not (landscape).
在我的用例中,我只需要知道视频是否为纵向(横向)。
guard let videoTrack = AVAsset(url: videoURL).tracks(withMediaType: AVMediaTypeVideo).first else {
return ...
}
let transformedVideoSize = videoTrack.naturalSize.applying(videoTrack.preferredTransform)
let videoIsPortrait = abs(transformedVideoSize.width) < abs(transformedVideoSize.height)
This has been tested with both front and rear cameras for all orientation possibilities.
这已经通过前后摄像头的所有方向可能性进行了测试。
回答by cleverbit
AVAssetImageGenerator
AVAssetImageGenerator
If you are using AVAssetImageGenerator
to generate images from AVAssets
, you can simply set the .appliesPreferredTrackTransform
property of AVAssetImageGenerator
to true
and it will return you images from your asset in the correct orientation! :)
如果您使用AVAssetImageGenerator
从 生成图像AVAssets
,您只需设置to的.appliesPreferredTrackTransform
属性,它就会以正确的方向从您的资产中返回图像!:)AVAssetImageGenerator
true
Swift 3
斯威夫特 3
But to extend on @onmyway133's answer in Swift 3:
但要扩展@onmyway133 在Swift 3 中的回答:
import UIKit
import AVFoundation
extension AVAsset {
var g_size: CGSize {
return tracks(withMediaType: AVMediaTypeVideo).first?.naturalSize ?? .zero
}
var g_orientation: UIInterfaceOrientation {
guard let transform = tracks(withMediaType: AVMediaTypeVideo).first?.preferredTransform else {
return .portrait
}
switch (transform.tx, transform.ty) {
case (0, 0):
return .landscapeRight
case (g_size.width, g_size.height):
return .landscapeLeft
case (0, g_size.width):
return .portraitUpsideDown
default:
return .portrait
}
}
}
回答by dhallman
While several of the answers here are correct, they are not comprehensive. For instance, you may also need to know which camera device was used to apply the proper transforms. I created a gist to do this very thing; extract the UIInterfaceOrientation and the AVCaptureDevicePosition.
虽然这里的几个答案是正确的,但它们并不全面。例如,您可能还需要知道使用哪个相机设备来应用正确的变换。我创建了一个要点来做这件事;提取 UIInterfaceOrientation 和 AVCaptureDevicePosition。
回答by Gyanendra Singh
If you do not want to use AVFoundation Framework just to get the orientation of the recorded video then try it out
如果您不想仅使用 AVFoundation Framework 来获取录制视频的方向,请尝试一下
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info {
NSString *orientation;
NSString *videoPath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
NSURL *myURL = [[NSURL alloc] initFileURLWithPath:videoPath];
self.movieController = [[MPMoviePlayerController alloc] initWithContentURL:myURL];
UIImage *thumbImage = [movieController thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
float width = thumbImage.size.width;
float height = thumbImage.size.height;
if (width > height){
orientation = @"Landscape";
}else{
orientation = @"Portrait";
}
[self dismissViewControllerAnimated:YES completion:nil];
}
回答by evya
- (UIImageOrientation)getImageOrientationWithVideoOrientation:(UIInterfaceOrientation)videoOrientation {
UIImageOrientation imageOrientation;
switch (videoOrientation) {
case UIInterfaceOrientationLandscapeLeft:
imageOrientation = UIImageOrientationUp;
break;
case UIInterfaceOrientationLandscapeRight:
imageOrientation = UIImageOrientationDown;
break;
case UIInterfaceOrientationPortrait:
imageOrientation = UIImageOrientationRight;
break;
case UIInterfaceOrientationPortraitUpsideDown:
imageOrientation = UIImageOrientationLeft;
break;
}
return imageOrientation;
}
回答by onmyway133
Extending on George's answer in Swift 2
扩展乔治在 Swift 2 中的回答
UIInterfaceOrientation
is the same with UIImageOrientation
UIInterfaceOrientation
是一样的 UIImageOrientation
extension AVAsset {
var g_size: CGSize {
return tracksWithMediaType(AVMediaTypeVideo).first?.naturalSize ?? .zero
}
var g_orientation: UIInterfaceOrientation {
guard let transform = tracksWithMediaType(AVMediaTypeVideo).first?.preferredTransform else {
return .Portrait
}
switch (transform.tx, transform.ty) {
case (0, 0):
return .LandscapeRight
case (g_size.width, g_size.height):
return .LandscapeLeft
case (0, g_size.width):
return .PortraitUpsideDown
default:
return .Portrait
}
}
}