2011-06-29 613 views
5

Descrtiption de la aplicación: Velocímetro. Tiene marca de aguja y aguja animada como superposición en el video. Emito la animación de la aguja en el video a través del postprocesamiento. Uso AVAssetExportSession y construyo una Composición AV que contiene mis capas animadas junto con las pistas de Video y Audio del video. Esto funciona bien Video muestra, aguja anima.Cómo vincular/sincronizar la animación a una grabación de video en tiempo real

Actualmente, para reproducir la animación durante el postprocesamiento, he guardado cualquier cambio en la velocidad con un tiempo desde que comenzó la "grabación" del video. Durante el posprocesamiento, despido un temporizador basado en los datos de tiempo/velocidad guardados para animar la aguja a la siguiente velocidad.

Problema: Resultante de vídeo/par animación no son del todo precisos y con frecuencia hay una falta de correspondencia entre la velocidad indicada cuando el video fue tomado y cuando se reproduce y compuesta. (por lo general, la aguja es anterior al video) debido al hecho de que la composición/compresión durante la exportación no es necesariamente en tiempo real.

Pregunta: ¿Hay alguna manera de incluir información acerca de la velocidad en la transmisión de video grabación y luego tener acceso a ella cuando se exporta para que el vídeo y el velocímetro se hacen coincidir temporalmente hasta?

Sería bueno obtener una devolución de llamada en momentos específicos durante la exportación que contiene mis datos de velocidad.

Como siempre ... ¡gracias!

Respuesta

1

En lugar de utilizar temporizadores para animar su aguja, cree una animación de fotograma clave basada en los datos de velocidad que registró.

En general, los temporizadores y CA no se combinan bien, al menos no de la manera que deduzco de su descripción.

1

Si necesita incrustar los metadatos mientras la aplicación se ejecuta en el iPhone, no sé cómo hacerlo. Si puede hacer la incrustación antes, use HTTP LIve Streaming y HTTP Live Streaming Tools.

Los metadatos se generan en un archivo mediante el id3taggenerator, y se incrustan en el video utilizando mediafilesegmenter. Ejemplo:

id3taggenerator -o camera1.id3 -text "Dolly camera" 
id3taggenerator -o camera2.id3 -text "Tracking camera" 

Hay varios tipos de metadatos se pueden incrustar, incluyendo objetos binarios. Consulte la página de manual para más detalles. Ahora necesitamos hacer referencia al archivo generado desde un "meta macro-archivo". Este es un archivo de texto con el siguiente formato:

60 id3 camera1.id3 
120 id3 camera2.id3 

El primer número es segundos transcurridos desde el inicio del vídeo en el que desea insertar la notificación. No recuerdo exactamente el comando mediafilesegmenter, lo siento, debe pasar al menos el archivo de macro, el índice y el archivo de video.

El video resultante contiene metadatos publicados por MPMoviePlayerController como notificaciones. Consulte esta página para obtener más detalles: http://jmacmullin.wordpress.com/2010/11/03/adding-meta-data-to-video-in-ios/

0

Hay una sesión de la WWDC de este año que podría proporcionar un enfoque diferente de lo que está haciendo. Puedes ver los videos aquí: http://developer.apple.com/videos/wwdc/2011/. Busque uno llamado "Trabajar con medios en AVFoundation". Los bits interesantes son alrededor del minuto 26 más o menos. No estoy completamente seguro de entender el problema, pero cuando lo leí, esa sesión se me ocurrió.

Saludos cordiales.

1

Debe utilizar CAAnimations y la propiedad beginTime para configurar sus animaciones antes de tiempo, a continuación, utilizar AVVideoComposition + AVVideoCompositionCoreAnimationTool para agregarlos al vídeo cuando se exporta. Tenga en cuenta sus estados de documentación:

Cualquier animación se interpretarán en línea de tiempo del vídeo, no en tiempo real ...

Así que sus animaciones se alinearán exactamente donde se especifica con la película resultante.

1

Ha pasado un tiempo desde que se hizo esta pregunta, pero después de buscar en todas partes, he logrado encontrar algo similar al muestrear datos en tiempo real durante la grabación (a 1/30 segundos con un temporizador para un video grabado en 30 fps) y almacenarlo en una matriz. Luego, en el postprocesamiento, creo múltiples CALayers en un bucle para cada elemento de datos en la matriz y dibujo la visualización de esos datos en cada capa.

Cada capa tiene una CAAnimation que se desvanece en la opacidad en la línea de tiempo del medio correcto con el atributo beginTime, que es simplemente 1/30 seg. multiplicado por el índice de matriz. Este es un tiempo tan corto que la capa aparece inmediatamente sobre la capa anterior. Si el fondo de la capa es opaco, oscurecerá la aguja renderizada en la capa anterior y parecerá que anima la aguja en una sincronización bastante buena con la captura de video original. Puede que tengas que modificar el tiempo un poco, pero no estoy a más de un marco.

/******** this has not been compiled but you should get the idea ************ 

// Before starting the AVAssetExportSession session and after the AVMutableComposition routine 

CALayer* speedoBackground = [[CALayer alloc] init]; // background layer for needle layers 
[speedoBackground setFrame:CGRectMake(x,y,width,height)]; // size and location 
[speedoBackground setBackgroundColor:[[UIColor grayColor] CGColor]]; 
[speedoBackground setOpacity:0.5] // partially see through on video 

// loop through the data 
for (int index = 0; index < [dataArray count]; index++) { 

    CALayer* speedoNeedle = [[CALayer alloc] init]; // layer for needle drawing 
    [speedoNeedle setFrame:CGRectMake(x,y,width,height)]; // size and location 
    [speedoNeedle setBackgroundColor:[[UIColor redColor] CGColor]]; 
    [speedoNeedle setOpacity:1.0]; // probably not needed 

    // your needle drawing routine for each data point ... e.g. 
    [self drawNeedleOnLayer:speedoNeedle angle:[self calculateNeedleAngle[dataArray objectAtIndex:index]]]; 

    CABasicAnimation *needleAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    needleAnimation.fromValue = [NSNumber numberWithFloat:(float)0.0]; 
    needleAnimation.toValue = [NSNumber numberWithFloat:(float)1.0]; // fade in 
    needleAnimation.additive = NO; 
    needleAnimation.removedOnCompletion = NO; // it obscures previous layers 
    needleAnimation.beginTime = index*animationDuration; 
    needleAnimation.duration = animationDuration -.03; // it will not animate at this speed but layer will appear immediately over the previous layer at the correct media time 
    needleAnimation.fillMode = kCAFillModeBoth; 
    [speedoNeedle addAnimation:needleAnimation forKey:nil]; 
    [speedoBackground addSublayer:needleOverlay]; 
} 

[parentLayer addSublayer:speedoBackground]; 

. 
. 
. 
// when the AVAssetExportSession has finished, make sure you clear all the layers 
parentLayer.sublayers = nil; 

Requiere mucho procesador y memoria, por lo que no es ideal para videos largos o dibujos complejos. Estoy seguro de que hay métodos más elegantes, pero esto funciona y espero que esto ayude.

+0

Cómo agregamos animación o efecto de transición a un video, creamos un video a partir de imágenes, ¿podría saber cómo agregamos el efecto? Utilizamos https://github.com/caferrara/img-to-video para crear una imagen para video. –

Cuestiones relacionadas