TRi*_*RiG 5 php ffmpeg shell-exec
我想要一个PHP函数,它接收文件的路径并返回有关它的信息数组.PHP文件可以调用FFmpeg.
返回的数据应该是这样的
Array(
[mime] => video/ogg
[container] => Ogg
[video] => Theora
[audio] => Vorbis
[duration] => 20.3 // in seconds
)
Array(
[mime] => audio/ogg
[container] => Ogg
[video] =>
[audio] => FLAC
[duration] => 3
)
Array(
[mime] => image/gif
[container] => GIF
[video] => Animated GIF
[audio] =>
[duration] => 2
)
Array(
[mime] => video/webm
[container] => WebM
[video] => VP8
[audio] => Vorbis
[duration] => 900.7
)
false // not a media file
Run Code Online (Sandbox Code Playgroud)
我从未使用FFmpeg或使用PHP的shell_exec()功能,但似乎FFmpeg会以相当难以解析的格式提供有关视频(或音频文件)的信息.我认为这样的事情是可能的.
ste*_*esu 10
FFmpeg可以完成你想要的任何事情,但你是正确的,它几乎不可能解析格式.如果您在基于UNIX的系统上使用操作系统和FFmpeg的功能来进行解析而不是让PHP尝试理解输出,那么实际上会更快.几个月前我为了类似的目的开发了以下shell命令.
fulltime=`ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//`;hour=`echo $fulltime | cut -d ':' -f 1`;minute=`echo $fulltime | cut -d ':' -f 2`;second=`echo $fulltime | cut -d ':' -f 3 | cut -d '.' -f 1`;echo `expr 3600 \* $hour + 60 \* $minute + $second`
Run Code Online (Sandbox Code Playgroud)
pipe(|)告诉UNIX将前一个命令的输出作为下一个命令的输入传递.分号(;)告诉UNIX开始一个新命令.UNIX shell还允许动态变量创建.要创建一个变量,你只需说var=value.要调用此变量,您必须使用美元符号,例如$var.
我的命令基本上取输出ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//并存储为fulltime.此命令进一步细分:
ffmpeg -i MOVIE.AVI 2>&1表示显示-iMOVIE.AVI的info().该2>&1相信重定向输出到管道,而不是到屏幕(使这个很久以前,所以我不清楚上)
grep 'Duration'将获取输入(输出ffmpeg -i MOVIE.AVI 2>&1),找到单词'Duration',并仅输出包含该单词的行.
cut -d ' ' -f 4将获取输入(前一个语句的输出),将其拆分为每个空格(' '),并仅输出其中的第四个.这是因为FFmpeg的输出类似于:
MOVIE.AVI
video encoder, yada yada
audio encoder, yada yada
bitrates and stuff
Duration: hh:mm:ss fulltime: 00:30:00.1
Run Code Online (Sandbox Code Playgroud)
换句话说,包含"持续时间"的行的第四个"部分"是实际持续时间...以小时,分钟和秒为单位(小数点后1位).
sed s/,//意味着毫无意义地替换','.这可能是一个很好的理由.
在此之后,我创建了三个变量hour,minute以及second:
hour=`echo $fulltime | cut -d ':' -f 1`;
minute=`echo $fulltime | cut -d ':' -f 2`;
second=`echo $fulltime | cut -d ':' -f 3 | cut -d '.' -f 1`;
Run Code Online (Sandbox Code Playgroud)
请注意,我将小时设置为输出echo $fulltime | cut -d ':' -f 1.如果我要在每个冒号分开时间,抓住第一部分(:)
我做了与分钟类似的事情,然后我用秒做同样的事情我只在最后砍掉任何小数.如果您在shell中工作,则必须删除此十进制数,因为该expr命令(我用于计算小时,分钟和秒的秒数)仅执行整数数学运算.如果你希望保持小数的持续时间,你将在这一点上必须返回PHP的小时,分钟和秒,并在那里进行解析.通过将以上内容替换为以下内容,最容易实现:
echo $fulltime
Run Code Online (Sandbox Code Playgroud)
这将在您调用之后向PHP返回一个字符串,例如"00:30:00.1" shell_exec(),然后您可以使用它轻松解析explode(':',$string).
要继续直接从shell获取秒数:
在获得了几小时,几分钟和几秒钟之后,出现了神奇的界限:
echo `expr 3600 \* $hour + 60 \* $minute + $second`
Run Code Online (Sandbox Code Playgroud)
该expr命令表示执行数学表达式.不幸的是,这是相当愚蠢的.首先,需要转义特殊字符(*在UNIX中是通配符,所以你必须使用它\*来表示乘法).接下来,它只执行整数数学运算.正如您所看到的,将小时乘以3600,分钟乘以60,并将它们全部加在一起相当容易.
整个庞大命令的输出只是一个数字.视频持续的秒数.它适用于所有视频格式.
请注意,这只是持续时间.对于视频编码器和音频编码器,您可能希望使用类似的方法,减去最后的数学运算.通用的解决方案是:
ffmpeg -i MOVIE.AVI 2>&1 | grep 'Something unique to the line you want' | cut -d ' ' -f <the "section" you want>
Run Code Online (Sandbox Code Playgroud)
这个输出可以继续在shell中解析(就像我上面做的那样)或者它可以传递给PHP.