【问题标题】:Querying an audio/video file for information查询音视频文件信息
【发布时间】:2010-10-14 19:30:00
【问题描述】:

我想要一个 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 会以相当难以解析的格式提供有关视频(或音频文件)的信息。不过,我认为这样的事情是可能的。

【问题讨论】:

    标签: php ffmpeg shell-exec


    【解决方案1】:

    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。

    【讨论】:

    • 哎哟!我会做一些实验。谢谢。
    • 好吧,在从 Ubuntu 9 更新到 10 的过程中,有些笨蛋在墙上的插座上关掉了我的电脑,并完全将它屏蔽了,所以我没有机会对此进行测试,但我无论如何,暂时将其标记为正确答案,因为它看起来应该可以工作。
    • “有什么办法可以退货”?看起来你在评论中不小心点击了enter。您想返回什么?
    • 不知道。我想我一定是在错误的评论框中输入了错误的内容,可能是在错误的网站上。我认为该评论是针对 h2g2 的。在我检查我的回复之前,我什至不知道评论在那里。已删除。
    • 输出格式可能与 .m2v 文件略有不同。如果你只是运行ffmpeg -i MOVIE.m2v 2&gt;&amp;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>
    

    【讨论】:

      【解决方案3】:

      可能想试试这个人。当您可以利用库时总是很好: http://www.phpclasses.org/browse/file/1582.html

      【讨论】:

        【解决方案4】:

        搜索php音频解析器时发现http://getid3.sourceforge.net/

        希望这会有所帮助,

        切碎

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多