客户端纯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
相关产品推荐
相关产品推荐

