5

AVFoundation le permite "componer" 2 recursos (2 videos) como 2 "pistas", como en Final Cut Pro, por ejemplo.Compositing 2 videos uno encima del otro con alpha

La teoría dice que puedo tener 2 vídeos en uno encima del otro, con alfa, y ver ambos.

O estoy haciendo algo mal, o hay un error en alguna parte, porque el siguiente código de prueba, aunque un poco desordenado, indica claramente que debería ver 2 videos, y solo veo uno, como se ve aquí: http://lockerz.com/s/172403384 - la plaza "azul" es IMG_1388.m4v

Por alguna razón, IMG_1383.MOV no se muestra.

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], AVURLAssetPreferPreciseDurationAndTimingKey, nil]; 
AVMutableComposition *composition = [AVMutableComposition composition]; 
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(4, 1)); 
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; 

// Track B 
NSURL *urlVideo2 = [NSURL URLWithString:@"file://localhost/Users/me/Movies/Temp/IMG_1388.m4v"]; 
AVAsset *video2 = [AVURLAsset URLAssetWithURL:urlVideo2 options:options]; 
AVMutableCompositionTrack *videoTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:0]; 
NSArray *videoAssetTracks2 = [video2 tracksWithMediaType:AVMediaTypeVideo]; 
AVAssetTrack *videoAssetTrack2 = ([videoAssetTracks2 count] > 0 ? [videoAssetTracks2 objectAtIndex:0] : nil); 
[videoTrack2 insertTimeRange:timeRange ofTrack:videoAssetTrack2 atTime:kCMTimeZero error:&error]; 

AVMutableVideoCompositionLayerInstruction *to = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack2]; 
[to setOpacity:.5 atTime:kCMTimeZero]; 
[to setTransform:CGAffineTransformScale(videoAssetTrack2.preferredTransform, .5, .5) atTime:kCMTimeZero]; 

// Track A 
NSURL *urlVideo = [NSURL URLWithString:@"file://localhost/Users/me/Movies/Temp/IMG_1383.MOV"]; 
AVURLAsset *video = [AVURLAsset URLAssetWithURL:urlVideo options:options]; 
AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:1]; 
NSArray *videoAssetTracks = [video tracksWithMediaType:AVMediaTypeVideo]; 
AVAssetTrack *videoAssetTrack = ([videoAssetTracks count] > 0 ? [videoAssetTracks objectAtIndex:0] : nil); 
[videoTrack insertTimeRange:timeRange ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil]; 

AVMutableVideoCompositionLayerInstruction *from = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack]; 
[from setOpacity:.5 atTime:kCMTimeZero]; 

// Video Compostion 
AVMutableVideoCompositionInstruction *transition = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
transition.backgroundColor = [[UIColor clearColor] CGColor]; 
transition.timeRange = timeRange; 
transition.layerInstructions = [NSArray arrayWithObjects:to, from, nil]; 
videoComposition.instructions = [NSArray arrayWithObjects:transition, nil]; 
videoComposition.frameDuration = CMTimeMake(1, 30); 
videoComposition.renderSize = CGSizeMake(480, 360); 


// Export 
NSURL *outputURL = [NSURL URLWithString:@"file://localhost/Users/me/Movies/Temp/export.MOV"]; 
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:[[composition copy] autorelease] presetName:AVAssetExportPresetHighestQuality]; 
[exportSession setOutputFileType:@"com.apple.quicktime-movie"]; 
exportSession.outputURL = outputURL; 
exportSession.videoComposition = videoComposition; 
[exportSession exportAsynchronouslyWithCompletionHandler:nil]; 

// Player 
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:composition]; 
playerItem.videoComposition = videoComposition; 
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem]; 
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; 

¿Está viendo algo mal?

El "objetivo" de este código es "registro" la entrada de cámara (video 1) y la salida OpenGL (vídeo 2). También traté de "componerlos" "directamente" con Buffers y todo eso, pero tampoco tuve éxito :(Resulta que AVFoundation es mucho menos trivial de lo que pensé.

+0

mc Hola @StuFF quiero fusionar múltiples de video con la transición que tengo uso de su código https: //gist.github.com/stuffmc/1572592/92f48ec664f1cce80def7fd2154b8809aec00b52 Pero no puedo obtener el archivo de salida en el directorio de documentos y tengo la respuesta * djromero * pero tampoco funciona. Por favor, ayúdenme con cualquier sugerencia. – sohil

Respuesta

0

Creo que lo has equivocado.

un archivo de vídeo puede tener múltiples secuencias de datos. Por ejemplo, si se trata de un vídeo con sonido el archivo tendrá 2 cursos de agua, el flujo de audio y el flujo de vídeo. Otro ejemplo es un archivo de vídeo de sonido envolvente que puede incluir 5 o más transmisión de audio y 1 secuencia de video

Al igual que el audio, la mayoría del formato de contenedor de archivos de video (mov, mp4, etc ...) admite varias transmisiones de video en 1 archivo, pero de hecho esto no significa que las transmisiones tendrá alguna relación n entre ellos, simplemente se almacenan en el mismo contenedor de archivos. Si abre dicho archivo con QuickTime, por ejemplo, obtendrá tantas ventanas como secuencias de video en dicho archivo.

De todos modos, las transmisiones de video no se 'mezclarán' de esta manera. Lo que intentas lograr está relacionado con el procesamiento de señal de la transmisión de video, y realmente te recomiendo que leas más sobre él.

Si usted realmente no necesita 'mezcla' los datos de vídeo junto a un archivo, es posible que desee mostrar tanto archivos de vídeo en uno al otro con MPMediaPlayers. Tenga en cuenta que lidiar con datos de video suele ser un problema intensivo de la CPU que quizás (en algún momento) no podrá resolver utilizando dispositivos iOS en la actualidad.

+0

que está claramente tratando de mezclar dos vídeos en uno encima del otro y añade opacidad a uno, por lo que se puede ver el vídeo subyacente. Si está sugiriendo que la composición solo tiene una pista de video, ¿cómo agrega las dos pistas al compositor para mezclar? – HPP

3

Se ve bien, excepto que esta parte:

AVMutableVideoCompositionLayerInstruction *from = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack]; 
AVMutableVideoCompositionLayerInstruction *to = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoAssetTrack2]; 

