一般播放器用于展示的视频总时长,使用的是 mediainfo中的哪个字段?
在使用 MediaInfo 获取视频信息时,播放器用于展示的“视频总时长” 通常对应以下字段:
✅ 推荐字段:Duration(或 Duration/String)
完整路径(在 MediaInfo 输出中):
- General track(全局轨道)下的
Duration
示例(命令行输出):
mediainfo --Inform="General;Duration: %Duration% ms" video.mp4
# 输出:Duration: 123456 ms
mediainfo --Inform="General;Duration: %Duration/String%" video.mp4
# 输出:Duration: 2 min 3 s
🔍 详细说明
| 字段名 | 类型 | 说明 |
|---|---|---|
Duration |
数值(毫秒) | 视频总时长,单位为 毫秒(ms),适合程序计算 |
Duration/String |
字符串 | 人类可读格式,如 1 h 23 min 45 s 或 00:23:45.123 |
Duration/String1 ~ String5 |
不同格式的字符串 | 如 String3: 00:23:45.123(标准时间码格式) |
📌 播放器应优先使用
General轨道的Duration,而不是 Video 或 Audio 轨道的 Duration,因为:
- 全局 Duration 是容器层面的总时长(最权威);
- 音视频轨道的 Duration 可能因编码差异略有不同(如音频比视频长 1 帧)。
🛠 如何通过 MediaInfo 库获取(编程示例)
Python(使用 pymediainfo):
from pymediainfo import MediaInfo
media_info = MediaInfo.parse("video.mp4")
general_track = media_info.tracks[0] # General track is first
duration_ms = general_track.duration # 单位:毫秒(int)
print(f"总时长: {duration_ms} ms") # e.g., 123456
JavaScript(前端 mediainfo.js):
const result = await mediaInfo.analyzeData(...);
const tracks = JSON.parse(result).media.track;
const general = tracks.find(t => t["@type"] === "General");
const durationMs = parseInt(general.Duration); // 字符串转数字
console.log(`总时长: ${durationMs} 毫秒`);
⚠️ 注意事项
-
单位是毫秒
MediaInfo 的Duration字段默认以 毫秒 为单位(即使原始文件用 PTS 表示),可直接用于播放器进度条计算。 -
避免使用 Video/Audio 轨道的 Duration
❌ Video Duration: 123400 ms ❌ Audio Duration: 123500 ms ✅ General Duration: 123456 ms ← 正确! -
某些损坏文件可能无 Duration
若文件 moov 在尾部(后置 MP4)且未完全下载,MediaInfo 可能无法读取时长 → 返回空或 0。 -
直播流/实时流无 Duration
对于 HLS/DASH 直播或 RTMP 流,Duration通常为0或N/A,因为内容是无限的。
✅ 总结
| 用途 | 推荐 MediaInfo 字段 |
|---|---|
| 播放器显示总时长(程序计算) | General.Duration(单位:毫秒) |
| UI 显示人类可读时长 | General.Duration/String3(格式:HH:MM:SS.mmm) |
💡 最佳实践:
播放器初始化时,优先从 容器(General)层级 读取Duration,若为空再 fallback 到 Video 轨道,并做好异常处理。
若文件 moov 在尾部(后置 MP4),但是是完整视频,可以获取到总时长吗
如果文件是完整的(moov 在尾部但文件已全部下载/存在),MediaInfo、FFmpeg、播放器等工具仍然可以准确获取到视频的总时长。
✅ 核心结论
只要 MP4 文件完整(即使 moov 在尾部),就能 100% 获取总时长。
因为 moov 原子中包含了所有元数据,包括:
- 视频/音频轨道的时长(
duration) - 时间刻度(
timescale) - 帧数、码率、关键帧位置等
只要程序能读到文件末尾的 moov,就能解析出正确时长。
🔍 技术原理
MP4 文件结构简述:
[ftyp] → [mdat](媒体数据) → [moov](元数据)
- moov 包含:
movie duration = sum of track durations track duration = (last DTS - first DTS) × timescale - 即使
moov在尾部,只要文件完整,解析器会:- 从文件末尾向前扫描(或直接 seek 到末尾)
- 找到
moov原子 - 解析其中的
mvhd.duration和tkhd.duration
📌 注意:这个过程需要读取文件末尾,所以:
- 如果文件未完全下载(如只下了一半),则无法获取时长;
- 如果文件已完整存储在本地或服务器上,则毫无问题。
🧪 实验验证
1. 用 MediaInfo 测试后置 MP4
# 生成一个 moov 在尾部的 MP4(默认行为)
ffmpeg -i input.mp4 -c copy output_back_moov.mp4
# 查看时长
mediainfo --Inform="General;Duration: %Duration% ms" output_back_moov.mp4
# ✅ 正常输出:Duration: 123456 ms
2. 用 FFprobe 验证
ffprobe -v quiet -show_entries format=duration -of csv=p=0 output_back_moov.mp4
# ✅ 输出:123.456(秒)
3. 用浏览器 <video> 加载
<video src="output_back_moov.mp4" controls></video>
- 虽然首帧加载慢(需先读完文件才能解析 moov),
- 但一旦加载完成,进度条和总时长显示完全正常。
⚠️ 唯一限制:文件必须完整
| 场景 | 能否获取时长? | 原因 |
|---|---|---|
| 本地完整 MP4(moov 在尾) | ✅ 能 | 可读取整个文件 |
| 云存储完整文件(HTTPS URL) | ✅ 能 | HTTP 支持 Range 请求,工具会自动 fetch 末尾 |
| 仅下载了前 10MB 的 MP4 | ❌ 不能 | moov 在尾部,未下载到 |
| 流式传输中(直播录制) | ❌ 不能 | 文件未结束,moov 尚未写入 |
💡 提示:
即使 moov 在尾部,HTTP 服务器支持 Range 请求(如 AWS S3、阿里云 OSS),MediaInfo 或 FFprobe 会自动发起Range: bytes=-65536请求读取文件末尾,从而快速定位 moov 并解析时长——无需下载整个文件!
✅ 总结
| 问题 | 答案 |
|---|---|
| 后置 MP4(moov 在尾)能否获取总时长? | ✅ 能,只要文件完整 |
| 是否需要转换为前置 MP4 才能读时长? | ❌ 不需要 |
| 什么情况下读不到时长? | 文件不完整 / 网络中断 / 服务器不支持 Range 请求 |
📌 最佳实践:
- 对于点播视频,即使 moov 在尾部,只要文件完整,所有工具都能正确读取时长;
- 但为了提升首屏加载速度(用户体验),仍建议用
ffmpeg -movflags +faststart转为前置 MP4。- 时长解析 ≠ 快速播放:前者只需读 moov(可在尾部),后者要求 moov 在头部。

浙公网安备 33010602011771号