一、需求背景
最近有个视频播放的需求,要求点击视频的预览图弹出模态框播放视频,而预览图要求获取视频的第一帧,作为预览图。
二、视频加载基本介绍
在视频/音频(audio/video)加载过程中,事件的触发顺序如下:
- onloadstart (浏览器开始寻找指定资源)
- ondurationchange (视频/音频 的时长发生变化时触发)
- onloadedmetadata (指定视频/音频 的元数据加载后触发)
- onloadeddata (当前帧的数据加载完成且还没有足够的数据播放)
- onprogress (下载指定的视频/音频 时触发)
- oncanplay (用户可以开始播放视频/音频 时触发)
- oncanplaythrough (可以正常播放且无需停顿和缓冲时触发)
三、方案
通过创建canvas标签,利用其drawImage() 方法在画布上绘制该视频,然后运用toDataURL方法转换canvas上的图片为base64格式。
需要注意的是,由于canvas无法对跨域的图片进行操作,需要提前处理好跨域问题。
核心实现代码如下:
function getVideoBase64(url) { return new Promise(function(resolve, reject) { let dataURL = ''; let video = document.createElement("video"); let output = document.getElementById("output"); video.setAttribute('crossorigin', 'anonymous'); //处理跨域 video.setAttribute('src', url); video.setAttribute('width', 400); video.setAttribute('height', 240); video.setAttribute('controls', 'controls'); video.currentTime = 8; //视频时长,一定要设置,不然大概率白屏 video.addEventListener('loadeddata', function(e) { let canvas = document.createElement("canvas"), width = video.width, //canvas的尺寸和图片一样 height = video.height; canvas.width = width; canvas.height = height; canvas.getContext("2d").drawImage(video, 0, 0, width, height); //绘制canvas dataURL = canvas.toDataURL('image/png'); //转换为base64 let img = document.createElement("img"); img.src = canvas.toDataURL("image/png"); // 获取图片的url output.appendChild(img); resolve(dataURL); }); }) }