Подтвердить что ты не робот

Как определить, был ли записан видеофайл в портретной ориентации или пейзаж в iOS

Я использую AlAssetsGroup enumerateAssetsAtIndexes для перечисления активов в приложении "Фотографии (камера)". Для данного видеообъявления я хочу определить, был ли он снят в портретном или альбомном режиме.

В следующем коде актив является AlAsset, и я тестировал его, если он является видеообъявлением [asset valueForProperty:ALAssetPropertyType] равен AlAssetTypeVideo, а затем:

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

В этом случае orientation всегда 0, что ALAssetOrientationUp. Возможно, этого и следовало ожидать, все видео в порядке, но портретное видео представлено в формате MPEG-4, поскольку видеоизображение на ландшафтном видео повернулось на 90 градусов (т.е. Все видео на самом деле пейзажи, попробуйте приложение MediaInfo на Mac, если вы не поверь мне).

Где внутри файла и/или как я могу получить доступ к информации, которая сообщает мне, что она была фактически записана, удерживая телефон в портретной ориентации?

Я также пробовал это, учитывая 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 height = 720, а значения преобразования a и d 1.0, остальные 0.0, независимо от ориентации захвата.

Я просмотрел метаданные, используя приложение MediaInfo на Mac, я сделал Hexdump и до сих пор не нашел разницы между пейзажным и портретным видео. Но QuickTime знает и отображает портретные видео по вертикали, и телефон знает, поворачивая портретное видео, если вы держите телефон в альбомной ориентации при воспроизведении и правильно отображаете его, удерживая его в портрете.

BTW Я не могу использовать ffmpeg (не могу жить с ограничениями лицензии). Есть ли собственный способ SDK для iPhone?

4b9b3361

Ответ 1

Кто-то на форумах apple dev предложил получить преобразование видеодорожки, это делает работу. Вы можете видеть из журналов ниже, что для этих ориентаций результаты имеют смысл, и наш веб-разработчик теперь может вращать множество видео, чтобы все они соответствовали и объединяли их в одно видео.

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) портрет вверх-вправо (кнопка дома внизу)

  • 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.000000

  • 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

  • 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

Ответ 2

В соответствии с предыдущим ответом вы можете использовать следующее для определения ориентации видео:

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

Ответ 3

Если вы не хотите использовать 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];

}

Ответ 4

Хотя некоторые из ответов здесь верны, они не являются исчерпывающими. Например, вам также может понадобиться знать, какое устройство камеры использовалось для применения правильных преобразований. Я создал суть, чтобы сделать это; извлеките UIInterfaceOrientation и AVCaptureDevicePosition.

Извлечь ориентацию AVAsset и положение камеры

Ответ 5

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

Ответ 6

AVAssetImageGenerator

Если вы используете AVAssetImageGenerator для создания изображений из AVAssets, вы можете просто установить свойство .appliesPreferredTrackTransform AVAssetImageGenerator на true, и оно вернет вам изображения из вашего актива в правильной ориентации!:)


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

Ответ 7

Расширение ответа Джорджа в Swift 2

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

Ответ 8

В моем случае использования мне только нужно было знать, есть ли видео в портрете или нет (пейзаж).

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)

Это было проверено как с передней, так и с задней камерой для всех возможностей ориентации.