如何在iOS中检测视频文件是纵向录制还是横向录制

kknvjkwl  于 2023-03-05  发布在  iOS
关注(0)|答案(9)|浏览(207)

我正在使用AlAssetsGroup enumerateAssetsAtIndexes列出照片(相机)应用程序中的资源。对于给定的视频资源,我希望确定它是以纵向模式还是横向模式拍摄的。
在下面的代码中,资产是AlAsset,我已经测试了它是否是视频资产[asset valueForProperty:ALAssetPropertyType]AlAssetTypeVideo,那么:

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

在这种情况下,orientation总是0,也就是ALAssetOrientationUp。也许这是意料之中的,所有的视频都是正确的,但肖像视频在MPEG-4中表示为旋转90度的风景视频(即所有的视频实际上都是风景,如果你不相信我,试试Mac上的MediaInfo应用程序)。
文件中的什么位置和/或我如何访问信息,这些信息告诉我它实际上是在纵向拿着手机时录制的?
我也尝试过这样做,给定资产的URL:

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);

这总是产生宽度〉高度,因此对于iPhone 4,宽度=1280高度=720,变换a和d值为1.0,其他值为0.0,无论捕获方向如何。
我已经用Mac上的MediaInfo应用程序查看了 meta数据,我做了一个Hexdump,到目前为止还没有发现横向和纵向视频之间有任何区别。但QuickTime知道并垂直显示纵向视频,如果你在播放时以横向方向拿着手机,手机会通过旋转纵向视频来知道,如果你以纵向方向拿着手机,手机会正确显示它。
顺便说一句,我不能使用ffmpeg(不能与许可证限制生活)。有一个iPhone SDK原生的方式来做到这一点?

vwhgwdsa

vwhgwdsa1#

根据前面的答案,您可以使用以下方法确定视频方向:

+ (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;
}
jljoyd4f

jljoyd4f2#

有人在苹果开发者论坛上建议转换视频轨道,这就完成了工作,你可以从下面的日志中看到,对于这些方向,结果是有意义的,我们的网络开发者现在能够旋转各种视频,使它们都匹配并合成为一个视频。

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);

日志使用4 iPhone 4视频与正常凸轮:(1)横向摄像头在右侧(主页按钮在左侧)(2)横向左(3)纵向倒置(4)纵向右上(主页按钮在底部)

  1. 2011-01-07 20:07:30.024我的秘密应用程序[1442:307]大小.宽度= 1280.000000大小.高度= 720.00000 2011-01-07 20:07:30.027我的秘密应用程序[1442:307]传输格式. a = -1.000000传输格式.B = 0.000000传输格式. c = 0.000000传输格式.d = -1.000000传输格式.传输格式= 1280.00000传输格式.传输格式= 720.000000
  2. 2011-01-07 20:07:45.052我的秘密应用程序[1442:307]大小.宽度= 1280.000000大小.高度= 720.000000 2011-01-07 20:07:45.056我的秘密应用程序[1442:307]传输格式a = 1.000000传输格式b = 0.000000传输格式c = 0.000000
    传输x f.d = 1.000000传输x f.传输x = 0.000000
    运输量= 0.000000
  3. 2011年1月7日20:07:53.763我的秘密应用程序[1442:307]大小.宽度= 1280.000000大小.高度= 720.000000 2011年1月7日20:07:53.766我的秘密应用程序[1442:307]传输格式a = 0.000000传输格式b = -1.000000传输格式c = 1.000000
    运输因子d = 0.000000运输因子tx = 0.000000运输因子ty = 1280.000000
  4. 2011-01-07 20:08:03.490我的秘密应用程序[1442:307]大小.宽度= 1280.000000大小.高度= 720.000000 2011-01-07 20:08:03.493我的秘密应用程序[1442:307]传输格式a = 0.000000传输格式b = 1.000000传输格式c = -1.000000
    运输因子d = 0.000000运输因子tx = 720.000000运输因子ty = 0.000000
fcipmucu

fcipmucu3#

在我的用例中,我只需要知道视频是纵向的还是横向的。

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)

这已经用前置和后置摄像头进行了测试,适用于所有方向。

tjrkku2a

tjrkku2a4#

AV资产图像生成器

如果您使用AVAssetImageGeneratorAVAssets生成图像,您只需将AVAssetImageGenerator.appliesPreferredTrackTransform属性设置为true,它将以正确的方向从资产返回图像!:)

雨燕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
        }
    }
}
zazmityj

zazmityj5#

如果您不想使用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];

}
mcvgt66p

mcvgt66p6#

虽然这里有几个答案是正确的,但它们并不全面。例如,你可能还需要知道使用哪种相机设备来应用适当的变换。我创建了一个要点来做这件事;提取UI接口方向和AV捕获设备位置。
Extract AVAsset Orientation and Camera Position

6rqinv9w

6rqinv9w7#

- (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;
}
syqv5f0l

syqv5f0l8#

对Swift 2中乔治回答的扩展
UIInterfaceOrientationUIImageOrientation相同

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
    }
  }
}
ha5z0ras

ha5z0ras9#

在swift 5中尝试此操作

func checkVideoOrientation(url: URL) {
    let asset = AVAsset(url: url)
    let track = asset.tracks(withMediaType: .video).first
    let size = track?.naturalSize ?? .zero
    let transform = track?.preferredTransform ?? .identity
    
    if size.width == transform.tx && size.height == transform.ty {
        self.postVideoOrientation = false //Portrait
    } else if size.width == transform.ty && size.height == transform.tx {
        self.postVideoOrientation = true //"Landscape"
    } else {
        self.postVideoOrientation = false //"Unknown"
    }
    
}

相关问题