查询音频/视频文件的信息

时间:2023-04-08
本文介绍了查询音频/视频文件的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我想要一个 PHP 函数,它接收文件的路径并返回有关它的信息数组.PHP文件可以调用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.

返回的数据应该类似于

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'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.

推荐答案

FFmpeg 几乎可以做您想做的一切,但您说得对,它几乎无法解析格式.如果您在基于 UNIX 的系统上使用操作系统和 FFmpeg 的功能进行解析,而不是让 PHP 尝试理解输出,那么实际上会更快.几个月前,我出于类似目的开发了以下 shell 命令.

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.

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`

管道 (|) 告诉 UNIX 将前一个命令的输出作为输入传递给下一个命令.分号 (;) 告诉 UNIX 开始一个新命令.UNIX shell 还允许动态创建变量.要创建变量,您只需说var=value.要调用此变量,您必须使用美元符号,例如 $var.

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 say var=value. To recall this variable you must use a dollar-sign, such as $var.

我的命令基本上采用 ffmpeg -i MOVIE.AVI 2>&1 | 的输出grep '持续时间' |剪切 -d ' ' -f 4 |sed s/,// 并将其存储为 fulltime.此命令进一步细分:

My command essentially takes the output of ffmpeg -i MOVIE.AVI 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,// and stores it as fulltime. This command is further broken down:

ffmpeg -i MOVIE.AVI 2>&1 表示显示 MOVIE.AVI 的信息(-i).2>&1 我相信将输出重定向到管道而不是屏幕(这是很久以前做的,所以我不清楚)

ffmpeg -i MOVIE.AVI 2>&1 means to display info (-i) for MOVIE.AVI. The 2>&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' 将获取输入(这是 ffmpeg -i MOVIE.AVI 2>&1 的输出),找到单词 'Duration', 并仅输出包含该单词的行.

grep 'Duration' will take the input (which was the output of ffmpeg -i MOVIE.AVI 2>&1), find the word 'Duration', and output only the line that contained that word.

cut -d ' ' -f 4 将获取输入(前一条语句的输出),在每个空格处将其拆分(' '),然后只输出其中的第四个.这是因为 FFmpeg 的输出看起来像:

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:

MOVIE.AVI
video encoder, yada yada
audio encoder, yada yada
bitrates and stuff
Duration: hh:mm:ss fulltime: 00:30:00.1

换句话说,包含持续时间"的行的第四个部分"是实际持续时间……以小时、分钟和秒为单位(保留 1 个小数位).

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/,// 表示将 ',' 替换为空.这可能是有充分理由的.

sed s/,// means to replace ',' with nothing. There was probably a good reason for this.

在此之后,我创建了三个变量 hourminutesecond:

After this I created the three variables hour, minute, and 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`;

请注意,我正在为 echo $fulltime | 的输出设置小时.cut -d ':' -f 1.如果我要在每个冒号(:)

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 (:)

我对分钟做了类似的处理,然后我对秒做同样的处理,只是在最后去掉了任何小数点.如果您在 shell 中工作,则必须删除这个小数点,因为 expr 命令(我曾经用它从小时、分钟和秒计算秒)只执行整数数学运算.如果您希望在持续时间内保留小数,此时您必须将小时、分钟和秒返回给 PHP 并在那里进行解析.将以上内容替换为:

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:

echo $fulltime

这将在您调用 shell_exec() 后向 PHP 返回一个字符串,例如00:30:00.1",然后您可以使用 explode(':',$string).

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 using explode(':',$string).

继续直接从 shell 获取秒数:

To continue with getting the seconds directly from shell:

在得到小时、分钟和秒后,出现了神奇的一行:

After getting the hours, minutes, and seconds came the magical line:

echo `expr 3600 * $hour + 60 * $minute + $second`

expr 命令表示执行数学表达式.不幸的是,它相当愚蠢.首先,需要对特殊字符进行转义(* 在 UNIX 中是通配符,因此必须使用 * 表示乘法).接下来,它只执行整数数学.如您所见,将小时乘以 3600,分钟乘以 60,然后将它们加在一起是相当容易的.

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:

ffmpeg -i MOVIE.AVI 2>&1 | grep 'Something unique to the line you want' | cut -d ' ' -f <the "section" you want>

这个输出可以继续在 shell 中解析(就像我在上面所做的那样)或者它可以传递给 PHP.

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.

这篇关于查询音频/视频文件的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:我收到错误“使用了已弃用的像素格式,请确保您使用 ffmpeg 正确设置了范围"……有人可以检查我下面的代码吗 下一篇:在php中使用ffmpeg为视频添加水印

相关文章