瀏覽器視頻幀操作方法?requestVideoFrameCallback()
前言
近期發(fā)現(xiàn)一個(gè)很酷的應(yīng)用場(chǎng)景,對(duì)著攝像頭做動(dòng)作,然后分析器動(dòng)畫(huà)渲染到 3D 模型上,在了解其實(shí)現(xiàn)原理后,對(duì)一些技術(shù)點(diǎn)做一些學(xué)習(xí)筆記。 requestVideoFrameCallback()
就是其中的技術(shù)點(diǎn),使用方法可以在瀏覽器中高效的處理視頻。
HTMLVideoElement.requestVideoFrameCallback() 是一個(gè)新的WEB API,2021 年 1 月 25 日提交的草案。requestVideoFrameCallback()
方法允許WEB開(kāi)發(fā)者注冊(cè)一個(gè)回調(diào)方法,回調(diào)方法在新視頻幀發(fā)送到合成器時(shí)在渲染步驟中運(yùn)行。這是為了讓開(kāi)發(fā)人員對(duì)視頻執(zhí)行高效的每幀視頻操作,例如視頻處理和繪制到畫(huà)布上(截屏)、視頻分析或與外部音頻源同步。
與 requestAnimationFrame() 的區(qū)別
可以通過(guò)API執(zhí)行方法 drawImage() 將視頻幀繪制到畫(huà)布等操作將盡可能的與屏幕上播放的視頻的幀速率同步。與通常每秒觸發(fā)約 60
次的 window.requestAnimationFrame()
不同,requestVideoFrameCallback()
與實(shí)際視頻幀速率綁定,但也有一個(gè)重要的例外:
運(yùn)行回調(diào)的有效速率是視頻速率和瀏覽器速率之間的較小速率。這意味著在以
60Hz
繪制的瀏覽器中播放的25fps
視頻將以25Hz
觸發(fā)回調(diào)。在同一個(gè)60Hz
瀏覽器中的120fps
視頻會(huì)以60Hz
觸發(fā)回調(diào)。
由于它與 window.requestAnimationFrame()
相似,該方法最初被提議為 video.requestAnimationFrame()
,最終使用新的名稱 requestVideoFrameCallback()
,這是在漫長(zhǎng)的討論后達(dá)成一致的,這個(gè)名稱相對(duì)來(lái)說(shuō)比較更加直觀。
在前端開(kāi)發(fā)中,通常在使用一些新的WEB API的時(shí)候需要檢測(cè)其可用性,同樣可以使用一下代碼進(jìn)行檢測(cè):
if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) { // 支持相應(yīng)的API }
瀏覽器支持
使用方法
如果曾經(jīng)使用過(guò) requestAnimationFrame()
方法,那么會(huì)立即對(duì) requestVideoFrameCallback()
方法并不陌生。注冊(cè)一次初始回調(diào),然后在回調(diào)觸發(fā)時(shí)重新注冊(cè)。
const videoFrameCallback = (now, metadata) => { console.log(now, metadata); // 重新注冊(cè)回調(diào)以獲得關(guān)于下一幀的通知。 videoElement.requestVideoFrameCallback(videoFrameCallback); }; // 最初注冊(cè)回調(diào),以便在第一幀時(shí)得到通知。 videoElement.requestVideoFrameCallback(videoFrameCallback);
在回調(diào)中,now
是一個(gè) DOMHighResTimeStamp
,metadata
是一個(gè) VideoFrameMetadata
字典,具有以下屬性:
presentationTime
:DOMHighResTimeStamp
類(lèi)型,用戶代理提交幀以進(jìn)行合成的時(shí)間。expectedDisplayTime
:DOMHighResTimeStamp
類(lèi)型,用戶代理期望框架可見(jiàn)的時(shí)間。width
:unsigned long
類(lèi)型,視頻幀的寬度,以像素為單位。height
:unsigned long
類(lèi)型,視頻幀的高度,以像素為單位。mediaTime
:double
類(lèi)型,媒體呈現(xiàn)時(shí)間戳 (PTS),以呈現(xiàn)幀的秒數(shù)為單位(例如,它在video.currentTime
時(shí)間線上的時(shí)間戳)。presentedFrames
:unsigned long
類(lèi)型,提交用于合成的幀數(shù)的計(jì)數(shù)。允許客戶端確定VideoFrameRequestCallback
實(shí)例之間是否丟失幀。processingDuration
:double
類(lèi)型,從將具有與此幀相同的呈現(xiàn)時(shí)間戳 (PTS) 的編碼數(shù)據(jù)包(例如,與mediaTime
相同)提交到解碼器直到解碼的幀準(zhǔn)備好呈現(xiàn)所經(jīng)過(guò)的持續(xù)時(shí)間(以秒為單位)。
對(duì)于 WebRTC
應(yīng)用程序,可能會(huì)出現(xiàn)其他屬性:
captureTime
:DOMHighResTimeStamp
類(lèi)型,對(duì)于來(lái)自本地或遠(yuǎn)程源的視頻幀,這是攝像機(jī)捕獲幀的時(shí)間。對(duì)于遠(yuǎn)程源,使用時(shí)鐘同步和RTCP
發(fā)送方報(bào)告來(lái)估計(jì)捕獲時(shí)間,以將 RTP 時(shí)間戳轉(zhuǎn)換為捕獲時(shí)間。receiveTime
:DOMHighResTimeStamp
類(lèi)型,對(duì)于來(lái)自遠(yuǎn)程源的視頻幀,這是平臺(tái)接收到編碼幀的時(shí)間,即通過(guò)網(wǎng)絡(luò)接收到屬于該幀的最后一個(gè)數(shù)據(jù)包的時(shí)間。rtpTimestamp
:unsigned long
類(lèi)型,與此視頻幀關(guān)聯(lián)的 RTP 時(shí)間戳。
請(qǐng)注意,在某些情況下,
width
和height
可能與videoWidth
和videoHeight
不同(例如,變形視頻可能具有矩形像素)。
在上面的參數(shù)列表中特別值得關(guān)注的是 mediaTime
,在 Chromium
的實(shí)現(xiàn)中,使用音頻時(shí)鐘作為支持 video.currentTime
的時(shí)間源。而 mediaTime
直接由幀的 presentationTimestamp
填充。如果希望以可再現(xiàn)的方式準(zhǔn)確地標(biāo)識(shí)幀,包括準(zhǔn)確地識(shí)別錯(cuò)過(guò)的幀,那么應(yīng)該使用 mediaTime
。
總結(jié)
能夠在瀏覽器中訪問(wèn)相機(jī)而不使用第三方軟件是一個(gè)不可思議的進(jìn)步。與 canvas
和一些JavaScript相結(jié)合,相機(jī)變得快速而容易訪問(wèn)。它不僅可以使用相機(jī),而且因?yàn)?nbsp;canvas
是超靈活的,將能夠在未來(lái)添加性感的 instagram
風(fēng)格的圖像濾鏡。
到此這篇關(guān)于瀏覽器視頻幀操作方法 requestVideoFrameCallback()的文章就介紹到這了,更多相關(guān)JS requestVideoFrameCallback內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript學(xué)習(xí)筆記之DOM基礎(chǔ) 2.4
DOM(Document Object Model),即“文檔對(duì)象模型”?;谡Z(yǔ)義的邏輯結(jié)構(gòu),DOM將網(wǎng)頁(yè)內(nèi)的元素與內(nèi)容呈現(xiàn)為一個(gè)清晰、易讀的樹(shù)狀模型,下面小編把最近整理有關(guān)javascript筆記之DOM基礎(chǔ)分享給大家,有需要的朋友可以參考下2015-08-08詳解uniapp分包的實(shí)現(xiàn)方式及優(yōu)點(diǎn)
當(dāng)今移動(dòng)應(yīng)用開(kāi)發(fā)領(lǐng)域,隨著用戶對(duì)于應(yīng)用功能和體驗(yàn)的要求不斷提高,應(yīng)用程序的復(fù)雜度也在不斷增加,在這種情況下,應(yīng)用程序的體積也隨之增大,為了解決這個(gè)問(wèn)題,Uniapp提供了分包功能,本文將詳細(xì)介紹Uniapp分包的功能和優(yōu)勢(shì),包括如何通過(guò)配置文件實(shí)現(xiàn)分包2023-09-09JavaScript中具名函數(shù)的多種調(diào)用方式總結(jié)
這篇文章主要介紹了JavaScript中具名函數(shù)的多種調(diào)用方式總結(jié),本文總結(jié)了4種方法,需要的朋友可以參考下2014-11-11JavaScript forEach 方法跳出循環(huán)的操作方法
這篇文章主要介紹了JavaScript forEach 方法跳出循環(huán)的操作方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-01-01