2010-04-07 11 views
6

Sto provando a generare miniature da punti casuali in un film utilizzando l'estensione FFMPEG e FFMPEG-PHP.Generazione di miniature casuali con PHP + FFMPEG

Il mio script funziona OK .. tuttavia occorrono 20 minuti solo per generare 5-10 miniature !!

Lo script funziona generando numeri casuali che vengono utilizzati come numeri di frame in seguito. Tutti i numeri generati sono compresi nel numero di fotogrammi del film.

Riesci a capire perché questo script impiega 20 minuti per terminare? Se no, una soluzione migliore?

<?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/>'; 
} 

?> 

Lo script DOVREBBE generare numeri di frame che sono validi? Qualcosa all'interno di START-END dovrebbe essere un numero di frame valido? Eppure il ciclo impiega anni!

+0

30 minuti? Cosa? Vorrei convertire 1 TB di video. –

risposta

4

Si potrebbe richiamare ffmpeg dalla linea di comando, utilizzando l'interruttore -ss cercare di un approrpriate start-point (nel tempo, non nel numero di fotogrammi) e -vframes 1 dire per estrarre esattamente un fotogramma, ad esempio:

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

estrarrà un frame da 10 secondi in e chiamarlo images/shot_10.jpg

0

non so molto di formati di pellicola, ma dal momento che la compressione probabilmente si basa su una singola compressione passaggio delta con cornici di riferimento, se il posizione dei fotogrammi di riferimento i s non definito, questo significa che il sistema deve riprodurre l'intero film per ottenere un determinato offset. Sarebbe facile controllarlo caricando sempre, diciamo, cercando un fotogramma tra l'offset 20 e il numero di fotogrammi diviso per qualche valore.

Supponendo che questo sia il caso, hai un ulteriore problema in quanto hai progettato il tuo algoritmo, devi riavvolgere all'inizio e cercare in avanti per ciascuno dei 5 fotogrammi - se hai generato i tuoi offset in anticipo , quindi ordinato la lista, ffmpeg potrebbe essere in grado di recuperare i frame in un singolo passaggio.

HTH

C.

1

Il problema qui è la parola casuale. Ho avuto successo con la durata del video e poi ho cercato di ottenere un frame con quella durata casuale. Facilmente modificabile per altri frame:

$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

questo codice veramente ottimo :) – danielad

+0

penso che mettere la cosa if (count (output)) su un ciclo for ... renda il valore casuale con più miniature giuste? – danielad

-5

Hai scritto un errore nel tuo ciclo.

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

Diciamo che il ciclo for viene eseguito all'infinito fino a quando non è rotto. Se l'istruzione if è falsa la prima volta, non è possibile raggiungere $i++ e il ciclo è quindi infinito.

È necessario posizionare $i++ nella parte inferiore del ciclo for, quindi l'esecuzione sarà 2 secondi anziché 20 minuti.

+0

Il comportamento è destinato.Si suppone che il ciclo venga eseguito finché non sono stati selezionati cinque fotogrammi, quindi il conteggio aumenta solo quando esiste un fotogramma selezionato a caso. – joequincy

Problemi correlati