中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript實現截取視頻第一幀的方法

發布時間:2020-09-14 09:44:23 來源:億速云 閱讀:976 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關javascript實現截取視頻第一幀的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

JavaScript截取視頻第一幀

一、背景

在企業資料的開發中,除了涉及到視頻上傳之外,還需要使用視頻中的第一幀或者或許幾幀作為視頻封面展示。

產生的問題:

因此,JS截取視頻第一幀的難點就此誕生,但是查閱了資料發現,網上提供的資料無外乎倆種,第一種是 wasm + ffmpeg 配合后端去截取,第二種是JS自行截取。優缺點也是顯而易見的,第一種,配合成本比較高,而且不是很靈活;第二種可以滿足一般條件下的使用,但是會有兼容問題(IE再見)以及截取黑屏的問題。

二、wasm + ffmpeg

這種方式優缺點也是顯而易見的,配合成本比較高,而且會造成web內存的急劇飆升,但是支持的視頻種類已經截取的幀數是很靈活的;由于涉及到服務端,具體可以參考 wasm + ffmpeg 截取視頻。

三、JavaScript 前端截取

這里前端截取的話就需要了解 video、canvas 標簽的兼容性和響應事件了。而且對IE可能不是那么友好。

1. canvas的知識這里不做過多補充,下面主要看一下video標簽的響應事件有哪些:

執行結果

根據順序,第一個被觸發的竟然是 timeupdate 事件,按設想來說,最先執行的應該是 loadedmetadata,元數據加載完畢。關于這一點,在MDN上沒有明確的說明,但是可以推理一下:

currentTime 更新時會觸發 timeupdate 事件

結論:雖然最先觸發,但是此時視頻文件尚未加載,截取的是 canvas 的無內容本身。注:timeupdate 事件根據使用的系統不同,每秒觸發4-66次,且由于觸發頻率高,單位過小(毫秒級別),事件響應需要延遲等原因,無法完全精準的控制。

  • loadedmetadata 上文提到,元數據加載完畢之后即觸發,但數據中并不包括視頻文件本身。結論:如果視頻文件較大,加載時間較長,仍然無法截取到已加載的第一幀。補充:通過 URL.createObjectURL()方法能夠基本做到無察覺,但并不保險。

  • loadeddata 當前幀數(第一幀)加載完畢觸發,沒毛病。結論:可用。補充:萬一第一幀是黑屏想用下一幀怎么辦,對不起,余下幀數加沒加載完不在它的考慮范圍之類,這個事件不管。

  • canplay 視頻能夠開始播放時觸發,也就是根據上傳的視頻幀數決定加載多少幀(24/25/30/60等等)后滿足播放畫面后觸發。總結:因為加載相對于 loadeddata的事件來說更多(多一丟丟),總體可行。補充:通過控制 currentTime可以滿足(但不可能是第二幀那么準確),可以看做“當前播放幀”。

  • play 開始播放時才會觸發,和上傳快速截取的需求不是很符合。

  • waiting 已播放但下一畫面沒緩沖好時觸發,適合插播小廣告。

2. 了解上面的響應事件之后,讓我們來看一下接下來截取操作:

上面的的結果是什么呢?

可以看到已經很成功的截取到了視頻的第一幀,那么到此階段,其實已經基本實現了需求,但是圖片是否是有效的,這個還未可知,所以需要我們進一步去判斷。

3. 第一幀是否有效

其實,截取到的第一幀圖片,有些時候由于視頻的質量不佳或者一些其他因素影響,截取到的圖片往往不是很符合預期,一直與會出現純黑的圖片,透明圖片,白色圖片等等無效圖片。因此,我們需要進行一下圖片有效性的識別。 那么,怎么去識別圖片的有效性呢?

這時候,你就需要認識一個新屬性了:Uint8ClampedArray

Uint8ClampedArray(8位無符號整型固定數組) 類型化數組表示一個由值固定在0-255區間的8位無符號整型組成的數組;如果你指定一個在 [0,255] 區間外的值,它將被替換為0或255;如果你指定一個非整數,那么它將被設置為最接近它的整數。(數組)內容被初始化為0。一旦(數組)被創建,你可以使用對象的方法引用數組里的元素,或使用標準的數組索引語法(即使用方括號標記)。

如果對 Uint8ClampedArray 感興趣,可以異步這里進一步研究 Uint8ClampedArray。

你是不是發現了什么?0~255這個是不是常見的數值,顏色的十六進制對應的數值。好,那么,接下來就是按照我們所思考好的去實現,看看是不是這么一個原理。javascript實現截取視頻第一幀的方法

代碼是實現了,那么結果呢,我這里分別使用白色圖片,透明圖片,黑色圖片來對照一下,拿到的結果究竟是不是和我們所想象的一直的: 首先我們來看一下透明圖片:

可以看到,結果數組里面,全部是 0;

白色圖片:

哎呦,全是255,那么黑色就應該全是0了,別急,讓我們看一下

黑色圖片:

出現了意想不到的數字,238,這是偏向255白色的色值,為什么會這樣呢?其實是因為白色和透明色沒有過度,而黑色是過度的,就是在canvas繪制的時候會出現這種問題,但是是可以忽略不計的。

知道了這三者的色值,那么接下來的判斷也就好辦了,直接在加一個條件就好了

為什么是200 和 0 呢?其實這倆個值你們可以根據實際情況去判斷合理范圍,200 對應的色值是#c8c8c8,是灰色,0是透明色,所以在這里就判斷是無效圖片了。只要brr數組里面沒有值,就說明是無效圖片。

那么實際情況如何呢?再來一張實際的對比圖:

可以看到,brr里面是有值的,而且還是大量的,所以這正圖片就是有效圖片。

4. 最后

JavaScript截取視頻第一幀就已經完畢了,如果還想優化就是針對無效圖片的時候,使用默認圖片展示即可。

四、總結

JavaScript截取視頻第一幀,過程比較繁雜,而且涉及到很大量的數據循環,會造成一定的內存增長,但是確確實實能解決這個問題,并且已經已用到了企業資料中,其中使用了一個取巧優化的辦法,只有brr數組有一個值被push進去,就直接break,這樣可以極大的優化性能。

關于javascript實現截取視頻第一幀的方法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汝州市| 广元市| 策勒县| 喜德县| 桐城市| 定州市| 永泰县| 桂林市| 手机| 望奎县| 博罗县| 龙江县| 阜阳市| 安丘市| 武川县| 临汾市| 运城市| 临安市| 思南县| 始兴县| 铅山县| 朝阳区| 永济市| 宁明县| 上杭县| 长子县| 洛隆县| 绍兴县| 上思县| 女性| 安远县| 华池县| 敖汉旗| 京山县| 酒泉市| 满洲里市| 瑞丽市| 安阳县| 丹凤县| 乐安县| 上高县|