2011-03-03 9 views
9

Estoy grabando video en un iPhone 4 con la cámara frontal y combinando el video con otros recursos multimedia. Me gustaría que este video sea una orientación vertical: la orientación predeterminada para todos los videos es horizontal y, en algunas circunstancias, debes administrarla manualmente.Rotación de video con AVMutableVideoCompositionLayerInstruction

Estoy utilizando AVFoundation y específicamente AVAssetExportSession con una composición de video AVMutable. Basado en los videos de WWDC, está claro que tengo que encargarme de 'arreglar' la orientación cuando estoy combinando videos en una nueva composición.

Por lo tanto, he creado un AVMutableVideoCompositionLayerInstruction unido a mi AVMutableVideoCompositionInstruction y estoy usando el setTransform: atTime: método para establecer un diseño de transformación para rotar el vídeo:

AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
CGAffineTransform portraitRotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0)); 
[passThroughLayer setTransform:portraitRotationTransform atTime:kCMTimeZero]; 

El problema es que cuando ver el video que se exporta, ninguno de los contenidos reales está en la pantalla. Si reduzco el ángulo de rotación a algo así como 45 grados, puedo ver parte del video en la pantalla, es casi como si no estuviera girando en el punto central. Estoy incluyendo imágenes a continuación para que quede más claro de lo que estoy hablando.

El tamaño natural del video es de 480x360. Intenté cambiar eso a 360x480 y no afecta el problema central.

0 grados de rotación:

enter image description here

45 grados de rotación:

enter image description here

Una rotación de 90 grados es sólo todo verde.

De todos modos, espero que alguien que ha hecho esto antes pueda señalarme en la dirección correcta. No puedo encontrar ningún documento sobre algunos de los temas más avanzados en las composiciones y exportaciones de AVFoundation.

+0

La entrada AVAssetWriter tiene una propiedad de transformación que se escribe en el archivo. Supongo que esto se ignora si primero está escribiendo su video capturado en un archivo. Puede intentar transformar el centro de AVMutableVideoCompositionLayerInstruction en el origen, girándolo y luego transformándolo. Parece que el origen predeterminado es la esquina superior izquierda. Esto es interesante. Te avisaré si encuentro algo. –

+0

@hunter ¿Puedes subir tu código para rotar el video? Por favor, ayúdame. Soy nuevo en iOS. –

+0

@Milanpatel Hola, lamentablemente no puedo publicar este código fuente ... pero ahora hay algunos buenos recursos disponibles. Este libro es un excelente lugar para aprender todo sobre AVFoundation (http://www.amazon.com/Learning-Foundation-Hands-Mastering-Framework/dp/0321961803). En última instancia, rotar el video consiste en construir una transformada afín (utilizada en otro lugar en iOS) y, en mi caso, entender que el punto de rotación era superior izquierdo, no central. Eso significa que también tienes que moverlo. – Hunter

Respuesta

6

Prueba esto:

AVMutableVideoCompositionLayerInstruction *passThroughLayer = AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0)); 
CGAffineTransform rotateTranslate = CGAffineTransformTranslate(rotateTransform,320,0); 
[passThroughLayer setTransform:rotateTranslate atTime:kCMTimeZero]; 

Básicamente la idea es crear una matriz de rotación y traslación. Usted lo gira a la orientación correcta y luego lo traduce a la vista. No vi ninguna forma de especificar un punto central mientras miraba a través de la API.

+0

Sí, gracias - En realidad, resolví esto por mi cuenta, pero lo que estás recomendando es básicamente correcto: el video usa el origen superior izquierdo como su punto de rotación, por lo que no solo debes rotar pero también moverlo al lugar correcto. ¡Gracias! – Hunter

+0

Como nuevo AVFoundation, ¿puedes explicar qué haces con passThroughLayer después de la transformación? ¿Cómo se asegura que la rotación se refleje en la película original o copiada? –

+0

El código anterior no está modificando la película. Está girando y traduciendo la capa en la que se muestra la película. Hay una serie de formas de modificar la película. Si todo lo que desea hacer es hacer que se visualice de forma diferente después de guardar la película, entonces investigue la propiedad de transformación AVAssetWriterInput. Es posible que desee publicar una nueva pregunta. –

2
AVAssetTrack *videoAssetTrack= [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject]; 

AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:videoAssetTrack atTime:kCMTimeZero error:&error]; 

videoCompositionTrack.preferredTransform = videoAssetTrack.preferredTransform; 
9

Basándose en lo que se ha respondido hasta ahora. Encontré una muy buena manera de eliminar errores y descubrir qué salió mal con tus transformaciones. Usando los métodos de rampa disponibles, puede animar las transformaciones para que sea más fácil ver lo que está haciendo su transformación.

La mayoría de las veces me encontré con transformaciones que parecían no hacer nada hasta que me di cuenta de que el solo uso de la propiedad preferredTransform de una pista de video solo puede hacer que la alimentación de video salga de la pantalla de renderizado.

AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 

[videoLayerInstruction setTransformRampFromStartTransform:CGAffineTransformIdentity 
toEndTransform:videoTrack.preferredTransform 
timeRange:CMTimeRangeMake(projectClipStart, projectClipDuration)]; 

Finalmente, he encontrado que en algunos casos que necesitaba para aplicar una traducción para traer de vuelta el video en la pantalla girada render.

CGAffineTransformConcat(videoTrack.preferredTransform, CGAffineTransformMakeTranslation(0, renderSize.height)) 

Nota: Sus valores de traducción pueden variar.

+0

Gracias, un consejo invaluable – AlimovAndrei

+0

¡Muy útil! Gracias – bcattle

0

también pueden ser relevantes, pero hay un error en el preferredTransform ser ajustada cuando se utiliza la cámara frontal .. ver aquí, por ejemplo, donde los chicos en el proyecto SDAVAssetExportSession han codificado una solución alternativa:

https://github.com/rs/SDAVAssetExportSession/pull/70

Cuestiones relacionadas