<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          這幾年,我在video上踩的坑

          時間:?2017-11-13閱讀:?1418標簽:?video

          H5-Video 實踐

          隨著移動設備的飛速發展、各瀏覽器環境對Video支持的普及、Flash的沒落,使用一個簡單的VideoHTMLElement標簽來替代原有的播放器插件進行視頻媒體播放,幫我們更好的提高用戶體驗、增加更多的產品可能性已經日趨明顯。

          這篇文章我們從Video的幾種應用場景、各環境中依然或將長期存在的問題、基于原生Video進行業務開發常見的問題等方面,一起學習了解更多的實踐方向和可能存在的坑。

          一. Viode的幾種應用場景

          1. 最基本的HTML標簽應用

          H5中視頻播放,像我們以前使用IMG標簽插入圖片到網頁里一樣方便,寫一個video設置一個src屬性指定媒體源地址就可以實現媒體播放了,針對低版本瀏覽器video的HTML結構也提供了友好的兼容方案,只需要在video標簽內寫上不兼容時要展示的HTML內容即可。

          <video src="https://chimee.org/vod/1.mp4" controls>
              您的瀏覽器不支持Video標簽。
          </video>


          為了便于用戶的操作,我們還設置了一個布爾型controls屬性,告訴瀏覽器這個播放器渲染時需要顯示控制條,在Chrome中渲染出的效果如下:

          image

          當然HTMLVideoElement的屬性設置不只簡單的提供了一個controls,還有更多的可配置項,比如:通過添加autoplay屬性開啟在動播放、通過添加muted設置為靜音模式、通過給volume屬性設置0.0~1.0之間的數值控制初始音量大小...

          2. 針對不同環境配置其支持的媒體資源

          目前原生H5支持的媒體格式主要有MP4、OGG、WebM、M3U8等,基于媒體編碼格式存在專利和產權歸屬問題,所以各大瀏覽器廠商之間對媒體格式的支持也各不相同:

          MP4:

          image

          WebM:

          image

          OGG:

          image

          M3U8:

          image

          通過上面可以看到,目前就MP4各瀏覽器的兼容較好。這種瀏覽器之間媒體格式支持的差異化,使得我們必須得考慮不同用戶環境的兼容問題。比較慶幸的是Video標準制定中也考慮了這些問題,比如在HTML代碼的編寫上我們可以在video標簽內嵌套source標簽來達成不同兼容環境下設定相應媒體源的需求:

          <video controls>
            <source src="https://chimee.org/vod/2.webm">
            <source src="https://chimee.org/vod/2.ogg">
            <source src="https://chimee.org/vod/2.mp4">
            <source src='https://chimee.org/x.myvideoext' type='video/mp4; codecs="mp4v.20.8, mp4a.40.2"'>
            <p>當前環境不支持video標簽。</p>
          </video>


          當我們設置了source,就可以讓不同的瀏覽器環境按照自身的支持情況,找到能正常解碼播放的媒體源進行播放,為了讓瀏覽器更快速準確的匹配媒體資源,建議同時設定type屬性,來明確說明媒體編碼格式,以盡可能的減少不必要的等待。

          另外,在編寫javascript的時候,也可以通過HTMLVideoElement的canPlayType API進行當前環境的格式兼容判斷:

          let videoEl = document.createElement("video");
          // 是否支持 MP4
          videoEl.canPlayType('video/mp4') !== '';
          // 是否支持 MP4 & 特定編碼的
          videoEl.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"') !== '';
          // 是否支持 webm & 特定編碼的
          videoEl.canPlayType('video/webm; codecs="vp8, vorbis"') !== '';
          // 是否支持 ogg & 特定編碼的
          videoEl.canPlayType('video/ogg; codecs="theora, vorbis"') !== '';
          // 是否支持 HLS 的 m3u8
          videoEl.canPlayType('application/vnd.apple.mpegURL') !== '';
          // 是否支持 HLS 的 TS 切片
          videoEl.canPlayType('video/mp2t; codecs="avc1.42E01E,mp4a.40.2"') !== '';


          使用canPlayType方法傳入要檢測的媒體類型或具體編碼格式,我們將可能得到'maybe'、'probably'、''三個String值中的一個,當得到空字串的時候,可以確定為不支持。

          image

          (動手嘗試一下)

          3. 使用Video的API和事件交互實現RPG互動游戲

          一方面我們可以通過VideoElement的JS API進行狀態的修改控制,來實現用戶行為對劇情發展的影響帶來不同場景間的切換;另一方面我們通過對VideoElement的事件監聽可以響應狀態的變化,當劇情發展到特定場景需要用戶執行關鍵抉擇。

          image

          動手嘗試一下

          到這里只是基于最基本的VideoAPI已經可以實現很多有意思的東西了。聰明的你一定想到了舉一反三,實現更復雜的一些互動游戲了吧,比如各種風靡微信的密室逃脫...

          image

          如果我們接下來在Video的使用上更進一步,加入更寬泛的H5 API應用,腦洞或許可以更大。

          4. 使用Video播放本地媒體文件

          在這里我們加入FileInput和FileReader API,讓用戶可以直接在網頁中預覽并播放自己選擇的本地媒體文件。

          let iptFileEl = document.querySelector('input[type="file"]');
          let videoEl = document.querySelector('video');
          
          iptFileEl.onchange = e =>{
            let file = iptFileEl.files && iptFileEl.files[0];
            playFile(file);
          };
          
          function playFile(file){
            if(file){
              let fileReader = new FileReader();
              fileReader.onload = evt => {
                if(FileReader.DONE == fileReader.readyState){
                  videoEl.src = fileReader.result;
                }else{
                  console.log('FileReader Error:', evt);
                }
              }
              fileReader.readAsDataURL(file);
            }else{
              videoEl.src = '';
            }
          }


          這里使用了比較簡單粗暴的方案 --- 當用戶選擇了媒體文件,那么直接使用FileReader得到本地文件的DataURI,并塞給video進行播放;雖然這個方案存在一些局限,但實用價值也還是挺高的,比如在線GIF編輯器 https://gif.75team.com 的視頻轉GIF功能就有用到類似的方案。

          image

          (動手嘗試一下)

          5. 使用Video播放設備自帶攝像頭視頻流

          隨著WebRTC的興起,以往在WEB端很難實現的需求,也完全可以成為現實。比如通過瀏覽器提供的 getUserMedia API,可以非常容易的開啟攝像頭并采集的視頻流在頁面上播放:

          navigator.getUserMedia(
            { audio: false, video: true},
            function(stream) {
              let video = document.querySelector('video');
              video.srcObject = stream;
              // 當媒體頭信息就緒,自動開始播放
              video.onloadedmetadata = () => video.play();
            },
            function(err) {
              alert('getUserMedia error: ' + err.message);
            }
          );


          既然能拿到攝像頭視頻流了,自然也就可以做更多的事情了,關于攝像頭媒體流播放可以點這里嘗試一下;而配合Canvas進行Video的畫面的分析處理,我們也可以做更多有趣的嘗試,比如:人臉識別 ...

          image

          而結合MediaRecorder API,也可以很方便的實現純WEB前端的視頻錄制功能

          6. 使用Video播放JS異步拉取的媒體流

          直播行業的興起,讓更多的人了解了動態媒體流的存在,而WebRTC制定之初也主要是定位在多媒體實時通訊方向,這里面包含的MediaSource API讓我們可以用JS創建動態媒體源,然后再通過任意異步方式往里 appendBuffer,實現不停的拉流播放。

          var video = document.querySelector('video');
          var mediaSource = new MediaSource(); 
          video.src = URL.createObjectURL(mediaSource);
          
          mediaSource.addEventListener('sourceopen', function() {
            var sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
            fetchAB('https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4', function (buf) {
              sourceBuffer.addEventListener('updateend', function () {
                mediaSource.endOfStream();
                video.play();
              });
              sourceBuffer.appendBuffer(buf);
            });
          });
          
          function fetchAB (url, cb) {
            var xhr = new XMLHttpRequest();
            xhr.open('get', url);
            xhr.responseType = 'arraybuffer';
            xhr.onload = function () { cb(xhr.response) };
            xhr.send();
          };


          異步拉流播放效果示例

          前面我們在談到原生Video支持的媒體格式類型時,了解到的M3U8動態切片格式是眾多格式中適合直播流的媒體類型,但并不是所有瀏覽器都支持,而且眼下很多直播平臺可能也還是在使用FLV比較多,但原生Video并不支持FLV,但是結合JS動態拉流、解碼、編碼、MediaSource API,也讓WEB前端直接播放原生不支持的媒體格式成為了可能。

          二. 現狀與未來

          1. 未來很美好

          當我們了解到這里,你是不是也想到除了上面這些不同類型的Video應用場景,還有更多的腦洞和點子呢?

          通過新的API了解和應用,顯而易見WEB前端能做的事情已經越來越多了,可以施展的空間也越來越大了呢!是不是也已經躍躍欲試想去新的空間里嘗試更多更大膽有趣的想法或探索更廣袤的可能了吧?

          多好的前景!多么的振奮人心啊!!~~~

          image

          2. 現狀還比較悲催

          如果你已經邁出這一步,打開H5-Video視頻播放處理的大門,就會發現 --- 并不是像想象中憧憬的那么美好。

          因為作為WEB前端研發人員,必須要面對不同的瀏覽器環境各自的實現,這就像挨個打開不同的大門,而每個大門里面蘊藏的是整齊有序還是雜亂無章亦或隨心所欲,打開之前都是未知的...

          image

          三. 無法避免的環境差異

          在IE還大行其道的WEB前端遠古時代,大家比較痛恨各種怪異模式,當下伴隨移動設備的興旺,各種W3C API標準也越來越完美了,但我們發現越來越多的設備、瀏覽器、WebView廠商雨后春筍一樣層出不窮,并且在標準的支持上也各有各的想法,甚至在自己的一畝三分地里制定著自己的規范標準...

          1. 各環境中Video UI不一致

          我們拿同一個頁面,放一個“大白兔”的示例視頻,在不同的瀏覽器環境下觀察截圖:

          image image image image image image image image

          怎么樣,意不意外?驚不驚喜?

          同一個瀏覽器不同的版本都可能大相徑庭,當你的用戶給你反饋播放器上一些奇奇怪怪按鈕看不懂事干嘛的、一些奇特的功能用著不爽的時候,你能確定他說的與你看到的是一個東西嗎?

          2. 各種環境中API實現與支持程度的差異

          看看下面這一堆配置都是什么鬼?(本小節參考資料)

          <video
            src="video.mp4" 
            controls
            poster="images.jpg"
            preload="auto" 
            webkit-playsinline="true" 
            playsinline="true"
            x-webkit-airplay="allow" 
            x5-video-player-type="h5"
            x5-video-player-fullscreen="true"
            x5-video-orientation="portraint"
            style="object-fit:fill">
          </video>


          我們針對不同的環境,必須做一些符合它的要求的配置,以期望能盡量達成我們想要的目的。但是不得不說的是,標準API里的controls、poster、autoplay也都未必有效(只是想隱藏控制條都得想各種糾結的辦法--裁剪出鏡、更或者一些宣傳短片干脆做成序列幀...),前面說的通過source來設置不同媒體源的方案,部分瀏覽器也可能是不認識的。

          W3C標準和MDN告訴我們可以通過VideoElement.error取得媒體播放異常的參考信息,但是實踐告訴我們,很多環境下是壓根沒有這么個東東,或者參考信息不夠詳盡靠譜。

          3. 事件交互行為不一致

          通過MediaEvents&API 檢測,會發現各環境中播放進度變化、事件觸發頻率不同、部分事件觸發時相應狀態值未必可靠、部分場景缺少事件(全屏狀態變化、系統播放器劫持)、seek時不一定觸發play...

          例如ios部分環境監聽canplay和canplaythrough(是否已緩沖了足夠的數據可以流暢播放),當加載時是不會觸發的,即使preload="auto"也沒用,但在pc的chrome調試器下和android下,是會在加載階段就觸發,ios需要播放后才會觸發。

          部分環境中視頻從開始播到能展現畫面會有短暫的黑屏(處理視頻源數據的時間),為了避免這個黑屏,可以在視頻上加個浮層或設置容器背景并在播放前隱藏video,然后監聽相關事件,開始播放或認為有畫面的時候再切換到Video界面。

          所以總體來看,并沒有可靠統一的規范。

          4. 媒體格式的支持無法保證

          在前面探討各瀏覽器環境原生Video支持的媒體類型時候,有各媒體格式兼容情況的詳盡貼圖 --- MP4 總體支持較好、M3U8在高版本移動環境較好、媒體點播直播中現存大量 flv 播放需求原生Video是不支持的。

          到系統層面來看,不同版本支持的類型或編解碼版本,也會存在各種不同的差異;當你不停的查標準規范、查API文檔,再不停的實踐,你也許會發現 ---- “哇靠,真的是‘能力越大責任越大’呢”。

          image

          四. 視頻播放業務層比較糾結的幾個問題

          如果耐著性子把環境問題一個一個踩坑,一個一個地雷趟過來,終于可以寫業務邏輯了,結果發現,業務邏輯上依然讓人頭大。

          1. 狀態處理容易存在沖突

          假如我們將原生video元素視作一個數據狀態儲存容器,那么可以看到以上四種需求需要如下權限:

          對于有播放狀態控制的一些控件,會同時需要狀態的讀、寫;對于展示式需求,例如無交互的彈幕、打賞禮品、特效掛件等,只需要讀狀態 --- 例如暫停則停止;更高級的,例如片頭、片尾、插片廣告,我們不但要知道播放狀態、時機,甚至要在廣告播放期間阻止一切默認行為,直到允許用戶跳過等,這就不只是需要完整的讀寫權限,還要具備阻截別人讀寫的功能...

          當業務邏輯日積月累狀態操作的場景越來越繁雜,缺乏合理的狀態管理機制,勢必會導致狀態混亂、沖突的產生。

          image

          2. 交互與層級管理的矛盾

          UI插件的需求在業務中也是紛繁復雜的,比如通常的彈幕插件是不需要交互,只要滾動展示內容,這時候我們點擊彈幕跟點擊播放器本身一樣要觸發暫停或播放行為。

          突然有一天需要夾雜展示點擊后跳轉詳情的廣告內容,這時需要交互行為,這也就與前面的需求相矛盾了。

          再加上一些動態變更層級的UI組件---比如右鍵菜單、popup配置浮層... 這也需要有一套可靠靈活的層級管理機制,來支撐這些可能出現的需求。

          image

          3. 日志收集上報易耦合

          好的產品離不開數據回饋、理性分析、合理優化。

          對于已經實現了的業務邏輯,當我們發現問題的時候,通常都是在后續迭代優化過程時,插入日志收集邏輯在已有業務邏輯中間,但這么以來我們的日志處理相關的邏輯勢必會分散在業務代碼的各個角落里,不但干擾業務邏輯的可讀性、對后續業務迭代增加難度,對于日志處理需求本身,也難以理解和維護;這帶來的弊端可能會更大的抵消掉了原期望通過它得到的價值。

          一套能與業務邏輯完全解耦的日志收集上報工具,不但有助于業務迭代優化,也一定要保證自身的獨立可迭代維護性。

          五. 小結

          綜上,如果要進行H5視頻播放開發,環境差異帶來的各種瑣碎問題無法避免,技術的發展也一直在不停的前進著,美好就在前面,避免重蹈覆轍踩別人踩過的坑,你也就有更多的時間和精力做更多有價值的產出。

          如果有一套更理想的解決方案,她能帶給我們統一的API與事件行為、可控的狀態管理機制、一致且可自定義的UI、支持熱插拔且解耦的插件處理策略、能保證各環境對M3U8&FLV的支持,并且可定制,你是否也會選擇她呢?

          原文來源:huzunjie   

          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/94

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网