2011-03-01 16 views
8

Tengo una vista de edición de video simple que usa AVPlayer. Creo una composición de AVMutable usando uno o varios AVURLAsset. Todo funciona bien, pero los videos siempre giran 90 grados. es decir, si el video fuente se tomó en modo retrato. AVPlayer lo muestra en modo paisaje y viceversa. He revisado la documentación y la he "maquinado" hasta la muerte y no puedo encontrar una solución. Puede que esté buscando en los lugares equivocados.iPhone SDK. ¿es posible rotar videos en AVplayer usando AVURLlAsset/AVMutableComposition?

¿Alguien puede ayudar?

Gracias de antemano;

Jean-Pierre

+0

Después de ver una sesión WWDC10 en AVFoundation Creo que hay un ajuste en alguna parte, pero necesito verlo de nuevo. Publicaré la respuesta cuando estoy seguro –

+1

¿Alguna vez resolvió este problema? Tengo el mismo problema. –

+0

Has resuelto este problema? Tengo el mismo problema, no sé lo que tengo que hacer –

Respuesta

1

Sin tener el código para examinar, es difícil saber lo que está pasando ... Pero lo más probable, su problema se produce porque se está perdiendo el valor de su propiedad preferredTransform.

Todos los objetos AVAssetTrack tienen una propiedad preferredTransform que se utiliza para especificar si los videos deben girarse o no. Si está creando nuevos objetos AVMutableAssetTrack, es posible que deba establecer el valor de esa propiedad para que el video permanezca en la orientación deseada.

3

Según entiendo, tiene algunos problemas de orientación, como el vídeo de retrato está en modo apaisado y, a veces, los videos se ponen boca abajo. Esto se debe a la orientación predeterminada de AVAsset. Todos los archivos de película e imagen grabados con la aplicación de cámara iPhone predeterminada tienen el marco de video configurado en horizontal, por lo que el medio se guarda en modo horizontal. AVAsset tiene una propiedad preferredTransform que contiene la información de orientación de medios, y esto se aplica a un archivo multimedia cada vez que lo ve usando la aplicación Photos o QuickTime. Puede corregir esto fácilmente aplicando las transformaciones necesarias a sus objetos AVAsset. Pero como sus dos archivos de video pueden tener diferentes orientaciones, necesitará usar dos instancias separadas de AVMutableCompositionTrack en lugar de una (suponga) como lo hizo originalmente. Cree dos pistas de video AVMutableCompositionTrack Como ahora tiene dos instancias separadas de AVMutableCompositionTrack, debe aplicar una AVMutableVideoCompositionLayerInstruction a cada pista para corregir la orientación. Añada el siguiente código

// Create AVMutableVideoCompositionInstruction 
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(firstAsset.duration, secondAsset.duration)); 
// Create an AVMutableVideoCompositionLayerInstruction for the first track 
AVMutableVideoCompositionLayerInstruction *firstlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:firstTrack]; 
AVAssetTrack *firstAssetTrack = [[firstAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
UIImageOrientation firstAssetOrientation_ = UIImageOrientationUp; 
BOOL isFirstAssetPortrait_ = NO; 
CGAffineTransform firstTransform = firstAssetTrack.preferredTransform; 
if (firstTransform.a == 0 && firstTransform.b == 1.0 && firstTransform.c == -1.0 && firstTransform.d == 0) { 
    firstAssetOrientation_ = UIImageOrientationRight; 
    isFirstAssetPortrait_ = YES; 
} 
if (firstTransform.a == 0 && firstTransform.b == -1.0 && firstTransform.c == 1.0 && firstTransform.d == 0) { 
    firstAssetOrientation_ = UIImageOrientationLeft; 
    isFirstAssetPortrait_ = YES; 
} 
if (firstTransform.a == 1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == 1.0) { 
    firstAssetOrientation_ = UIImageOrientationUp; 
} 
if (firstTransform.a == -1.0 && firstTransform.b == 0 && firstTransform.c == 0 && firstTransform.d == -1.0) { 
    firstAssetOrientation_ = UIImageOrientationDown; 
} 
[firstlayerInstruction setTransform:firstAsset.preferredTransform atTime:kCMTimeZero]; 
[firstlayerInstruction setOpacity:0.0 atTime:firstAsset.duration]; 
// Create an AVMutableVideoCompositionLayerInstruction for the second track 
AVMutableVideoCompositionLayerInstruction *secondlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:secondTrack]; 
AVAssetTrack *secondAssetTrack = [[secondAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
UIImageOrientation secondAssetOrientation_ = UIImageOrientationUp; 
BOOL isSecondAssetPortrait_ = NO; 
CGAffineTransform secondTransform = secondAssetTrack.preferredTransform; 
if (secondTransform.a == 0 && secondTransform.b == 1.0 && secondTransform.c == -1.0 && secondTransform.d == 0) { 
    secondAssetOrientation_= UIImageOrientationRight; 
    isSecondAssetPortrait_ = YES; 
} 
if (secondTransform.a == 0 && secondTransform.b == -1.0 && secondTransform.c == 1.0 && secondTransform.d == 0) { 
    secondAssetOrientation_ = UIImageOrientationLeft; 
    isSecondAssetPortrait_ = YES; 
} 
if (secondTransform.a == 1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == 1.0) { 
    secondAssetOrientation_ = UIImageOrientationUp; 
} 
if (secondTransform.a == -1.0 && secondTransform.b == 0 && secondTransform.c == 0 && secondTransform.d == -1.0) { 
    secondAssetOrientation_ = UIImageOrientationDown; 
} 
[secondlayerInstruction setTransform:secondAsset.preferredTransform atTime:firstAsset.duration]; 
} 

Finalmente, agregue las instrucciones, es solo la corrección de orientación aplicada a la segunda pista.

mainInstruction.layerInstructions = [NSArray arrayWithObjects:firstlayerInstruction, secondlayerInstruction,nil]; 
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; 
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction]; 
mainCompositionInst.frameDuration = CMTimeMake(1, 30); 

CGSize naturalSizeFirst, naturalSizeSecond; 
if(isFirstAssetPortrait_){ 
    naturalSizeFirst = CGSizeMake(FirstAssetTrack.naturalSize.height, FirstAssetTrack.naturalSize.width); 
} else { 
    naturalSizeFirst = FirstAssetTrack.naturalSize; 
} 
if(isSecondAssetPortrait_){ 
    naturalSizeSecond = CGSizeMake(SecondAssetTrack.naturalSize.height, SecondAssetTrack.naturalSize.width); 
} else { 
    naturalSizeSecond = SecondAssetTrack.naturalSize; 
} 

float renderWidth, renderHeight; 
if(naturalSizeFirst.width > naturalSizeSecond.width) { 
    renderWidth = naturalSizeFirst.width; 
} else { 
    renderWidth = naturalSizeSecond.width; 
} 
if(naturalSizeFirst.height > naturalSizeSecond.height) { 
    renderHeight = naturalSizeFirst.height; 
} else { 
    renderHeight = naturalSizeSecond.height; 
} 
MainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight); 

esperanza esto ayuda

Cuestiones relacionadas