gpt4 book ai didi

php - 实时 ffmpeg shell 输出 PHP

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:57 25 4
gpt4 key购买 nike

好吧,这几天我一直在和这个问题作斗争。在我的本地 Windows 机器上运行良好,但似乎无法在我的 CentOS 服务器上运行。我的脚本获取正在转换的视频的持续时间,还获取它在 ffmpeg 中处理的当前秒数。但是,它只是抓取 ffmpeg 输出的“输入文件”并停在那里。由于某种原因,ffmpeg 喜欢在 STDERR 管道上输出,我尝试使用两个管道(STDOUT [1] 和 STDERR [2])。很奇怪。

$filename = "somefilename.tmp";
$descriptor = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);

$ffmpeg = "ffmpeg -i /var/www/spotloader/videos/flipped/tmp/".$file."_comb.ts -vcodec mpeg2video -acodec pcm_s16le -pix_fmt yuv422p -vtag xdvb -b:v 13000k -r 30000/1001 /var/www/spotloader/videos/flipped/tmp/".$file.".mov";

//open the process
$process = proc_open($ffmpeg, $descriptor, $pipes, NULL, $_ENV);

//if the process opened
if ( is_resource( $process ) == true )
{
//get process status
$procStatus = proc_get_status( $process );

//if its running, let node know
if ( $procStatus['running'] )
{
//nodejs socket, nothing wrong here
$this->_sendSocket('converting', array('filename' => str_replace('.tmp', '', $file)));
}

//while the process is running
while( $procStatus['running'] === true )
{
//there is output in the pipe
if ( !feof( $pipes[1] ) )
{
//get the output
$data = fgets($pipes[1], 128);
//match the outputs duration and save it.
if(preg_match('/Duration:\s([0-9]{2}:[0-9]{2}:[0-9]{2})/', $data, $matches))
{
static $duration;
$duration = $this->_convertToSeconds($matches[1]);
}

//match the outputs current encoding time
if(preg_match('/time=([0-9]{2}:[0-9]{2}:[0-9]{2})/', $data, $matches))
{
//convert to seconds works fine, so it is not included.
$curTime = $this->_convertToSeconds($matches[1]);
//nodejs socket, nothing wrong here
$this->_sendSocket('update', array('percent' => round( ($curTime / $duration) * 100), 'filename' => str_replace('.tmp', '', $file)));
}
}

//update process status
$procStatus = proc_get_status( $process );
}

//nodejs socket, nothing wrong here
$this->_sendSocket('converted', array('percent' => 100, 'filename' => str_replace('.tmp', '', $file)));
}

我使用上面的 PHP 代码接收到的 FFMPEG 输出

