H5 video標籤列表渲染用canvas擷取視訊畫面做封面
這是一個關於h5的video視訊播放標籤來做視訊播放擷取視訊畫面的問題。
需求是這樣的:要渲染一個視訊資源列表,在列表中獲取視訊的畫面來做列表的封面。看到這個需求就想,為什麼要在列表裡擷取視訊畫面做封面,為什麼不是後端返回圖片url呢?沒有那麼多為什麼,做出來就是了。
首先是找百度,怎麼擷取h5視訊的畫面,搜了一遍,大都是通過canvas來畫出來的。基本實現過程是:通過video標籤把視訊載入進來,設定display:none; 把video標籤隱藏起來,然後通過canvas的drawImage方法把視訊畫面畫出來,得到一個base6位的圖片編碼,然後將這個base64位的編碼賦給img標籤的src即可。
先來一串程式碼:
html:
<video id="video" :src="videoSrc" x-webkit-airplay="allow" preload="auto" style="display: none"></video>
<div id="output"></div>
js:
captureImage() {
const output = document.getElementById('output')
const video = document.getElementById('video')
const canvas = document.createElement('canvas')
canvas.width = video.videoWidth * 0.3
canvas.height = video.videoHeight * 0.3
const img = new Image()
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height)
const dataUrl = canvas.toDataURL('image/png')
img.src = dataUrl
output.appendChild(img)
},
這是擷取一個視訊畫面的實現程式碼,可以監聽視訊載入好了之後執行captureImage() 方法(我這裡是基於vue的寫法,應該比較好理解)。那接下來進入主題,渲染視訊列表,如何去畫每個視訊的畫面呢?這裡我寫了個公共的方法:
html:
<li v-for="(item, index) in items" :key="index">
<div class="video-cover">
<video :id="item.id" :src="item.src" x-webkit-airplay="allow" preload="auto" style="display: none"></video>
{{captureImage(item.id, index, 'items')}}
<img :src="item.cover">
</div>
</li>
js:
// videoId: 視訊標籤的id; index: 列表資料的索引;key: this.$data讀取列表資料的key
captureImage(videoId, index, key) {
const self = this
setTimeout(function () {
const videoEle = document.getElementById(videoId)
const canvas = document.createElement('canvas')
canvas.width = 265
canvas.height = 180
canvas.getContext('2d').drawImage(videoEle, 0, 0, canvas.width, canvas.height)
const dataUrl = canvas.toDataURL('image/png')
self.$set(self.$data[key][index], 'cover', dataUrl)
}, 100)
}
這是基於vue的寫法,首先寫一個擷取視訊畫面的公共方法,在進行列表渲染時,每渲染一個item,呼叫一次該方法(也可以在updated鉤子裡迴圈呼叫),傳入對應的視訊標籤的id以便獲取dom節點。這裡加了延時器,一開始沒加的時候,發現獲取到的videoEle是null,可能是該方法執行的時候,video標籤還沒渲染好,給個小小的延時就可以了(不知有沒有更好的解決方法,就先這樣做著了,如果路過的大神有更好的解決方案,還望賜教)。
以上的做法可以在列表裡渲染出視訊畫面做封面了,高興了一小會。後來發現,有bug!!!由於瀏覽器載入視訊速度的問題,導致列表中有些封面畫出來是一張透明的圖片,甚至有時候全部都是透明的圖片,可能是畫的時候,視訊畫面還沒載入。後來試了好多方法,最終做了小小的優化:
html:
<li v-for="(item, index) in items" :key="index">
<div class="video-cover">
<video :id="item.id" :src="item.src" x-webkit-airplay="allow" autoplay preload="auto" style="display: none"></video>
{{captureImage(item.id, index, 'items')}}
<img :src="item.cover">
</div>
</li>
js:
// videoId: 視訊標籤的id; index: 列表資料的索引;key: this.$data讀取列表資料的key
captureImage(videoId, index, key) {
const self = this
setTimeout(function () {
const videoEle = document.getElementById(videoId)
const canvas = document.createElement('canvas')
canvas.width = 265
canvas.height = 180
videoEle.addEventListener('timeupdate', function () {
canvas.getContext('2d').drawImage(videoEle, 0, 0, canvas.width, canvas.height)
const dataUrl = canvas.toDataURL('image/png')
self.$set(self.$data[key][index], 'cover', dataUrl)
videoEle.pause()
}, false)
}, 100)
}
這裡做了小小的改變,就是在渲染視訊列表是讓ta自動播放(autoplay),然後在畫封面的方法裡通過video的timeupdate事件來監聽視訊播放位置的改變,然後在進行canvas的繪製,繪製完呼叫video的pause()方法,暫停播放,這樣就能保障每個item都能畫出不是透明的圖片啦。
The end:可算是把視訊列表的封面都畫出來了,美中不足的是,視訊載入的速度還是沒法控制,列表中有些視訊載入的慢的,會延時好幾秒才畫出來。
以上就是H5 video標籤列表渲染用canvas擷取視訊畫面做封面的一個不完美的方法,如果路過的親有更好的解決方法,望分享,麼麼噠。
相關文章
- 使用JavaCV實現讀取視訊資訊及自動擷取封面圖Java
- 使用javacv 獲取視訊第一幀 做封面Java
- video標籤製作簡易版彈幕視訊IDE
- 視訊直播:Windows中各類畫面源的擷取和合成方法總結Windows
- 怎麼用Word做資料夾側面標籤?Word做資料夾側面標籤教程
- php ffmpeg 視訊擷取PHP
- js擷取影片的封面圖片JS
- 獲取網路視訊任意幀畫面
- vue 擷取視訊第一幀Vue
- HTML <canvas> 標籤HTMLCanvas
- H5的video標籤中遇到無效源解決H5IDE
- CSS和canvas標籤設定畫布尺寸區別CSSCanvas
- html列表標籤HTML
- PH 如何實現調取展示實時視訊畫面?
- 短視訊平臺搭建,指定視訊中的某一幀做為視訊的封面
- 如何在視訊中擷取到高清的畫面並轉換為圖片的格式
- CSS之列表標籤CSS
- 用MediaCodec實現多段視音訊的擷取與拼接音訊
- c:forTokens標籤delims擷取字元字元
- ## H5 canvas畫圖白板踩坑H5Canvas
- 帝國CMS靈動標籤顯示標題屬性、擷取標題字數
- wasm + ffmpeg實現前端擷取視訊幀功能ASM前端
- canvas畫素點操作 —— 視訊綠幕摳圖Canvas
- H5新增標籤元素H5
- HTML5 標籤列表HTML
- 移動終端H5頁面meta標籤的設定H5
- 用面對物件方式定tab標籤物件
- 自動分類打標籤!飛槳TSM模型幫你做視訊理解模型
- iOS開發中擷取相機部分畫面,切割sampleBuffer(Crop sample buffer)iOS
- canvas標籤簡單介紹Canvas
- canvas標籤clock(時鐘)案例Canvas
- HTML5的canvas標籤HTMLCanvas
- 音訊擷取分割工具音訊
- web實戰:video結合canvas實現視訊線上截圖WebIDECanvas
- 易優Channel獲取欄目列表-Eyoucms標籤手冊
- PbootCMS可使用的列表標籤內容tags標籤呼叫boot
- 愛奇藝短視訊打標籤技術解析
- 愛奇藝短視訊智慧標籤生成實踐