查询音频/视频文件以获取信息

时间:2010-10-14 19:30:01

标签: 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

我从未使用FFmpeg或使用PHP的shell_exec()功能,但似乎FFmpeg会以相当难以解析的格式提供有关视频(或音频文件)的信息。我认为这样的事情是可能的。

4 个答案:

答案 0 :(得分: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`

管道(|)告诉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表示显示MOVIE.AVI的信息(-i)。我相信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

换句话说,包含“持续时间”的行的第四个“部分”是实际持续时间...以小时,分钟和秒为单位(小数点后1位)。

sed s/,//表示无任何替换','。这可能是一个很好的理由。

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

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的输出。如果我要在每个冒号(:

分割时间,抓住第一部分

我跟分钟做的相似,然后我只用秒做同样的事情,但我最后砍掉了小数。如果你在shell中工作,那么必须删除这个小数,因为expr命令(我用来计算小时,分钟和秒的秒数)只执行整数数学运算。如果你希望保持小数的持续时间,你将在这一点上必须返回PHP的小时,分​​钟和秒,并在那里进行解析。通过将上述内容替换为:

,这将是最容易实现的
echo $fulltime

这会在您调用shell_exec()后向PHP返回一个字符串,例如“00:30:00.1”,然后您可以使用explode(':',$string)轻松解析。

继续直接从shell获取秒数:

在获得了几小时,几分钟和几秒钟之后,出现了一条神奇的路线:

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

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>

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

答案 1 :(得分:2)

我会看一下Mediainfo。如果你传入--Output = XML,它会给你这样的东西:

<?xml version="1.0" encoding="UTF-8"?>
<Mediainfo>
<File>
<track type="General">
<Complete_name>Movie.webm</Complete_name>
<Format>Matroska</Format>
<File_size>215 MiB</File_size>
<Duration>28mn 39s</Duration>
<Overall_bit_rate>1 049 Kbps</Overall_bit_rate>
<Movie_name>Safari</Movie_name>
<Writing_application>Lavf52.78.0</Writing_application>
<Writing_library>Lavf52.78.0</Writing_library>
</track>

<track type="Video">
<ID>1</ID>
<Format>V_VP8</Format>
<Codec_ID>V_VP8</Codec_ID>
<Duration>28mn 39s</Duration>
<Bit_rate>529 Kbps</Bit_rate>
<Width>768 pixels</Width>
<Height>432 pixels</Height>
<Display_aspect_ratio>16:9</Display_aspect_ratio>
<Frame_rate>25.000 fps</Frame_rate>
<Bits__Pixel_Frame_>0.064</Bits__Pixel_Frame_>
<Stream_size>108 MiB (50%)</Stream_size>
<Language>Norwegian</Language>
</track>

<track type="Audio">
<ID>2</ID>
<Format>Vorbis</Format>
<Format_settings__Floor>1</Format_settings__Floor>
<Codec_ID>A_VORBIS</Codec_ID>
<Duration>28mn 39s</Duration>
<Bit_rate_mode>Constant</Bit_rate_mode>
<Bit_rate>500 Kbps</Bit_rate>
<Channel_s_>2 channels</Channel_s_>
<Sampling_rate>48.0 KHz</Sampling_rate>
<Resolution>16 bits</Resolution>
<Stream_size>102 MiB (48%)</Stream_size>
<Writing_library>libVorbis 20090709 (UTC 2009-07-09)</Writing_library>
<Language>Norwegian</Language>
</track>
</File>
</Mediainfo>

答案 2 :(得分:1)

可能想尝试这个家伙。在利用库时总是很好: http://www.phpclasses.org/browse/file/1582.html

答案 3 :(得分:0)

在搜索php音频解析器时找到http://getid3.sourceforge.net/

希望这有帮助,

CHEARS