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

客户端纯JS生成视频多缩略图问题:Canvas无法绘制图像求解决方案

客户端生成视频缩略图无法绘制到Canvas的解决方案

问题原因

设置video.currentTime后,视频跳转到指定帧是异步操作,直接调用drawImage时视频尚未完成帧加载,导致Canvas绘制内容为空。

修正后的代码

JavaScript部分

const fileInput = document.querySelector('#input-video-file');
const video = document.getElementById('video');

fileInput.addEventListener('change', async (e) => {
  video.src = URL.createObjectURL(e.target.files[0]);
  await new Promise(resolve => video.onloadedmetadata = resolve);
  
  const duration = video.duration;
  const sampleCount = 10; // 生成10张缩略图
  const sampleDuration = duration / sampleCount;

  // 逐个生成缩略图,避免同时seek导致冲突
  for (let i = 0; i < sampleCount; i++) {
    const thumbTime = i * sampleDuration;
    await genThumb(thumbTime);
  }
});

function genThumb(thumbTime) {
  return new Promise((resolve) => {
    // 监听视频seek完成事件
    const onSeeked = () => {
      video.removeEventListener('seeked', onSeeked);
      
      const canvas = document.createElement("canvas");
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      canvas.id = `thumb-${thumbTime.toFixed(2)}`; // 用固定格式避免ID问题
      
      const ctx = canvas.getContext('2d');
      ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
      
      document.body.appendChild(canvas);
      resolve();
    };

    video.addEventListener('seeked', onSeeked);
    video.currentTime = thumbTime;
  });
}

HTML部分

<div id="app">
  <input id="input-video-file" type="file" accepts="video/mp4">
  <video id="video" controls></video>
</div>

关键修改点

  • 用Promise包装seeked事件,确保视频跳转到指定帧后再执行绘制
  • 异步逐个生成缩略图,避免同时设置多个currentTime导致的帧加载冲突
  • 修正Canvas的ID命名,避免浮点数带来的ID格式问题
  • 使用await等待视频元数据加载完成,确保duration和视频宽高属性有效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:20:54