一、需求背景
最近有個視頻播放的需求,要求點擊視頻的預覽圖彈出模態框播放視頻,而預覽圖要求獲取視頻的第一幀,作為預覽圖。
二、視頻加載基本介紹
在視頻/音頻(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); }); }) }