J'utilise AlAssetsGroup enumerateAssetsAtIndexes
pour répertorier les actifs dans l'application Photos (Appareil photo). Pour un élément vidéo donné, je souhaite déterminer s'il a été tourné en mode portrait ou paysage.
Dans le code suivant, l'élément est une AlAsset
et j'ai testé pour voir s'il s'agissait d'un élément vidéo [asset valueForProperty:ALAssetPropertyType]
est AlAssetTypeVideo
, puis:
int orientation = [[asset valueForProperty:ALAssetPropertyOrientation] intValue];
Dans ce cas, orientation
est toujours 0, ce qui est ALAssetOrientationUp
. C’est peut-être à prévoir, toutes les vidéos sont en bon ordre, mais une vidéo portrait est représentée sous la forme MPEG-4 sous la forme d’une vidéo en mode paysage tournée à 90 degrés mac si tu ne me crois pas).
Où dans le fichier et/ou comment puis-je accéder aux informations qui me disent qu’elles ont été réellement enregistrées tout en maintenant le téléphone en mode portrait?
J'ai également essayé ceci, étant donné l'URL de l'actif:
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);
Ce qui donne toujours une largeur> hauteur donc pour iPhone 4, largeur = 1280 hauteur = 720 et les valeurs de transformation a et d sont 1.0
, les autres sont 0.0
, quelle que soit l’orientation de la capture.
J'ai examiné les métadonnées à l'aide de l'application MediaInfo sur le Mac, j'ai réalisé un Hexdump et, jusqu'à présent, je n'ai trouvé aucune différence entre un paysage et une vidéo de portrait. Mais QuickTime connaît et affiche les vidéos portrait verticalement, et le téléphone sait en tournant une vidéo portrait si vous tenez le téléphone en orientation paysage lors de la lecture et l'affiche correctement s'il est tenu en portrait.
En passant, je ne peux pas utiliser ffmpeg
(je ne peux pas vivre avec les restrictions de licence). Existe-t-il un moyen natif du SDK pour iPhone de procéder?
Quelqu'un sur les forums de développement Apple a suggéré d'obtenir la transformation de la piste vidéo, cela fait le travail. Vous pouvez voir dans les journaux ci-dessous que, pour ces orientations, les résultats ont du sens et que notre développeur Web est désormais en mesure de faire pivoter une variété de vids afin qu'ils correspondent et les composent en une seule vidéo.
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);
Journalise avec 4 vidéos iPhone 4 avec la caméra normale: (1) caméra en paysage à droite (bouton principal à gauche) (2) paysage à gauche (3) portrait à l'envers (4) portrait en haut à droite (bouton principal en bas)
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
Sur la base de la réponse précédente, vous pouvez utiliser les éléments suivants pour déterminer l'orientation de la vidéo:
+ (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;
}
Bien que plusieurs réponses soient correctes, elles ne sont pas exhaustives. Par exemple, vous devrez peut-être également savoir quel appareil photo a été utilisé pour appliquer les transformations appropriées. J'ai créé un Gist pour faire cette chose même; extraire les UIInterfaceOrientation et AVCaptureDevicePosition.
Extraction de l'orientation et de la position de la caméra AVAsset
Dans mon cas d'utilisation, je n'avais besoin que de savoir si une vidéo est en portrait ou non (paysage).
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)
Cela a été testé avec les caméras avant et arrière pour toutes les possibilités d'orientation.
Si vous ne souhaitez pas utiliser AVFoundation Framework uniquement pour obtenir l'orientation de la vidéo enregistrée, essayez-le.
-(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];
}
Si vous utilisez AVAssetImageGenerator
pour générer des images à partir de AVAssets
, vous pouvez simplement définir la propriété .appliesPreferredTrackTransform
de AVAssetImageGenerator
sur true
et les images de votre actif vous seront renvoyées dans l'orientation correcte! :)
Mais pour prolonger la réponse de @ onmyway133 dans 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
}
}
}
- (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;
}
Étendre la réponse de George dans Swift 2
UIInterfaceOrientation
est la même chose que 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
}
}
}