這篇文章將為大家詳細(xì)講解有關(guān)javascript實(shí)現(xiàn)截取視頻第一幀的方法,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
在企業(yè)資料的開發(fā)中,除了涉及到視頻上傳之外,還需要使用視頻中的第一幀或者或許幾幀作為視頻封面展示。
因此,JS截取視頻第一幀的難點(diǎn)就此誕生,但是查閱了資料發(fā)現(xiàn),網(wǎng)上提供的資料無(wú)外乎倆種,第一種是 wasm + ffmpeg 配合后端去截取,第二種是JS自行截取。優(yōu)缺點(diǎn)也是顯而易見(jiàn)的,第一種,配合成本比較高,而且不是很靈活;第二種可以滿足一般條件下的使用,但是會(huì)有兼容問(wèn)題(IE再見(jiàn))以及截取黑屏的問(wèn)題。
這種方式優(yōu)缺點(diǎn)也是顯而易見(jiàn)的,配合成本比較高,而且會(huì)造成web內(nèi)存的急劇飆升,但是支持的視頻種類已經(jīng)截取的幀數(shù)是很靈活的;由于涉及到服務(wù)端,具體可以參考 wasm + ffmpeg 截取視頻。
這里前端截取的話就需要了解 video、canvas 標(biāo)簽的兼容性和響應(yīng)事件了。而且對(duì)IE可能不是那么友好。
執(zhí)行結(jié)果
根據(jù)順序,第一個(gè)被觸發(fā)的竟然是 timeupdate 事件,按設(shè)想來(lái)說(shuō),最先執(zhí)行的應(yīng)該是 loadedmetadata,元數(shù)據(jù)加載完畢。關(guān)于這一點(diǎn),在MDN上沒(méi)有明確的說(shuō)明,但是可以推理一下:
當(dāng) currentTime 更新時(shí)會(huì)觸發(fā) timeupdate 事件
結(jié)論:雖然最先觸發(fā),但是此時(shí)視頻文件尚未加載,截取的是 canvas 的無(wú)內(nèi)容本身。注:timeupdate 事件根據(jù)使用的系統(tǒng)不同,每秒觸發(fā)4-66次,且由于觸發(fā)頻率高,單位過(guò)小(毫秒級(jí)別),事件響應(yīng)需要延遲等原因,無(wú)法完全精準(zhǔn)的控制。
loadedmetadata 上文提到,元數(shù)據(jù)加載完畢之后即觸發(fā),但數(shù)據(jù)中并不包括視頻文件本身。結(jié)論:如果視頻文件較大,加載時(shí)間較長(zhǎng),仍然無(wú)法截取到已加載的第一幀。補(bǔ)充:通過(guò) URL.createObjectURL()方法能夠基本做到無(wú)察覺(jué),但并不保險(xiǎn)。
loadeddata 當(dāng)前幀數(shù)(第一幀)加載完畢觸發(fā),沒(méi)毛病。結(jié)論:可用。補(bǔ)充:萬(wàn)一第一幀是黑屏想用下一幀怎么辦,對(duì)不起,余下幀數(shù)加沒(méi)加載完不在它的考慮范圍之類,這個(gè)事件不管。
canplay 視頻能夠開始播放時(shí)觸發(fā),也就是根據(jù)上傳的視頻幀數(shù)決定加載多少幀(24/25/30/60等等)后滿足播放畫面后觸發(fā)。總結(jié):因?yàn)榧虞d相對(duì)于 loadeddata的事件來(lái)說(shuō)更多(多一丟丟),總體可行。補(bǔ)充:通過(guò)控制 currentTime可以滿足(但不可能是第二幀那么準(zhǔn)確),可以看做“當(dāng)前播放幀”。
play 開始播放時(shí)才會(huì)觸發(fā),和上傳快速截取的需求不是很符合。
waiting 已播放但下一畫面沒(méi)緩沖好時(shí)觸發(fā),適合插播小廣告。
上面的的結(jié)果是什么呢?
可以看到已經(jīng)很成功的截取到了視頻的第一幀,那么到此階段,其實(shí)已經(jīng)基本實(shí)現(xiàn)了需求,但是圖片是否是有效的,這個(gè)還未可知,所以需要我們進(jìn)一步去判斷。
其實(shí),截取到的第一幀圖片,有些時(shí)候由于視頻的質(zhì)量不佳或者一些其他因素影響,截取到的圖片往往不是很符合預(yù)期,一直與會(huì)出現(xiàn)純黑的圖片,透明圖片,白色圖片等等無(wú)效圖片。因此,我們需要進(jìn)行一下圖片有效性的識(shí)別。 那么,怎么去識(shí)別圖片的有效性呢?
這時(shí)候,你就需要認(rèn)識(shí)一個(gè)新屬性了:Uint8ClampedArray
Uint8ClampedArray(8位無(wú)符號(hào)整型固定數(shù)組) 類型化數(shù)組表示一個(gè)由值固定在0-255區(qū)間的8位無(wú)符號(hào)整型組成的數(shù)組;如果你指定一個(gè)在 [0,255] 區(qū)間外的值,它將被替換為0或255;如果你指定一個(gè)非整數(shù),那么它將被設(shè)置為最接近它的整數(shù)。(數(shù)組)內(nèi)容被初始化為0。一旦(數(shù)組)被創(chuàng)建,你可以使用對(duì)象的方法引用數(shù)組里的元素,或使用標(biāo)準(zhǔn)的數(shù)組索引語(yǔ)法(即使用方括號(hào)標(biāo)記)。
如果對(duì) Uint8ClampedArray 感興趣,可以異步這里進(jìn)一步研究 Uint8ClampedArray。
你是不是發(fā)現(xiàn)了什么?0~255這個(gè)是不是常見(jiàn)的數(shù)值,顏色的十六進(jìn)制對(duì)應(yīng)的數(shù)值。好,那么,接下來(lái)就是按照我們所思考好的去實(shí)現(xiàn),看看是不是這么一個(gè)原理。
代碼是實(shí)現(xiàn)了,那么結(jié)果呢,我這里分別使用白色圖片,透明圖片,黑色圖片來(lái)對(duì)照一下,拿到的結(jié)果究竟是不是和我們所想象的一直的: 首先我們來(lái)看一下透明圖片:
可以看到,結(jié)果數(shù)組里面,全部是 0;
白色圖片:
哎呦,全是255,那么黑色就應(yīng)該全是0了,別急,讓我們看一下
黑色圖片:
出現(xiàn)了意想不到的數(shù)字,238,這是偏向255白色的色值,為什么會(huì)這樣呢?其實(shí)是因?yàn)榘咨屯该魃珱](méi)有過(guò)度,而黑色是過(guò)度的,就是在canvas繪制的時(shí)候會(huì)出現(xiàn)這種問(wèn)題,但是是可以忽略不計(jì)的。
知道了這三者的色值,那么接下來(lái)的判斷也就好辦了,直接在加一個(gè)條件就好了
為什么是200 和 0 呢?其實(shí)這倆個(gè)值你們可以根據(jù)實(shí)際情況去判斷合理范圍,200 對(duì)應(yīng)的色值是#c8c8c8,是灰色,0是透明色,所以在這里就判斷是無(wú)效圖片了。只要brr數(shù)組里面沒(méi)有值,就說(shuō)明是無(wú)效圖片。
那么實(shí)際情況如何呢?再來(lái)一張實(shí)際的對(duì)比圖:
可以看到,brr里面是有值的,而且還是大量的,所以這正圖片就是有效圖片。
JavaScript截取視頻第一幀就已經(jīng)完畢了,如果還想優(yōu)化就是針對(duì)無(wú)效圖片的時(shí)候,使用默認(rèn)圖片展示即可。
JavaScript截取視頻第一幀,過(guò)程比較繁雜,而且涉及到很大量的數(shù)據(jù)循環(huán),會(huì)造成一定的內(nèi)存增長(zhǎng),但是確確實(shí)實(shí)能解決這個(gè)問(wèn)題,并且已經(jīng)已用到了企業(yè)資料中,其中使用了一個(gè)取巧優(yōu)化的辦法,只有brr數(shù)組有一個(gè)值被push進(jìn)去,就直接break,這樣可以極大的優(yōu)化性能。
關(guān)于javascript實(shí)現(xiàn)截取視頻第一幀的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
分享文章:javascript實(shí)現(xiàn)截取視頻第一幀的方法-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)源:http://vcdvsql.cn/article40/ddgceo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、外貿(mào)網(wǎng)站建設(shè)、建站公司、ChatGPT、做網(wǎng)站、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容