Как определить, был ли записан видеофайл в портретной ориентации или пейзаж в 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?
Ответы
Ответ 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)
Это было проверено как с передней, так и с задней камерой для всех возможностей ориентации.