很久很久以前,網絡安全還不那么引起重視的年代,各大瀏覽器廠商都有支持嵌入本地應用程序的框架。眾所周知得諸如"activex ATL npapi之類的標准框架"都允許原生應用開發者將視頻的解碼和播放業務放到應用程序內處理,再通過<object>標簽等形式借用瀏覽器提供的窗口句柄來實現html和原生應用窗口的布局和展示。那個時候一切看起來都很和諧。
但是伴隨互聯網的發展,大部分還混得下去的瀏覽器廠商逐漸意識到要並且原生應用在網頁中的嵌入,因為大部分的原生應用都存在安全隱患,如果用戶電腦的訪問權限控制不嚴格的話,存在很大的隱患。至此各個視頻相關業務公司就開始使出各種奇招。
綜述整個歷史差不多就是這樣(整個是鄙人多年以來經驗總結)
ocx/npapi ——> atl/nappi ——>chromeapp
——> native messaging
——> flash ——>video標簽
——>sokect通信+本地應用
——>js解碼庫+canvas
——>直接上原生客戶端,內嵌瀏覽器引擎(俗稱混合app)
上述所有的方案,很不幸的博主都經理過。其中,紫色的即將完全淡出歷史舞台,但是絕對算當上功臣了。紅色的就是曇花一現,藍色的使用場景小的可憐,綠色的方案在各自擅長的領域發光發熱,黃色的絕對是個異類,但是不得不說能很快的解決所有的廠商五花八門的框架,並且可以快速的出一個產品,說服用戶一勞永逸。
在這里我們重點分享一下js解碼庫+canvas這個看起來比較符合時代發展的產物的實現方案和大致步驟。
你一定是想直接來一二三四吧?NO,這里我必須說明一下,如果你想將某個開源解碼庫轉成js的軟解庫實現視頻播放功能,而你碰巧是一個web開發,那我要建議你一定要先去看看內存是什么?並且大致了解下什么是編解碼。沒有這些基礎,依葫蘆畫瓢你都畫不像。
首先簡單說下基礎知識部分:
1)從一段視頻流到一個畫面播放之間大致經過的過程(我也不是專業編解碼的,講的不准確請勿拍):
我們拿到的某個視頻文件或者一段直播視頻實際內容是一段二進制的數據。
這段數據包含了連續的單幀的編碼后的數據,在每一幀數據之上依照不同的文件格式進行封裝(這一層可以理解為為不同的播放器程序做一些特定的視頻業務而進行的,通常我們所說的mp4 avi等等都數據對視頻原始幀的二次封裝,加上了一些特定的信息。)而每一幀的原始數據又分不同的編碼類型(h264 jpeg等)。
先對二進制數據流做碼流分析,識別出碼流的封裝格式,拆解幀頭部分得到一個個的單幀的裸數據
對每一幀的裸數據送解碼接口進行解碼,得到yuv數據,或者rgb
在客戶端的播放窗口上調用系統的API來顯示yuv或者rgb,按照幀率來進行yuv的間隔顯示(例如幀率為25的視頻,則每40ms顯示一幀yuv)
2)瀏覽器對js的內存操作的支持,web開發可以通過typearray類型將所有的需要的數據都轉換成整形或者浮點型的數值,並保存在內存當中,並且由調用者管理內存的申請和釋放。在支持webassembly技術的瀏覽器下,c/c++代碼模塊轉換成wasm文件內申請的內存可以與普通的js文件共享。
下一章節,將會對asm.js webassembly ffmpeg 以及emsdk坐下簡單的介紹