【问题标题】:How to get video duration in seconds? [duplicate]如何以秒为单位获取视频时长? [复制]
【发布时间】:2013-10-01 13:17:21
【问题描述】:

如何以秒为单位获取视频时长?

我尝试过的:

ffmpeg -i file.flv 2>&1 | grep "Duration"
  Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s


mediainfo file.flv | grep Duration
Duration : 39mn 43s

这很接近,但不是那么准确,2383 是 39.71 分钟

    ffmpeg -i file.flv 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'
2383

【问题讨论】:

标签: time awk ffmpeg duration


【解决方案1】:

有一个更好、更快且 CPU/HD 占用率更低的解决方案,只需使用 mediainfo 而不依赖于 awk:

mediainfo --Inform="General;%Duration%" input.m4v

【讨论】:

  • 请注意,这为您提供毫秒数,因此比任何 grep / awk 变体更准确。例如:mediainfo --Inform="General;%Duration%" video.mp4 --> 204466mediainfo video.mp4 | grep '^Duration' --> Duration : 3 min 24 s (= 204000ms)
【解决方案2】:

2383 是正确的。一分钟有 60 秒,而不是 100 秒。43/60 = .71

https://www.google.com/#q=39+minutes+43.08+seconds+in+seconds

【讨论】:

    【解决方案3】:

    使用awk

    mediainfo file.flv | awk '/Duration/ {print $3*60+$4}'
    2383
    
    ffmpeg -i file.flv 2>&1 | awk '/Duration/ {split($2,a,":");print a[1]*3600+a[2]*60+a[3]}'
    2383.08
    

    要处理不同的格式,请使用:

    cat file
    Duration : 39mn 43s
    Duration : 39s 43ms
    

    awk '/Duration/ {for (i=3;i<=NF;i++) if ($i~/[0-9]+mn$/) s+=$i*60; else if ($i~/[0-9]+s$/) s+=$i; else if ($i~/[0-9]+ms$/) s+=$i/10; print s;s=0}'  file
    2383
    43.3
    

    【讨论】:

    • 感谢 Jotne,正是我想要的!
    • 发现了一个错误。如果视频的长度小于 1 分钟,则您的 mediainfo 示例无法正确执行,因为 mediainfo 以不同的格式输出时间,例如:Duration : 36s 360ms 和使用您在 2520 中的代码的结果。请修复。
    • @IliaRostovtsev 你和问题发帖者user2783132是同一个人吗?
    • 不! :) 他也有同样的问题,我现在知道了..
    • @IliaRostovtsev 查看我更新的帖子
    【解决方案4】:

    它对我有用,试试吧:)

    $duration = shell_exec("ffmpeg -i \"". $input . "\" 2>&1");
    
    preg_match("/Duration: (\d{2}:\d{2}:\d{2}\.\d{2})/",$duration,$matches);
    $time = explode(':',$matches[1]);
    $hour = $time[0];
    $minutes = $time[1];
    $seconds = round($time[2]);
    
    $total_seconds = 0;
    $total_seconds += 60 * 60 * $hour;
    $total_seconds += 60 * $minutes;
    echo $total_seconds += $seconds;
    

    【讨论】:

      【解决方案5】:

      你可以使用

      ffprobe -v quiet -print_format xml -show_format -show_streams inputfile.flv
      

      它会返回一个像这样的xml

      <?xml version="1.0" encoding="UTF-8"?>
      <ffprobe>
          <streams>
              <stream index="0" codec_name="h264" codec_long_name="H.264 / AVC / MPEG-4 AVC / 
          MPEG-4 part 10" profile="High" codec_type="video" codec_time_base="1/50" codec_tag_string="avc1" codec_tag="0x31637661" width="1920" height="1080" has_b_frames="2" sample_aspect_ratio="0:1" display_aspect_ratio="0:1" pix_fmt="yuvj420p" level="40" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/12800" start_pts="0" start_time="0.000000" duration_ts="50176" duration="3.920000" bit_rate="4347640" nb_frames="98">
                      <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
                      <tag key="language" value="eng"/>
                      <tag key="handler_name" value="VideoHandler"/>
                  </stream>
              <stream index="1" codec_name="aac" codec_long_name="AAC (Advanced Audio Coding)" codec_type="audi
      
      o" codec_time_base="1/48000" codec_tag_string="mp4a" codec_tag="0x6134706d" sample_fmt="fltp" sample_rate="48000" channels="2" bits_per_sample="0" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/48000" start_pts="-1024" start_time="-0.021333" duration_ts="189184" duration="3.941333" bit_rate="122277" nb_frames="185">
                  <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
                  <tag key="language" value="eng"/>
                  <tag key="handler_name" value="SoundHandler"/>
              </stream>
          </streams>
      
          <format filename="inputfile.flv" nb_streams="2" format_name="mov,mp4,m4a,3gp,3g2,mj2" format_long_name="QuickTime / MOV" start_time="-0.021333" duration="3.942000" size="2194901" bit_rate="4454390">
              <tag key="major_brand" value="isom"/>
              <tag key="minor_version" value="512"/>
              <tag key="compatible_brands" value="isomiso2avc1mp41"/>
              <tag key="encoder" value="Lavf54.63.100"/>
          </format>
      </ffprobe>
      

      然后按视频流过滤,即通常属性索引为“0”的视频流,并获取属性“duration”的值,该值已经以秒为单位。

      【讨论】:

        【解决方案6】:

        我在 php 中使用过这个:

        exec('mediainfo --Inform="General;%Duration%" ' . $filename, $output);
        // type 86 sec = 85962.695312
        $durationInSec = ceil(ceil($output[0])/1000);
        

        【讨论】:

          【解决方案7】:

          如果你有 ffmpeg,你也应该有 ffprobe。它以一系列 key=value 对的形式向 STDOUT 输出信息,并默认以秒为单位给出持续时间(如果需要 hh:mm:ss,则必须使用 -sexagesimal 选项):

          ffprobe -show_format file.mp4 | grep -F duration | cut -d= -f2
          

          【讨论】:

            【解决方案8】:

            如果您安装了ffmpeg,很可能您也安装了ffprobe

            ffprobe -i file.mp4 -show_format -v quiet | sed -n 's/duration=//p' | xargs printf %.0f
            

            该命令将返回一个整数值。

            输出示例:

            190

            【讨论】:

            • 我还想要一个 hh:mm:ss.ms 格式的输出,但我不得不稍微修改你建议的命令以获得我需要的东西。我将Video 替换为General 以给出命令--Inform="General;%Duration/String3%"。 MediaInfo 版本 0.7.69
            • 您没有将值转换为秒,而是将 ms 部分截断而不是四舍五入。所以你的结果不准确。您可以轻松地删除 Rodrigo 的答案给出的值的最后 3 位数字,并通过 php 和字符串解析省略绕道。
            • @trs 同意。我不喜欢我自己的旧答案,所以我编辑了它。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-10-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-16
            • 2021-10-05
            相关资源
            最近更新 更多