1. 程式人生 > >js實現視訊截圖,視訊批量截圖,canvas實現

js實現視訊截圖,視訊批量截圖,canvas實現

## 擷取視訊的某一時間的影象並儲存 利用canvas的繪畫能力畫出視訊某一幀的視訊畫面, 獲得到影象之後轉換成base64影象, 再利用a標籤的實現自動儲存到本地 * html程式碼 ``` html 去下載 ``` * js程式碼 ``` js // 繫結下載 document.getElementById("btn").onclick = function() { videoCover("視訊地址", null, 400) } /** * @param {String} src 視訊連結 * @param {Number} width 視訊容器播放的寬 * @param {Number} height 視訊容器播放的高 * @param {Number} second 需要截圖視訊的幀數, 單位秒 * @param {Number} bufftime 視訊載入緩衝的時長, 單位秒 */ function videoCover(src, width, height, second, bufftime) { const canvas = document.createElement('canvas'); // 建立canvas 用來截圖 const video = document.createElement('video'); // 建立video 用來存放被截圖的視訊 const img = document.getElementById('img') // 用來顯示截圖的圖片效果 const a = document.getElementById('a') // 用來自動下載圖片儲存到本地 video.setAttribute('crossOrigin', 'anonymous'); // 支援跨域 document.body.appendChild(video); // 把視訊插入頁面裡 video.setAttribute('src', src); // 設定video路徑 video.style.visibility = "hidden" // 視訊不顯示 // 監聽視訊播放 video.onplay = function() { // 暫停 video.pause() // 指定播放時間 1代表視訊的第一秒幀 可以浮點數 video.currentTime = second || 1 // 設定視訊容器的寬高播放 如果設定一項會自動按照比例生成 這裡是高固定,寬自動 video.height = height || video.clientHeight; // 設定canvas的截圖大小,如果沒給定寬高值會取視訊容器的寬高 canvas.width = width || video.clientWidth; canvas.height = height || video.height; /* 使用定時器為了視訊跳轉到某一幀的時候視訊進行緩衝,等視訊載入完成之後進行截圖 如果截圖是黑屏說明視訊未載入完成就開始截圖了 */ setTimeout(() => { // 使用canvas進行繪畫 視訊畫面 canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); // 獲取到base64圖片 png格式 const IMG_TYPE = "png" const b64 = canvas.toDataURL('image/' + IMG_TYPE); // 展示到頁面上給img的src賦值 document.getElementById('img').setAttribute('src', b64); // 設定下載圖片地址 document.getElementById('a').setAttribute('href', b64); // 設定下載圖片的名稱 const filename = "測試圖" + "." + IMG_TYPE document.getElementById('a').setAttribute('download', filename); // 模擬點選自動下載圖片 document.getElementById('a').click() // 移除視訊容器 document.body.removeChild(video); }, bufftime * 1000 || 3000); } // 當視訊準備就緒的時候 video.onloadeddata = () => { // 播放它 video.play() } } ``` 以上程式碼就完成了單個的視訊截圖了. * 如何實現多個視訊批量截圖視訊呢? 使用for迴圈遍歷 呼叫 ``videoCover`` 函式, ``videoCover`` 需要重寫一下. 先規定需要遍歷視訊截圖的內容 ``` json [ { "src":"*******.video", // 視訊下載地址 "currentTime":5, //需要擷取的視訊幀數,第幾秒 "filename":"測試1", // 需要下載到本地的檔名 "filetype":"png" // 下載的圖片型別 }, { "src":"*******.video", // 視訊下載地址 "currentTime":5, //需要擷取的視訊幀數,第幾秒 "filename":"測試1", // 需要下載到本地的檔名 "filetype":"png" // 下載的圖片型別 } ] ``` * 重寫``videoCover`` 函式 > 使用``promise``,``async``,``await`` 遍歷迴圈截圖下載圖片 ```js /** * @param {Object} obj 視訊內容物件 * @param {Number} width 視訊容器播放的寬 * @param {Number} height 視訊容器播放的高 * @param {Number} bufftime 視訊載入緩衝的時長, 單位秒 */ function videoCover(obj, width, height, bufftime) { return new Promise((resolve, reject) => { const canvas = document.createElement('canvas'); // 建立canvas 用來截圖 const video = document.createElement('video'); // 建立video 用來存放被截圖的視訊 const img = document.getElementById('img') // 用來顯示截圖的圖片效果 const a = document.getElementById('a') // 用來自動下載圖片儲存到本地 video.setAttribute('crossOrigin', 'anonymous'); // 支援跨域 document.body.appendChild(video); // 把視訊插入頁面裡 video.setAttribute('src', obj.src); // 設定video路徑 video.style.visibility = "hidden" // 視訊不顯示 // 監聽視訊播放 video.onplay = function () { // 暫停 video.pause() // 指定播放時間 1代表視訊的第一秒幀 可以浮點數 video.currentTime = obj.currentTime || 1 // 設定視訊容器的寬高播放 如果設定一項會自動按照比例生成 這裡是高固定,寬自動 video.height = height || video.clientHeight; // 設定canvas的截圖大小,如果沒給定寬高值會取視訊容器的寬高 canvas.width = width || video.clientWidth; canvas.height = height || video.height; /* 使用定時器為了視訊跳轉到某一幀的時候視訊進行緩衝,等視訊載入完成之後進行截圖 如果截圖是黑屏說明視訊未載入完成就開始截圖了 */ setTimeout(() => { // 使用canvas進行繪畫 視訊畫面 canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); // 獲取到base64圖片 png格式 const b64 = canvas.toDataURL('image/' + obj.filetype); // 移除視訊容器 document.body.removeChild(video); resolve(b64) }, bufftime * 1000 || 3000); } // 當視訊準備就緒的時候 video.onloadeddata = () => { // 播放它 video.play() } }) } ``` * 在寫個迴圈遍歷``videoCover`` 函式 ```js async function start() { const DATA = [{ "src": "http:/****.mp4", // 視訊下載地址 "currentTime": 5, //需要擷取的視訊幀數,第幾秒 "filename": "測試1", // 需要下載到本地的檔名 "filetype": "png" // 下載的圖片型別 }, { "src": "http:/****.mp4", // 視訊下載地址 "currentTime": 2, //需要擷取的視訊幀數,第幾秒 "filename": "測試2", // 需要下載到本地的檔名 "filetype": "png" // 下載的圖片型別 }] const img = document.getElementById('img') // 用來顯示截圖的圖片效果 const a = document.getElementById('a') // 用來自動下載圖片儲存到本地 for (let index = 0; index < DATA.length; index++) { const element = DATA[index]; console.log("開始截圖視訊:" + element.src); const b64 = await videoCover(element, null, 400, 3) // 展示到頁面上給img的src賦值 img.setAttribute('src', b64); // 設定下載圖片地址 a.setAttribute('href', b64); // 設定下載圖片的名稱 const filename = element.filename + "." + element.filetype a.setAttribute('download', filename); // 模擬點選自動下載圖片 a.click() console.log("截圖儲存到本地成功:命名<" + filename + ">"); } console.log("所有視訊截圖下載本地完成!"); } // 繫結下載 document.getElementById("btn").onclick = function () { start() } ``` 然後點選按鈕去截圖,就可以開始批量截圖視訊儲存到本地了. ![多個視訊截圖](https://gitee.com/kong_yiji_and_lavmi/my-image/raw/master/videoCover.png) ### 提示: async/await屬於es7語法,部分低版本瀏覽器暫不支援,需要前往高版本瀏覽