使用 PHP 从 FFMPEG 读取实时输出
Reading live output from FFMPEG using PHP
我正在处理的问题是在执行 ffmpeg 命令时获取 shell 输出,并使用 php 将其写入 html 页面。
经过一些研究,我在这里发现了一个非常相似的请求:,它看起来很完美,但它根本不起作用。
基本思路是使用 AJAX 请求调用 PHP 脚本,该脚本应执行命令并回显进程中的实时读取内容,注意使用 this.readyState==3(否则JS脚本只有完成后才会收到响应)
对于 PHP 部分,我尝试使用上面答案中的代码,(显然适合我的需要):
function liveExecuteCommand($command){
while (@ ob_end_flush()); // end all output buffers if any
$proc = popen($command, 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "<pre>$live_output</pre>";
@ flush();
}
pclose($proc);
}
我使用的 AJAX 部分
function getLiveStream(){
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState == 3) {
document.getElementById("result").innerHTML = this.responseText;
}
};
var url = 'process/getlive';
ajax.open('GET', url,true);
ajax.send();
}
遗憾的是,这不起作用。
正在执行的命令是这样的:'ffmpeg.exe -i "C:/Users/BACKUP/Desktop/xampp/htdocs/testarea/test.mp4" -map 0:0 -map 0:1 -c:v libx264 -preset fast -crf 26 -c:a libmp3lame -ar 24000 -q:a 5 "C:\Users\BACKUP\Desktop\xampp\htdocs\testarea\output/test.mkv"'
,我测试过它有效。
当我 运行 html 页面和其中的 ajax 脚本时,ffmpeg 命令甚至没有 运行,因为我检查了任务管理器。它只是 returns 一个空白文本。
当我 运行 php 脚本本身时,命令 运行s,文件被转换但它根本不回显任何东西。
经过更多研究后,我还找到了这个页面,它似乎正是为了这个目的而制作的:https://github.com/4poc/php-live-transcode/blob/master/stream.php
相关部分在最后,前面的代码是处理ffmpeg特有的选项。但它也没有用,结果完全相同。
现在我正在考虑将输出简单地写入一个文件并从中动态读取它,但我真的很想知道为什么它们都不适合我。
编辑: 回答如何从正在写入的临时文件中获取内容,而不是直接从进程中获取内容。
ffmpeg 将其状态写入 stderr
而不是 stdout
参见 http://php.net/manual/en/function.popen.php 示例 2
<?php
error_reporting(E_ALL);
/* Add redirection so we can get stderr. */
$handle = popen('/path/to/executable 2>&1', 'r');
echo "'$handle'; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);
?>
我正在处理的问题是在执行 ffmpeg 命令时获取 shell 输出,并使用 php 将其写入 html 页面。
经过一些研究,我在这里发现了一个非常相似的请求:
基本思路是使用 AJAX 请求调用 PHP 脚本,该脚本应执行命令并回显进程中的实时读取内容,注意使用 this.readyState==3(否则JS脚本只有完成后才会收到响应)
对于 PHP 部分,我尝试使用上面答案中的代码,(显然适合我的需要):
function liveExecuteCommand($command){
while (@ ob_end_flush()); // end all output buffers if any
$proc = popen($command, 'r');
$live_output = "";
$complete_output = "";
while (!feof($proc))
{
$live_output = fread($proc, 4096);
$complete_output = $complete_output . $live_output;
echo "<pre>$live_output</pre>";
@ flush();
}
pclose($proc);
}
我使用的 AJAX 部分
function getLiveStream(){
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState == 3) {
document.getElementById("result").innerHTML = this.responseText;
}
};
var url = 'process/getlive';
ajax.open('GET', url,true);
ajax.send();
}
遗憾的是,这不起作用。
正在执行的命令是这样的:'ffmpeg.exe -i "C:/Users/BACKUP/Desktop/xampp/htdocs/testarea/test.mp4" -map 0:0 -map 0:1 -c:v libx264 -preset fast -crf 26 -c:a libmp3lame -ar 24000 -q:a 5 "C:\Users\BACKUP\Desktop\xampp\htdocs\testarea\output/test.mkv"'
,我测试过它有效。
当我 运行 html 页面和其中的 ajax 脚本时,ffmpeg 命令甚至没有 运行,因为我检查了任务管理器。它只是 returns 一个空白文本。
当我 运行 php 脚本本身时,命令 运行s,文件被转换但它根本不回显任何东西。
经过更多研究后,我还找到了这个页面,它似乎正是为了这个目的而制作的:https://github.com/4poc/php-live-transcode/blob/master/stream.php
相关部分在最后,前面的代码是处理ffmpeg特有的选项。但它也没有用,结果完全相同。
现在我正在考虑将输出简单地写入一个文件并从中动态读取它,但我真的很想知道为什么它们都不适合我。
编辑:
ffmpeg 将其状态写入 stderr
而不是 stdout
参见 http://php.net/manual/en/function.popen.php 示例 2
<?php
error_reporting(E_ALL);
/* Add redirection so we can get stderr. */
$handle = popen('/path/to/executable 2>&1', 'r');
echo "'$handle'; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);
?>