捕获FFMPEG输出

12

为了尝试昨天的问题的解决方案,我需要读取来自ffmpeg的输出。这是一个与那里的问题不同的问题,所以我提出了一个新问题。

我应该如何在PHP中获取ffmpeg -i命令的输出?

这是我的尝试:

<?PHP
    error_reporting(E_ALL);
    $src = "/var/videos/video1.wmv";
    $command = "/usr/bin/ffmpeg -i " . $src;
    echo "<B>",$command,"</B><br/>";
    $command = escapeshellcmd($command);

    echo "backtick:<br/><pre>";
    `$command`;

    echo "</pre><br/>system:<br/><pre>";
    echo system($command);

    echo "</pre><br/>shell_exec:<br/><pre>";
    echo shell_exec($command);

    echo "</pre><br/>passthru:<br/><pre>";
    passthru($command);

    echo "</pre><br/>exec:<br/><pre>";
    $output = array();
    exec($command,$output,$status);
    foreach($output AS $o)
    {
            echo $o , "<br/>";
    }
    echo "</pre><br/>popen:<br/><pre>";
    $handle = popen($command,'r');
    echo fread($handle,1048576);
    pclose($handle);
    echo "</pre><br/>";
?>

这是我的输出:

<B>/usr/bin/ffmpeg -i /var/videos/video1.wmv</B><br/>
backtick:<br/>
    <pre></pre><br/>
system:<br/>
    <pre></pre><br/>
shell_exec:<br/>
    <pre></pre><br/>
passthru:<br/>
    <pre></pre><br/>
exec:<br/>
    <pre></pre><br/>
popen:<br/>
    <pre></pre><br/>

我不明白。 safe_mode 已关闭。 disable_functions 中没有任何内容。该目录被 www-data (我的 Ubuntu 系统上的 Apache 用户) 拥有。我从 exec()system() 获得了有效的状态,并且从命令行运行相同的命令会给我大量输出。我感觉我一定错过了一些显而易见的东西,但是我不知道是什么。

4个回答

29

问题在于您只捕获了标准输出(stdout),而没有捕获标准错误输出(stderr)(请参见标准流)。

修改这一行:

$command = "/usr/bin/ffmpeg -i " . $src;

进入

$command = "/usr/bin/ffmpeg -i " . $src . " 2>&1";

再试一次吧 :)


啊...是的。这很有道理,因为我的返回状态是1(而不是0)。我希望那样可以解决问题,但我仍然得到相同的结果,只是在开头加上了:“<B>/usr/bin/ffmpeg -i /var/videos/video1.wmv 2>&1</B>”。我会进行一些研究,看看Ubuntu在重定向stderr方面是否有所不同。 - Andrew Ensley
我可以确认以下代码应该可以工作。我曾经在一个业余项目中使用过这一行。exec('ffmpeg -i ' . escapeshellarg($filepath) . ' 2>&1', $output); - Werner
啊哈!我找到问题所在了。我的问题出在escapeshellcmd()函数上。它把"2>&1"改成了"2>&1"。我尝试了你的代码,它起作用了。我学到的教训是:在对命令进行所有修改之后再输出它=p。谢谢。 - Andrew Ensley

8
请使用ffprobe代替,它更快,支持JSON输出。
$output = shell_exec('ffprobe -v quiet -print_format json -show_format -show_streams "path/to/yourfile.ext"');
$parsed = json_decode($output, true);

您可以在一个PHP数组中找到所有视频信息!出于某种原因,这比使用ffmpeg -i要快得多。


1
哇,多么有用的函数!我不知道这个存在。谢谢! - Andrew Ensley
1
这也比每次初始化ffmpeg要快得多! - tweak2

4

获取输出状态和输出:

exec("ffmpeg -i input.avi output.mp4 2>&1", $output, $returnStatus);

print_r($output);

if($returnStatus === 0){
   // success
}
else {
   //fail
}

niiiiiiiiiiiiceeeeeeeeeeeee - Farzad

0

你可以使用 exec 和 print_r 来输出内容...

exec("ffmpeg -i input.avi -vcodec h264 -acodec aac -strict -2 output.mp4 2>&1",$output);

echo "<pre>";
print_r($output);
echo "</pre>";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接