此文已由做者吳家聯受權網易雲社區發佈。
css
歡迎訪問網易雲社區,瞭解更多網易技術產品運營經驗。html
去年年中的時候,藉着產品改版的機會,將以前的h5播放器好好整理重構了一番。以前的h5播放器較爲簡陋,有幾個大問題:沒有適配移動端(最大的不足)、沒有提供直播模式、有一些歷史遺留的bug沒有修復。重構版除了解決了這幾個大問題外,還作了不少的優化。加上與flash播放器的結合和近期飛哥主導的教育產品組件標準化,播放器適用性變得更強更通用了。前端
1. h5播放器的設計思路 android
重構後應該包含這些功能:支持點播(非加密的MP4)和直播播放(m3u8)、兼容(適配)移動端、根據平臺自動選擇(使用flash仍是h5)。ios
框架和庫上,仍是選擇主要使用nej框架,nej提供了很豐富的方法。對外暴露的類使用regular實現,由於教育產品前端組件和業務工程大部分是使用regular的,在使用上會很方便。另外在移動端上選用了flexible方案,由於教育產品的web頁適配已經統一使用flexible了,手勢事件的處理選用了web
爲了方便擴展和添加組件,使用了觀察者模式。觀察者模式在視頻播放器這樣規模的工程中使用很是合適,也是屢試不爽的一種設計模式。我直接參考了flex中相似的實現,使用js寫了一遍(固然本身寫也很快)。設計模式
圖如上所示,component基類和componentContainer單例類實現了觀察者模式,全部組件都繼承自component類,component實例中能夠調用方法發送notification對象進行組件之間的通訊,notification的調度則在componentContainer中實現了。這些組件分爲必須組件和可選組件,必須組件包括:視頻對象組件(movieData)、視頻播放組件(mainVideo)、api組件等,可選組件則是根據不一樣產品的業務需求來開發的,能夠經過不一樣組件列表的配置來自定義播放器的具體功能,這個也是在componentContainer實現。Html5VideoMedia則是對HTMLVideoElement的封裝,它不做爲一個組件,只是提供視頻播放的功能,以及定義了相關的事件,使用Html5VideoMedia的除了視頻播放組件,還能夠是片頭廣告組件。api
適配方面,樣式上的適配使用了flexible的方案。有的組件比較複雜,好比控制條,在web端和移動端功能差異很大,樣式差異也很大,能夠考慮不一樣平臺使用不一樣組件(圖中能夠看到control和controlMobile),邏輯上會很清晰,不用寫不少的if和else,不過由於這樣要依賴更多的組件,js和css文件會更大一些。我的以爲爲了提升代碼的可維護性,犧牲部分的文件大小也是可取的。瀏覽器
2. hls直播的一些特色微信
直播狀態的判斷。其實直播功能跟業務的關聯是很大的,這裏的直播狀態也是隻業務中的狀態,好比:未開始、即將開始、直播中、直播結束等等。咱們產品中目前仍是使用前端輪詢的方式更新直播的狀態,有一點要提的是hls流是不會觸發end事件的,因此h5直播的狀態實際上是徹底靠輪詢來控制的。
如何判斷流異常。通常網絡問題或者是源問題的處理能夠監聽video標籤和source標籤的error事件,兩種標籤都須要監聽。可是error觸發時的錯誤信息有時候並不信息,或者說不一樣瀏覽器實現上不同,以前有碰到過改變currentTime屬性來seek,偶爾會觸發error事件,可是error中只說了是網絡錯誤,沒有任何其餘信息,在對比了其餘視頻後才肯定是某個視頻轉碼的問題,確實十分的蛋疼。在直播流播放過程當中,偶爾會出現流異常的狀況,流異常通常會表現爲畫面卡死,不必定觸發error事件。我參考了以前青果同事的方案:每隔一段時間檢查currentTime,若是在播放狀態下currentTime在這段時間內未改變,極可能就是流異常了,則主動從新加載。
3.一些目前沒法解決的問題
ios上視頻相關的問題不少,由於系統的限制太多了。稍微列一下:
1. 同時只能播放一個視頻或者音頻,只容許一個video或者audio標籤。作片頭廣告功能會麻煩一點。
2. ios版本較低的Safari中播放視頻會強制全屏,ios 10中可使用playsinline。在微信和一些定製的webkit中能夠添加webkit-playsinline解決。
3. 在沒有人爲操做的狀況下,沒法實現進入頁面自動開始播放視頻
4. ios中沒法使用js控制video音量,只能由物理按鍵控制。在ios中你能夠直接隱藏音量控制功能了。。。
5. 還有截屏的問題,不過產品中沒有使用到就暫時沒有調研。
android上的問題也不少,主要是由於android版本太多、機型太多,各方面良莠不齊。稍微列一下:
1. 部分android系統會直接替換video標籤,使用系統播放器播放,常見於國產手機
2. canPlayType方法檢測結果與實際不符,這個問題在開發過程當中遇到過,例如在一部華碩手機上檢測到不支持m3u8播放,可是實際卻能夠播放,本來想放開這個限制的,後來發如今雲課堂app的webview中強制播放可能會致使app崩潰,因此最後仍是加上了檢測。。
3. 不支持m3u8播放的android通常是android4.0左右及如下的
網易雲免費體驗館,0成本體驗20+款雲產品!
更多網易技術、產品、運營經驗分享請點擊。
相關文章:
【推薦】 IOS渠道追蹤方式
【推薦】 如何解決在線網頁掛載本地樣式的問題