2010-04-07 16 views
6

Estoy tratando de generar miniaturas de puntos aleatorios en una película usando la extensión FFMPEG y FFMPEG-PHP.Generando miniaturas aleatorias con PHP + FFMPEG

Mi secuencia de comandos funciona bien ... sin embargo, tarda 20 minutos para generar 5-10 miniaturas !!

La secuencia de comandos funciona mediante la generación de números aleatorios que se utilizan como números de cuadros más adelante. Todos los números generados están dentro del recuento de cuadros de películas.

¿Puedes averiguar por qué este script tarda unos 20 minutos en completarse? Si no, ¿una mejor solución?

<?php 

//Dont' timeout 
set_time_limit(0); 

//Load the file (This can be any file - still takes ages) 
$mov = new ffmpeg_movie('1486460.mp4'); 

//Get the total frames within the movie 
$total_frames = $mov->getFrameCount(); 

//Loop 5-10 times to generate random frames 5-10 times 
for ($i = 1; $i <= 5;) { 
    // Generate a number within 200 and the total number of frames. 
$frame = mt_rand(200,$total_frames); 
$getframe = $mov->getFrame($frame); 
// Check if the frame exists within the movie 
// If it does, place the frame number inside an array and break the current loop 
if($getframe){ 
    $frames[$frame] = $getframe ; 
    $i++; 
} 
} 

//For each frame found generate a thumbnail 
foreach ($frames as $key => $getframe) { 
$gd_image = $getframe->toGDImage(); 
imagejpeg($gd_image, "images/shot_".$key.'.jpeg'); 
imagedestroy($gd_image); 
echo $key.'<br/>'; 
} 

?> 

¿El script DEBERÍA estar generando números de cuadro válidos? ¿Algo dentro de START - END debe ser un número de fotograma válido? ¡Sin embargo, el ciclo lleva años!

+0

30 minutos? ¿Que? Convertiría 1TB de video. –

Respuesta

4

Se podría invocar ffmpeg desde la línea de comandos, mediante el interruptor -ss a buscar a un approrpriate puesta en punto (en el tiempo, no en número de cuadros) y -vframes 1 para indicarle que debe extraer exactamente un marco, por ejemplo:

ffmpeg -i 1486460.mp4 -ss 10 -vframes 1 images/shot_10.jpg 

va a extraer un fotograma de 10 segundos y llamarlo images/shot_10.jpg

0

no sé mucho acerca de los formatos de película, pero ya que la compresión probablemente se basa en un único pase de compresión delta con los marcos de referencia, si el posición de los marcos de referencia i s no definido, esto significa que el sistema tiene que reproducir la película completa para llegar a una compensación particular. Sería fácil verificar esto cargando siempre, por ejemplo, buscando un marco entre el desplazamiento 20 y el número de cuadros dividido por algún valor.

Asumiendo que este es el caso, usted tiene un problema adicional en la forma en que ha diseñado su algoritmo, necesita rebobinar al inicio y buscar cada uno de los 5 fotogramas - si generó sus compensaciones por adelantado , luego ordena la lista, ffmpeg puede recuperar los cuadros en una sola pasada.

HTH

C.

1

El problema aquí es la palabra azar. Logré la duración del video y luego intenté obtener un cuadro con esa duración aleatoria. Fácilmente modificable para más marcos:

$cmd = "ffmpeg -i {$src} 2>&1 |grep Duration"; 

    $output = array(); 

    exec($cmd, $output); 

    if(count($output)) { 
     $duration = explode(':', trim(str_replace('Duration:', NULL, current(explode(',', current($output)))))); 
     list($hour, $min, $sec) = $duration; 
     $sec = sprintf("%02d:%02d:%02d", rand(0, $hour), rand(0, $min), rand(0, $sec)); 
    } else { 
     $sec = "00:00:12"; //12sec it's ok :) 
    } 

    $cmd = "ffmpeg -ss {$sec} -i {$src} -s {$w}x{$h} -f image2 -vframes 1 {$destination}"; 

    $output = array(); 

    exec($cmd, $output); 
+0

esto realmente genial codificación :) – danielad

+0

Creo que poner el if (contar (salida)) cosa en un ... loop hace que el valor aleatorio con más miniaturas ¿verdad? – danielad

-5

Has escrito un error en tu loop.

if($getframe) { 
    $frames[$frame] = $getframe; 
    $i++; 
} 

Digamos que el bucle for funciona infinitamente hasta que se rompe. Si la instrucción if es falsa la primera vez, entonces $i++ no puede ser alcanzado y el ciclo es interminable.

Debe colocar el $i++ en la parte inferior del ciclo for, luego la ejecución será de 2 segundos en lugar de 20 minutos.

+0

El comportamiento está destinado.Se supone que el ciclo se ejecutará hasta que se hayan seleccionado cinco cuadros, por lo que el recuento solo aumentará cuando exista un marco seleccionado al azar. – joequincy