我想使用 proc_open 从使用 ffmpeg 的视频中读取每一帧,然后使用 PHP 对这些帧进行处理。
这是一个相反的例子——它从 PHP 逐帧发送到 ffmpeg:
$descriptors = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "C:/error-output.txt", "a")
);
$frames = glob('Q:/images/*.jpg');
$command = "ffmpeg -f image2pipe -pix_fmt rgb24 -framerate 10 -c:v mjpeg -i - ".
"-r 10 -vcodec libx264 -pix_fmt yuv420p -preset faster -crf 17 ".
"-y test.mp4";
$ffmpeg = proc_open($command, $descriptors, $pipes);
if (!is_resource($ffmpeg))
{
die('Could not run ffmpeg');
}
foreach ($frames AS $frame)
{
fwrite($pipes[0], file_get_contents($frame) );
}
fclose($pipes[0]);
这就是我正在尝试但无法正确解决的方法:
$descriptors = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"), write to
2 => array("file", "C:/error-output.txt", "a")
);
$command = "ffmpeg -i 1.gif -ss 00:00:3 -s 650x390 -vframes 100 -c:v png -f image2pipe -";
$ffmpeg = proc_open($command, $descriptors, $pipes);
if (!is_resource($ffmpeg))
{
die('Could not run ffmpeg');
}
while (!feof($pipes[1]))
{
$frame = fread($pipes[1], 5000);
}
fclose($pipes[1]);
最大的问题是我不知道要从 ffmpeg 读取多少数据才能获得整个帧。
最佳答案
$descriptors = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("file", "C:/path/error-output.txt", "a")
);
$command = 'ffmpeg -i INPUT.mp4 -ss 00:00:10 -t 120 -c:v png -f image2pipe -compression_level 0 -';
$ffmpeg = proc_open($command, $descriptors, $pipes);
if (!is_resource($ffmpeg))
{
die('Could not run ffmpeg');
}
$k = 0;
$buff = '';
$blend = 0;
while (!feof($pipes[1]))
{
$buff .= fread($pipes[1], 50000);
$pos = strpos($buff, chr(137).'PNG', 1);
if ($pos !== false)
{
$frame = substr($buff, 0, $pos);
$buff = substr($buff, $pos);
handleFrame($frame, $k);
$k++;
}
}
handleFrame($buff, $k);
fclose($pipes[0]);
fclose($pipes[1]);
function handleFrame(&$str, $num)
{
$im = imagecreatefromstring($str);
...
}
关于php - 使用 php、ffmpeg 和 proc_open 逐帧读取视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61271954/