Es necesario utilizar videoTrack y videoTrack2 para construir las instrucciones de capa, es decir, las pistas añadidas a composition, en lugar de los activos originales videoAssetTrack y videoAssetTrack2.

Además, la adición de una transformación para rotar el video es un poco más complicado (como todo en la AVFoundation allá de lo básico). Acabo de comentar la línea para que reproduzca los 2 videos.

Este es el código con las modificaciones:

NSError *error = nil; 
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], AVURLAssetPreferPreciseDurationAndTimingKey, nil]; 
AVMutableComposition *composition = [AVMutableComposition composition]; 
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(4, 1)); 
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; 

// Track B 
NSURL *urlVideo2 = [[NSBundle mainBundle] URLForResource:@"b" withExtension:@"mov"];   
AVAsset *video2 = [AVURLAsset URLAssetWithURL:urlVideo2 options:options]; 
AVMutableCompositionTrack *videoTrack2 = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:0]; 
NSArray *videoAssetTracks2 = [video2 tracksWithMediaType:AVMediaTypeVideo]; 
AVAssetTrack *videoAssetTrack2 = ([videoAssetTracks2 count] > 0 ? [videoAssetTracks2 objectAtIndex:0] : nil); 
[videoTrack2 insertTimeRange:timeRange ofTrack:videoAssetTrack2 atTime:kCMTimeZero error:&error]; 

AVMutableVideoCompositionLayerInstruction *to = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack2]; 
[to setOpacity:.5 atTime:kCMTimeZero]; 
//[to setTransform:CGAffineTransformScale(videoAssetTrack2.preferredTransform, .5, .5) atTime:kCMTimeZero]; 

// Track A 
NSURL *urlVideo = [[NSBundle mainBundle] URLForResource:@"a" withExtension:@"mov"];   
AVURLAsset *video = [AVURLAsset URLAssetWithURL:urlVideo options:options]; 
AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:1]; 
NSArray *videoAssetTracks = [video tracksWithMediaType:AVMediaTypeVideo]; 
AVAssetTrack *videoAssetTrack = ([videoAssetTracks count] > 0 ? [videoAssetTracks objectAtIndex:0] : nil); 
[videoTrack insertTimeRange:timeRange ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil]; 

AVMutableVideoCompositionLayerInstruction *from = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
[from setOpacity:.5 atTime:kCMTimeZero]; 

// Video Compostion 
AVMutableVideoCompositionInstruction *transition = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
transition.backgroundColor = [[UIColor clearColor] CGColor]; 
transition.timeRange = timeRange; 
transition.layerInstructions = [NSArray arrayWithObjects:to, from, nil]; 
videoComposition.instructions = [NSArray arrayWithObjects:transition, nil]; 
videoComposition.frameDuration = CMTimeMake(1, 30); 
videoComposition.renderSize = composition.naturalSize; // CGSizeMake(480, 360); 
+0

No puedo hacer que sea aún funciona (su código), pero ... Parece extraño para mí que iba a tener que añadir "VideoTrack", que es un '' AVMutableCompositionTrack * en la documentación/cabecera establece claramente '- [videoCompositionLayerInstructionWithAssetTrack : (AVAssetTrack *) track' (lo que el parámetro debe ser un '' mi AVAssetTrack * * * videoAssetTrack es Gracias por su ayuda, aunque al final, por fin "compuesto" dos videos "cuadro por cuadro" como se indica en https.! :. //devforums.apple.com/message/601194#601194 –

+0

AVMutableCompositionTrack es una subclase de AVAssetTrack necesita instrucciones para las pistas en su composición (VideoTrack y videoTrack2), de lo contrario, no tiene efecto sobre el resultado – djromero

+0

el funcionamiento de su verdadera.. código con mis * * :) vídeos me da '- [AVPlayerItem setVideoComposition:] composición de vídeo debe tener un renderSize' positivo sin embargo. ¿Qué código usas para "mostrar" el video en un AVPlayerLayer? –

Cuestiones relacionadas