代码之家  ›  专栏  ›  技术社区  ›  TRiG

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

  •  4
  • TRiG  · 技术社区  · 14 年前

    我想要一个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 回复  |  直到 11 年前
        1
  •  9
  •   stevendesu    14 年前

    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 显示信息的方式( -i )对于movie.avi.这个 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/,// 意思是将“,”替换为“Nothing”。这可能是一个很好的理由。

    在这之后,我创建了三个变量 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`;
    

    注意,我正在设置输出的小时数 echo $fulltime | cut -d ':' -f 1 . 如果我要在每个结肠上分开时间,就要抓起第一部分。( : )

    我用分钟做类似的事情,然后用秒做同样的事情,只在结尾处切掉小数。如果您在shell中工作,则必须删除此小数,因为 expr 命令(我用来从小时、分钟和秒计算秒)只执行整数数学。如果您希望将小数保留一段时间,那么此时必须将小时、分钟和秒返回给PHP,并在那里进行解析。将上述内容替换为:

    echo $fulltime
    

    这将在调用后向PHP返回一个字符串,如“00:30:00.1” shell_exec() ,然后您可以使用 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。

        2
  •  2
  •   Henrik Lied    14 年前

    我去看看 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
  •  1
  •   Brent    14 年前

    可能想试试这个家伙。当你可以利用一个图书馆时总是很好的: http://www.phpclasses.org/browse/file/1582.html

        4
  •  0
  •   Radu    13 年前

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

    希望这有帮助,

    切尔