js實現視訊截圖,視訊批量截圖,canvas實現
阿新 • • 發佈:2020-12-05
## 擷取視訊的某一時間的影象並儲存
利用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語法,部分低版本瀏覽器暫不支援,需要前往高版本瀏覽