You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript获取HTML Video的帧率?现有方案存精度问题

解决视频元素帧率获取的精度问题

方案1:直接读取视频轨道的元数据帧率

这是精度最高的方式,直接获取视频文件本身的帧率属性,无需依赖帧时间计算。需要等待视频元数据加载完成后读取:

const video = document.querySelector('video');

// 监听元数据加载完成事件
video.addEventListener('loadedmetadata', () => {
  const videoTrack = video.videoTracks[0];
  if (videoTrack) {
    const trackSettings = videoTrack.getSettings();
    // frameRate 为精确浮点数,支持 29.97、59.94 这类非整数帧率
    const preciseFps = trackSettings.frameRate;
    console.log('视频原始帧率:', preciseFps);
    // 按需取整
    const roundedFps = Math.round(preciseFps);
  }
});

注意事项:

  • 需确保视频已设置有效src并开始加载,才会触发loadedmetadata事件
  • 对于内嵌第三方视频(如YouTube),需确认视频元素已完成元数据加载

方案2:改进requestVideoFrameCallback的多帧平均计算

若需获取视频实际渲染帧率(而非原始帧率),可通过累积多帧时间差的方式,抵消单帧mediaTime的精度误差:

const video = document.querySelector('video');
let frameCount = 0;
let lastMediaTime = null;
// 取10帧计算平均,可根据需求调整样本量
const sampleFrameCount = 10;

function calculateFps(timestamp, metadata) {
  const currentMediaTime = metadata.mediaTime;
  
  if (lastMediaTime === null) {
    lastMediaTime = currentMediaTime;
  } else {
    frameCount++;
    
    // 累积到指定帧数后计算平均帧率
    if (frameCount >= sampleFrameCount) {
      const totalMediaElapsed = currentMediaTime - lastMediaTime;
      const avgFrameDuration = totalMediaElapsed / frameCount;
      const preciseFps = 1 / avgFrameDuration;
      console.log('实际渲染帧率(多帧平均):', preciseFps);
      
      // 重置计数,持续监测
      frameCount = 0;
      lastMediaTime = currentMediaTime;
    }
  }
  
  video.requestVideoFrameCallback(calculateFps);
}

video.requestVideoFrameCallback(calculateFps);

优势:

  • 通过多帧平均消除单帧mediaTime的精度偏差
  • 能反映浏览器实际渲染视频的帧率(如性能限制导致的降帧、倍速播放场景)

方案3:结合performance.now()计算真实渲染帧率

如果mediaTime的精度始终无法满足需求,可使用浏览器高精度时间戳performance.now()计算帧间隔:

const video = document.querySelector('video');
let lastPerformanceTime = null;
let frameCount = 0;
const sampleFrameCount = 15;

function calculateRealFps(timestamp, metadata) {
  const currentTime = performance.now();
  
  if (lastPerformanceTime !== null) {
    frameCount++;
    if (frameCount >= sampleFrameCount) {
      const totalElapsed = currentTime - lastPerformanceTime;
      const avgFrameDuration = totalElapsed / frameCount;
      const realFps = 1000 / avgFrameDuration; // 转换为每秒帧数
      console.log('真实渲染帧率:', realFps);
      
      frameCount = 0;
      lastPerformanceTime = currentTime;
    }
  } else {
    lastPerformanceTime = currentTime;
  }
  
  video.requestVideoFrameCallback(calculateRealFps);
}

video.requestVideoFrameCallback(calculateRealFps);

注意:

  • 该方法计算的是浏览器渲染视频帧的实际帧率,可能与视频原始帧率存在差异(如倍速播放、浏览器降帧)

总结

  • 若需视频原始文件帧率,优先选择方案1(读取视频轨道元数据),精度最高
  • 若需实际播放的渲染帧率,选择方案2或3,通过多帧平均减少精度误差

内容的提问来源于stack exchange,提问作者derder56

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:54:29