信息发布→ 登录 注册 退出

HTML5怎么获取视频时长_HTML5获取视频总时长信息的代码【方法】

发布时间:2026-01-03

点击量:
video.duration 返回 NaN 是因元数据未加载完成,须监听 loadedmetadata 事件并在 isFinite(video.duration) 为真时读取;动态设 src 需重新绑定事件;React 中需用 useRef 和 useEffect 正确管理生命周期。

video 元素的 duration 属性返回 NaN?

直接读取 video.duration 很可能得到 NaN,因为视频元数据(包括时长)默认是懒加载的,元素创建后、甚至 loadedmetadata 事件触发前都不可靠。必须等元数据加载完成才能安全读取。

常见错误写法:

const video = document.getElementById('myVideo');
console.log(video.duration); // 大概率 NaN

  • 确保视频资源已设置 src 或通过 source 子元素指定
  • 监听 loadedmetadata 事件,而不是 loadcanplay —— 后者可能在元数据就绪前就触发
  • 如果视频是动态设置 src,需在赋值后重新监听事件(旧监听器不会自动复用)

正确获取总时长的最小可靠代码(原生 JS)

以下代码在大多数现代浏览器中稳定可用,兼容 MP4、WebM 等主流格式:

const video = document.getElementById('myVideo');

video.addEventListener('loadedmetadata', () => {
  if (isFinite(video.duration)) {
    console.log('视频总时长(秒):', video.duration);
  } else {
    console.warn('无法获取时长:可能是流媒体、无音频轨或服务器未返回 Content-Length');
  }
});

// 若 src 是后续设置的,记得重新绑定
// video.src = 'video.mp4'; // 此行之后事件监听依然有效
  • isFinite()typeof duration === 'number' 更稳妥,能同时排除 NaNInfinity
  • 某些 HLS 或 DASH 流媒体(如 .m3u8)即使加载成功,duration 也可能为 Infinity(|直播|场景)或 NaN(服务端未提供准确时长)
  • 部分无音轨纯视频文件(尤其编码异常的 AVI/FLV 转换件)可能导致浏览器无法解析时长

React 中用 useEffect 获取 video 时长要注意什么?

在函数组件中,容易忽略 DOM 元素是否已挂载、事件是否被重复绑定或漏卸载:

import { useRef, useEffect } from 'react';

function VideoPlayer() {
  const videoRef = useRef(null);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    const handleLoadedMetadata = () => {
      if (isFinite(video.duration)) {
        console.log('React 中获取到时长:', video.duration);
      }
    };

    video.addEventListener('loadedmetadata', handleLoadedMetadata);

    // 清理:防止组件卸载后事件回调执行
    return () => {
      video.removeEventListener('loadedmetadata', handleLoadedMetadata);
    };
  }, []);

  return 
  • 不要在 useEffect 依赖数组里写 videoRef —— 它是 mutable 对象,每次渲染都相同,加了也没用
  • 避免在 useEffect 内部直接调用 video.load(),除非你明确需要重载;多数情况设好 src 就够了
  • SSR 环境下 videoRef.current 初始为 null,必须判空

为什么有时 duration 值不精确?

HTML5 视频时长不是“绝对真实值”,它取决于浏览器如何解析容器头信息和编解码器报告:

  • MP4 文件若未做 moov 原子前置(即“fast start”优化),Chrome 可能先加载大量数据才拿到时长,导致延迟或失败
  • 某些 WebM 文件因 VP9 编码帧时间戳不连续,Firefox 可能返回略短于实际播放时长的 duration
  • 服务端启用范围请求(Accept-Ranges: bytes)但响应头缺失 Content-RangeContent-Length,也会影响元数据加载
  • ffmpeg 修复: ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4

真正需要高精度时长(比如逐帧同步),不能只信 duration,得结合 video.seekablevideo.buffered 或后端返回的 JSON 元数据。

标签:# 为什么  # copy  # Length  # mutable  # NULL  # dash  # chrome  # firefox  # 视频时长  # red  # react  # 后端  # 懒加载  # 浏览器  # 编码  # html5  # json  # js  # html  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!