【Google Chrome】【Firefox】【Microsoft Edge】再生可能なMP4動画の長さが再生中に変わるパターンの紹介

 ブラウザ上に読み込まれた動画の長さは Video 要素の duration プロパティから読み取ることができます。

HTMLMediaElement.duration – Web API | MDN

 例えば次の様にできます。

const d = document.querySelector('video').duration;
console.log(d);// 動画長を表示

 この動画長ですが、実は動画ファイルよっては再生中に変化することがあります。これは例えば次のデモです。

 動画ファイルが末尾付近に来た際、動画長が伸びました。ブラウザ内部の挙動なのですが、これは恐らく動画内の情報の不一致から起きます。例えばデモの動画について ffprobe で情報を取得すると次になります。

# メタ情報のもろもろについて取得。動画の長さである Duration を見ます。
> ffprobe -hide_banner "demo.mp4"
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'demo.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp41isom
    creation_time   : 2022-04-04T04:12:13.000000Z
    artist          : Microsoft Game DVR
    title           : ffprobe Documentation — Mozilla Firefox
  Duration: 00:00:10.43, start: 0.000000, bitrate: 4514 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 1920x1088 [SAR 1:1 DAR 30:17], 3578 kb/s, 12.66 fps, 59.94 tbr, 30k tbn (default)
    Metadata:
      creation_time   : 2022-04-04T04:12:13.000000Z
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : AVC Coding
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2022-04-04T04:12:13.000000Z
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]

 Duration は 10.43 秒とあります。一方で各フレームについての情報を取得すると最後のフレームの情報は次の様になります。

# 各フレームについての情報を取得
> ffprobe -show_frames  -pretty -print_format json demo.mp4 > demo_frames.txt
# 最後の画像フレームが次です。
        {
            "media_type": "video",
            "stream_index": 0,
            "key_frame": 0,
            "pts": 313845,
            "pts_time": "0:00:10.461500",
            "pkt_dts": 310344,
            "pkt_dts_time": "0:00:10.344800",
            "best_effort_timestamp": 313845,
            "best_effort_timestamp_time": "0:00:10.461500",
            "pkt_duration": 1001,
            "pkt_duration_time": "0:00:00.033367",
            "pkt_pos": "4826418",
            "pkt_size": "3.034180 Kibyte",
            "width": 1920,
            "height": 1088,
            "pix_fmt": "yuv420p",
            "sample_aspect_ratio": "1:1",
            "pict_type": "P",
            "coded_picture_number": 131,
            "display_picture_number": 0,
            "interlaced_frame": 0,
            "top_field_first": 0,
            "repeat_pict": 0,
            "chroma_location": "left"
        },

 これの pts_time と best_eddort_timestamp_time がそれです。pts は Presentation Time-Stamp の略です。

FFmpeg: AVPacket Struct Reference#int64_t AVPacket::pts
FFmpeg: AVFrame Struct Reference#int64_t AVFrame::best_effort_timestamp

 これらはこの時間にこのフレームを表示すべき、という情報でこれが 10.461500 秒です。このため最後の方のフレームを読むとメタ情報の動画の長さと不整合が起きます。恐らくこの不整合を解消するためにブラウザは動画の長さを途中で伸ばすことになったのでしょう。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG