ブラウザ上に読み込まれた動画の長さは 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 秒です。このため最後の方のフレームを読むとメタ情報の動画の長さと不整合が起きます。恐らくこの不整合を解消するためにブラウザは動画の長さを途中で伸ばすことになったのでしょう。
