擷取視訊的某一時間的影像並儲存
利用canvas的繪畫能力畫出視訊某一幀的視訊畫面, 獲得到影像之後轉換成base64影像, 再利用a標籤的實現自動儲存到本地
- html程式碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>視訊截圖儲存到本地</title>
</head>
<body>
<div><button id="btn">開始截圖</button></div>
<img id="img">
<a id="a" download="" style="display: none;">去下載</a>
</body>
</html>
- 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
需要重寫一下.
先規定需要遍歷視訊截圖的內容
[
{
"src":"*******.video", // 視訊下載地址
"currentTime":5, //需要擷取的視訊幀數,第幾秒
"filename":"測試1", // 需要下載到本地的檔名
"filetype":"png" // 下載的圖片型別
},
{
"src":"*******.video", // 視訊下載地址
"currentTime":5, //需要擷取的視訊幀數,第幾秒
"filename":"測試1", // 需要下載到本地的檔名
"filetype":"png" // 下載的圖片型別
}
]
- 重寫
videoCover
函式
使用
promise
,async
,await
遍歷迴圈截圖下載圖片
/**
* @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
函式
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()
}
然後點選按鈕去截圖,就可以開始批量截圖視訊儲存到本地了.