ffmpeg version 1.2.1 Copyright (c) 2000-2013 the FFmpeg developers
built on May 10 2013 15:14:14 with gcc 4.4.6 (GCC) 20120305 (Red Hat 4.4.6-4)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64
--mandir=/usr/share/man --enable-shared --enable-runtime-cpudetect --enable-gpl
--enable-version3 --enable-postproc --enable-avfilter --enable-pthreads
--enable-x11grab --enable-vdpau --disable-avisynth --enable-frei0r --enable-libopencv
--enable-libdc1394 --enable-libgsm --enable-libmp3lame --enable-libnut
--enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-librtmp --enable-libspeex --enable-libtheora --enable-libvorbis
--enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid
--extra-cflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC'
--disable-stripping
libavutil 52. 18.100 / 52. 18.100
libavcodec 54. 92.100 / 54. 92.100
libavformat 54. 63.104 / 54. 63.104
libavdevice 54. 3.103 / 54. 3.103
libavfilter 3. 42.103 / 3. 42.103
libswscale 2. 2.100 / 2. 2.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 2.100 / 52. 2.100
[mpegts @ 0x243c620] max_analyze_duration 5000000 reached at 5016000 microseconds
Input #0, mpegts, from '/var/www/spotloader/videos/flipped/tmp/Wildlife10.tmp_comb.ts':
Duration: 00:00:02.02, start: 1.389978, bitrate: 227018 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: mpeg2video (4:2:2) ([2][0][0][0] / 0x0002), yuv422p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0:1[0x101](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, 1 channels (FL+FR), s16p, 128 kb/s

FFMPEG 输出我期待最后的“time=00:00:00”是我需要实时捕获的。这是通过直接在 shell 中运行 FFMPEG 命令来实现的。

ffmpeg version 1.2.1 Copyright (c) 2000-2013 the FFmpeg developers
built on May 10 2013 15:14:14 with gcc 4.4.6 (GCC) 20120305 (Red Hat 4.4.6-4)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64
--mandir=/usr/share/man --enable-shared --enable-runtime-cpudetect --enable-gpl
--enable-version3 --enable-postproc --enable-avfilter --enable-pthreads
--enable-x11grab --enable-vdpau --disable-avisynth --enable-frei0r --enable-libopencv
--enable-libdc1394 --enable-libgsm --enable-libmp3lame --enable-libnut
--enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-librtmp --enable-libspeex --enable-libtheora --enable-libvorbis
--enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid
--extra-cflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC'
--disable-stripping
libavutil 52. 18.100 / 52. 18.100
libavcodec 54. 92.100 / 54. 92.100
libavformat 54. 63.104 / 54. 63.104
libavdevice 54. 3.103 / 54. 3.103
libavfilter 3. 42.103 / 3. 42.103
libswscale 2. 2.100 / 2. 2.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 2.100 / 52. 2.100
[mpegts @ 0x10c9620] max_analyze_duration 5000000 reached at 5016000 microseconds
Input #0, mpegts, from '/var/www/spotloader/videos/flipped/tmp/Wildlife10.tmp_comb.ts':
Duration: 00:00:02.02, start: 1.389978, bitrate: 227018 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: mpeg2video (4:2:2) ([2][0][0][0] / 0x0002), yuv422p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
Stream #0:1[0x101](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, 1 channels (FL+FR), s16p, 128 kb/s
Channel layout 'stereo' with 2 channels does not match specified number of channels 1: ignoring specified channel layout
Output #0, mov, to '/var/www/spotloader/videos/flipped/tmp/Wildlife10.tmp.mov':
Metadata:
encoder : Lavf54.63.104
Stream #0:0: Video: mpeg2video (xdvb / 0x62766478), yuv422p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 13000 kb/s, 30k tbn, 29.97 tbc
Stream #0:1(eng): Audio: pcm_s16le (sowt / 0x74776F73), 48000 Hz, stereo, s16, 1536 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (mpeg2video -> mpeg2video)
Stream #0:1 -> #0:1 (mp2 -> pcm_s16le)
Press [q] to stop, [?] for help
Input stream #0:1 frame changed from rate:48000 fmt:s16p ch:1 chl:1 channels (FL+FR) to rate:48000 fmt:s16p ch:2 chl:stereo
Input stream #0:1 frame changed from rate:48000 fmt:s16p ch:2 chl:stereo to rate:48000 fmt:s16p ch:1 chl:mono
Input stream #0:1 frame changed from rate:48000 fmt:s16p ch:1 chl:mono to rate:48000 fmt:s16p ch:2 chl:stereo
Input stream #0:0 frame changed from size:1920x1080 fmt:yuv422p to size:1280x720 fmt:yuv422p0
Input stream #0:1 frame changed from rate:48000 fmt:s16p ch:2 chl:stereo to rate:44100 fmt:s16p ch:2 chl:stereo
frame= 741 fps= 52 q=2.6 size= 43866kB time=00:00:24.65 bitrate=14573.5kbits/s dup=5 drop=0

有什么想法吗?从 Windows 切换到 CentOS 需要改变什么?

编辑:我使用 popen 让它工作反而。它还减少了我的代码。如果其他人确实有解决方案,请继续并发布。谢谢!

最佳答案

这里有一些东西

这是我前一段时间正在做的一个项目。我认为它非常接近你想要的。请注意,它有点问题而且不是很安全

ffmpeTest.php

<html>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<h2>Video Uploader</h2>

<form method="post" enctype="multipart/form-data">
<input type="file" required id="upload" name="file"/>
<input type="submit" value="Upload video" id="upload" name="upload"/>
</form>

<?
ini_set('memory_limit', '1000M');
ini_set('post_max_size', '1000M');
ini_set('upload_max_filesize', '1000M');


if(isset($_POST['upload'])){

$ffmpeg = '/usr/local/Cellar/ffmpeg/1.2.1/bin/ffmpeg';//path to ffmpeg

$origVideo = $_FILES['file']['tmp_name'];
$newVideo = "videos/".$_FILES['file']['name'];
move_uploaded_file($origVideo, $newVideo);
$time = time();

$command1 = $ffmpeg.' -i "'.$newVideo.'" videos/'.$time.'.flv ';
shell_exec(sprintf('%s > videos/block.txt 2>&1 &', $command1));
}
?>

<div id="load"></div>
<script>

$('#thumb').load(function(){
setInterval(function() {
$('#load').load('http://localhost/Playground/ffmpeLoader.php ffmpeLoader.php');
}, 600);
});
</script>
</body>
</html>

ffmpeloader.php

<?
$content = @file_get_contents('videos/block.txt');

if($content){
//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 time in the file that is already encoded
preg_match_all("/time=(.*?) bitrate/", $content, $matches);

$rawTime = array_pop($matches);

//this is needed if there is more than one match
if (is_array($rawTime)){$rawTime = array_pop($rawTime);}

//rawTime is in 00:00:00.00 format. This converts it to seconds.
$ar = array_reverse(explode(":", $rawTime));
$time = floatval($ar[0]);
if (!empty($ar[1])) $time += intval($ar[1]) * 60;
if (!empty($ar[2])) $time += intval($ar[2]) * 60 * 60;

//calculate the progress
$progress = round(($time/$duration) * 100);
echo "<progress id='p' max='100' value='" . $progress . "'></progress><span> ".$progress."%</span>";


}
if($progress == 100){


echo '<p> Done!</p>';
}
?>

关于php - 实时 ffmpeg shell 输出 PHP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19007363/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com