原生JS實現(xiàn)視頻截圖功能的示例代碼
視頻截圖效果預覽
利用Canvas進行截圖
要用原生js實現(xiàn)視頻截圖,可以利用canvas
的繪圖功能 ctx.drawImage
,只需要獲取到視頻標簽,就可以通過drawImage
把視頻當前幀圖像繪制在canvas畫布上。
const video = document.querySelector('video') const canvas = document.createElement('canvas') const w = video.videoWidth const h = video.videoHeight canvas.width = w canvas.height = h const ctx = canvas.getContext('2d') ctx.drawImage(video, 0, 0, w, h)
接下來,需要把畫布轉化為圖片,canvas提供了兩個2D轉換為圖片的方法:canvas.toDataURL()
和canvas.toBlob()
canvas.toDataURL(mimeType, qualityArgument)方法
toDataURL可以把圖片轉換成base64格式的圖片,是一個同步方法,使用很簡單,在上面已經繪制好畫布的基礎上,只需要下面一行代碼就可以獲取到當前視頻幀的截圖了
const imageUrl = canvas.toDataURL("image/png") console.log(imageUrl)
可以看到,它最終生成了一個很長字符串的base64圖片地址。
canvas.toBlob(callback, mimeType, qualityArgument)方法
這個方法相比上一個方法的優(yōu)點是它是異步的,所以有一個callback回調,這個callback回調方法默認的第一個參數(shù)就是轉換好的blob文件信息,本文也想重點介紹這種方法的使用。
先說明一下這個方法的三個參數(shù):
參數(shù) | 類型 | 是否必傳 | 說明 |
---|---|---|---|
callback | Function | 是 | toBlob()方法執(zhí)行成功后的回調方法,支持一個參數(shù),表示當前轉換的Blob對象 |
mimeType | String | 否 | 表示需要轉換的圖像的mimeType類型。默認值是image/png,還可以是image/jpeg,甚至image/webp(前提瀏覽器支持)等 |
qualityArgument | Number | 否 | 表示轉換的圖片質量。范圍是0到1。由于Canvas的toBlob()方法轉PNG是無損的,因此,此參數(shù)默認是沒有效的,除非,指定圖片mimeType是image/jpeg或者image/webp,此時默認壓縮值是0.92 |
使用寫法如下:
canvas.toBlob((blob) => { console.log(blob) }, 'image/png', 0.92)
可以看到方法執(zhí)行得到的是當前轉換的Blob對象
那么剩下的就是要將此Blob對象進一步轉化為可供img
顯示的圖片地址。
將Blob對象轉化為圖片地址
下面介紹三種方法進行轉化:
方式一: 通過URL.createObjectURL()方法將Blob轉化為URL
canvas.toBlob((blob) => { const imageUrl = URL.createObjectURL(blob) console.log(1, imageUrl) }, 'image/jpeg', 1)
如下圖所示,轉化得到的是一個bold流的圖片地址。
方式二: 通過FileReader將Blob轉化為DataURL
canvas.toBlob((blob) => { const reader = new FileReader() reader.readAsDataURL(blob) reader.onload = () => { const imageUrl = reader.result console.log(2, imageUrl) } }, 'image/webp', 1)
如下圖所示,轉化得到的是一個base64的圖片地址。
方式三: 通過ajax將Blob上傳到服務器
canvas.toBlob((blob) => { const formData = new FormData() formData.append('file', blob) // 這里的'file'是接口接收參數(shù)的字段名,需要根據(jù)實際情況改變 const xhr = new XMLHttpRequest() xhr.onload = () => { const imageUrl = JSON.parse(xhr.responseText).data // 接口回調參數(shù),需要根據(jù)實際情況處理 console.log(3, imageUrl) } xhr.open('POST', '/api/upload', true) // '/api/upload'是上傳接口,需要根據(jù)實際情況改變 xhr.send(formData) }, 'image/webp', 1)
由此就會將圖片上傳到你的文件服務器里,最終可以得到一個你自己文件服務器下對應的圖片地址。
toBlob()方法的兼容
首先,toBlob()方法IE9瀏覽器不支持,因為Blob數(shù)據(jù)格式IE10+才支持。
然后,對于IE瀏覽器,toBlob()的兼容性有些奇怪,IE10瀏覽器支持ms私有前綴的toBlob()方法,完整方法名稱是msToBlob()。而IE11+,toBlob()方法卻不支持。
但是,我們可以基于toDataURL()方法進行polyfill,性能相對會差一些,JavaScript代碼如下:
if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value: function (callback, type, quality) { var canvas = this setTimeout(function() { var binStr = atob( canvas.toDataURL(type, quality).split(',')[1] ) var len = binStr.length var arr = new Uint8Array(len) for (var i = 0; i < len; i++) { arr[i] = binStr.charCodeAt(i) } callback(new Blob([arr], { type: type || 'image/png' })) }) } }) }
注意事項
使用外部鏈接播放視頻的話需要在視頻標簽上設置允許跨域的處理,添加屬性crossOrigin='anonymous'
即可,
<video className="videoTag" crossOrigin='anonymous' controls> <source src="https://www.w3school.com.cn/example/html5/mov_bbb.mp4" type='video/mp4' /> </video> <video className="videoTag" crossOrigin='anonymous' controls> <source src="https://www.w3school.com.cn/example/html5/mov_bbb.mp4" type='video/mp4' /> </video>
或者,在js里處理
const video = document.querySelector(".videoTag") video.setAttribute('crossOrigin', 'anonymous') video.load()
否則會報以下錯誤:
完整封裝示例
最后,給出一個利用toBlob
進行視頻截圖,最終獲取base64圖片地址
的封裝方法,代碼示例如下:
function getBase64ByVideo(video) { const canvas = document.createElement("canvas") const w = video.videoWidth const h = video.videoHeight canvas.width = w canvas.height = h return new Promise((resolve, reject) => { // 由于toBlob方法是異步的,所以這里用Promise const ctx = canvas.getContext('2d') ctx.drawImage(video, 0, 0, w, h) canvas.toBlob((blob) => { // 通過FileReader將Blob轉化為DataURL const reader = new FileReader() reader.readAsDataURL(blob) reader.onload = () => { const imageUrl = reader.result resolve(imageUrl) } }, 'image/webp', 1) // 根據(jù)需要可以自行配置這里的兩個參數(shù) }) }
調用方法:
const videoTag = document.querySelector(".videoTag") const dataUrl = await getBase64ByVideo(videoTag)
以上就是原生JS實現(xiàn)視頻截圖功能的示例代碼的詳細內容,更多關于JS視頻截圖的資料請關注腳本之家其它相關文章!
相關文章
深入解析JavaScript中函數(shù)的Currying柯里化
這篇文章主要介紹了JavaScript中函數(shù)的Currying柯里化,Currying 的重要意義在于可以把函數(shù)完全變成"接受一個參數(shù)、返回一個值"的固定形式,需要的朋友可以參考下2016-03-03JavaScript實現(xiàn)在頁面刷新時成功發(fā)送停止請求
最近接到一個需求,需要在頁面刷新或者關閉瀏覽器標簽頁的時候觸發(fā)停止當前sql的接口,所以本文小編給大家詳細介紹了解決方案和實現(xiàn)代碼,需要的朋友可以參考下2023-11-11JS實現(xiàn)不使用圖片仿Windows右鍵菜單效果代碼
這篇文章主要介紹了JS實現(xiàn)不使用圖片仿Windows右鍵菜單效果代碼,涉及文鼎字及css樣式的使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10微信小程序定義和調用全局變量globalData的實現(xiàn)
這篇文章主要介紹了微信小程序定義和調用全局變量globalData的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11