J'ai joué avec ça pendant quelques jours. Ce truc "ffmpegprogress" m'a aidé, mais il était très difficile de le faire fonctionner avec mon installation, et difficile de lire le code.
Afin de montrer la progression de ffmpeg, vous devez faire ce qui suit :
- exécuter la commande ffmpeg depuis php sans qu'elle attende une réponse (pour moi, c'était la partie la plus difficile)
- dire à ffmpeg d'envoyer sa sortie vers un fichier
- à partir de l'interface (AJAX, Flash, etc.), tapez directement sur ce fichier ou sur un fichier php qui peut extraire la progression de la sortie de ffmpeg.
Voici comment j'ai résolu chaque partie :
1. L'idée suivante m'est venue de "ffmpegprogress". Voici ce qu'il a fait : un fichier PHP en appelle un autre via un socket http. Le second exécute le "exec" et le premier fichier ne fait que s'y accrocher. Pour moi, son implémentation était trop complexe. Il utilisait "fsockopen". J'aime bien CURL. Alors voici ce que j'ai fait :
$url = "http://".$_SERVER["HTTP_HOST"]."/path/to/exec/exec.php";
curl_setopt($curlH, CURLOPT_URL, $url);
$postData = "&cmd=".urlencode($cmd);
$postData .= "&outFile=".urlencode("path/to/output.txt");
curl_setopt($curlH, CURLOPT_POST, TRUE);
curl_setopt($curlH, CURLOPT_POSTFIELDS, $postData);
curl_setopt($curlH, CURLOPT_RETURNTRANSFER, TRUE);
// # this is the key!
curl_setopt($curlH, CURLOPT_TIMEOUT, 1);
$result = curl_exec($curlH);
En fixant CURLOPT_TIMEOUT à 1, cela signifie qu'il attendra 1 seconde pour une réponse. Il serait préférable que cette valeur soit inférieure. Il existe aussi le CURLOPT_TIMEOUT_MS qui prend des millisecondes, mais il n'a pas fonctionné pour moi.
Après 1 seconde, CURL raccroche, mais la commande exec continue de fonctionner. Partie 1 résolue.
BTW - Quelques personnes ont suggéré d'utiliser la commande "nohup" pour cela. Mais cela n'a pas semblé fonctionner pour moi.
*Avoir un fichier php sur votre serveur qui peut exécuter du code directement sur la ligne de commande est un risque de sécurité évident. Vous devriez avoir un mot de passe, ou coder les données du message d'une manière ou d'une autre.
2. Le script "exec.php" ci-dessus doit aussi dire à ffmpeg de sortir dans un fichier. Voici le code pour cela :
exec("ffmpeg -i path/to/input.mov path/to/output.flv 1> path/to/output.txt 2>&1");
Notez le "1> path/to/output.txt 2>&1". Je ne suis pas un expert en ligne de commande, mais d'après ce que je peux dire, cette ligne dit "envoyer la sortie normale dans ce fichier, ET envoyer les erreurs au même endroit". Consultez cette url pour plus d'informations : http://tldp.org/LDP/abs/html/io-redirection.html
3. Depuis le front-end, appelez un script php script en lui donnant l'emplacement du fichier output.txt. Ce fichier php va alors extraire la progression du fichier texte. Voici comment j'ai fait :
// # get duration of source
preg_match("/Duration: (.*?), start:/", $content, $matches);
$rawDuration = $matches[1];
// # rawDuration is in 00:00:00.00 format. This converts it to seconds.
$ar = array_reverse(explode(":", $rawDuration));
$duration = floatval($ar[0]);
if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;
// # get the current time
preg_match_all("/time=(.*?) bitrate/", $content, $matches);
$last = array_pop($matches);
// # this is needed if there is more than one match
if (is_array($last)) {
$last = array_pop($last);
}
$curTime = floatval($last);
// # finally, progress is easy
$progress = $curTime/$duration;
J'espère que cela aidera quelqu'un.