查询音频/视频文件的信息
我想要一个 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
我从未使用过 FFmpeg 或 PHP 的 shell_exec() 函数,但 FFmpeg 似乎会以相当难以理解的方式提供有关视频(或音频文件)的信息解析格式。不过,我认为这样的事情是可能的。
I want a PHP function which receives the path to a file and returns an array of information about it. The PHP file can call FFmpeg.
Returned data should be something like
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
I've never worked with FFmpeg or with PHP's shell_exec()
function, but it seems that FFmpeg will give information about videos (or audio files) in a fairly hard-to-parse format. I assume that something like this is possible, though.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
FFmpeg 几乎可以完成您想要的所有操作,但您是对的,它的格式几乎无法解析。如果您在基于 UNIX 的系统上使用操作系统和 FFmpeg 的功能来进行解析,而不是让 PHP 尝试理解输出,实际上会更快。几个月前,我出于类似的目的开发了以下 shell 命令。
管道 (
|
) 告诉 UNIX 将上一个命令的输出作为下一个命令的输入传递。分号 (;
) 告诉 UNIX 开始一个新命令。 UNIX shell 还允许动态创建变量。要创建变量,您只需输入var=value
。要调用此变量,您必须使用美元符号,例如$var
。我的命令本质上采用 ffmpeg -i MOVIE.AVI 2>&1 | 的输出grep '持续时间' |切 -d ' ' -f 4 | sed s/,// 并将其存储为
fulltime
。该命令进一步细分为:ffmpeg -i MOVIE.AVI 2>&1
表示显示 MOVIE.AVI 的信息 (-i
)。我相信2>&1
将输出重定向到管道而不是屏幕(很久以前就做了这个,所以我不清楚)grep 'Duration' 将获取输入(这是
ffmpeg -i MOVIE.AVI 2>&1
的输出),找到单词“Duration”,并仅输出包含该单词的行。cut -d ' ' -f 4
将获取输入(上一条语句的输出),在每个空格处将其分割 (' '
),并仅输出其中第四个。这是因为 FFmpeg 的输出看起来像这样:换句话说,包含“Duration”的行的第四个“部分”是实际持续时间...以小时、分钟和秒为单位(带 1 位小数)。
sed s/,//
表示将 ',' 替换为空。这可能是有充分理由的。之后,我创建了三个变量
hour
、month
和second
:请注意,我将 hour 设置为
echo 的输出$全职|剪切 -d ':' -f 1
。如果我要在每个冒号处分割时间(:
),抓住第一部分,我对分钟做类似的事情,然后我只对秒做同样的事情,我在末尾截掉任何小数。如果您在 shell 中工作,则必须删除此小数,因为
expr
命令(我用它来根据小时、分钟和秒计算秒)仅执行整数数学运算。如果您希望保留持续时间的小数,此时您必须将小时、分钟和秒返回给 PHP 并在那里进行解析。通过将上面的内容替换为最容易做到这一点:在调用
shell_exec()
后,这将向 PHP 返回一个字符串,例如“00:30:00.1”,然后您可以使用以下命令轻松解析该字符串爆炸(':',$string)
。继续直接从 shell 获取秒:
获取小时、分钟和秒后,出现了神奇的一行:
expr
命令表示执行数学表达式。不幸的是,这是相当愚蠢的。首先,特殊字符需要转义(*
在UNIX中是通配符,所以必须使用\*
来表示乘法)。接下来,它仅执行整数数学运算。正如您所看到的,将小时乘以 3600、分钟乘以 60,然后将它们全部相加,这是相当容易的。整个庞大命令的输出只是一个数字。视频持续的秒数。它应该适用于所有视频格式。
请注意,这只是持续时间。至于视频编码器和音频编码器,您需要使用类似的方法,减去最后的数学。一个通用的解决方案是:
它的输出可以继续在 shell 中解析(就像我上面所做的那样),也可以将其传递给 PHP。
FFmpeg can do just about everything you want, but you're correct that it's in a nearly impossible to parse format. It's actually quicker if you're on a UNIX-based system to use the Operating System and the features of FFmpeg to do the parsing rather than have PHP try to understand the output. I developed the following shell command several months ago for a similar purpose.
The pipe (
|
) tells UNIX to pass the output of the previous command as the input to the next command. The semi-colon (;
) tells UNIX to begin a new command. The UNIX shell also allows for on-the-fly variable creation. To create a variable you just sayvar=value
. To recall this variable you must use a dollar-sign, such as$var
.My command essentially takes the output of
ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//
and stores it asfulltime
. This command is further broken down:ffmpeg -i MOVIE.AVI 2>&1
means to display info (-i
) for MOVIE.AVI. The2>&1
I believe redirected the output to a pipe rather than to the screen (made this forever ago, so I'm not clear on that)grep 'Duration'
will take the input (which was the output offfmpeg -i MOVIE.AVI 2>&1
), find the word 'Duration', and output only the line that contained that word.cut -d ' ' -f 4
will take the input (the output of the previous statement), split it up at every space (' '
), and output only the fourth of these. This is because the output of FFmpeg looks something like:In other words, the fourth "section" of the line containing "Duration" is the actual duration... In hours, minutes, and seconds (with 1 decimal place).
sed s/,//
means to replace ',' with nothing. There was probably a good reason for this.After this I created the three variables
hour
,minute
, andsecond
:Notice that I'm setting hour to the output of
echo $fulltime | cut -d ':' -f 1
. Grabbing the first portion if I were to split the time at every colon (:
)I do similar with minutes, then I do the same with seconds only I chop off any decimal at the end. This decimal has to be removed if you're working in shell since the
expr
command (which I used to calculate seconds from hours, minutes, and seconds) only performs integer math. If you wish to keep the decimal for duration, you will at this point have to return the hours, minutes, and seconds to PHP and do the parsing there. This would be most easily done by replacing the above with:This will return a string such as "00:30:00.1" to PHP after you have called
shell_exec()
, which you can then easily parse usingexplode(':',$string)
.To continue with getting the seconds directly from shell:
After getting the hours, minutes, and seconds came the magical line:
The
expr
command says to perform a mathematical expression. Unfortunately it's rather stupid. First, special characters need to be escaped (*
is a wildcard in UNIX, so you have to use\*
to mean multiply). Next, it only performs integer math. It was fairly easy, as you can see, to multiply hours by 3600, minutes by 60, and add them all together.The output of this entire, massive command, will just be a single number. The number of seconds that the video lasts. It should work for all video formats.
Mind you this is just duration. As for video encoder and audio encoder you would want to use similar methods, minus the math at the end. A generic solution would be:
The output of this can either continue to be parsed in shell (as I did above with the time) or it can be passed to PHP.
我会看一下 Mediainfo。如果你传入 --Output=XML,它会给你这样的东西:
I'd take a look at Mediainfo. If you pass in --Output=XML, it'll give you something like this:
可能想尝试一下这个人。当你可以利用库时总是好的:
http://www.phpclasses.org/browse/file/1582.html
Might want to try this guy out. Always good when you can leverage a library:
http://www.phpclasses.org/browse/file/1582.html
在搜索 php 音频解析器时发现 http://getid3.sourceforge.net/
希望这有帮助,
Cears
Found http://getid3.sourceforge.net/ when searching for php audio parser
Hope this helps,
Chears