1. 程式人生 > >關於使用video標籤時src網址blob型別的理解

關於使用video標籤時src網址blob型別的理解

想下載一個視訊時發現是個blob:src形式;不明白這個是個什麼鬼,以下是搜尋學習的總結

  1. javascript
    var video=document.querySelector('video');
    var mediaSource=new MdeiaSource;
    video.Src=URL.createObjectURL(mediaSource);
    mediaSource.addEventListener('sourceopen',sourceOpen);
    function sourceOpen(){
    var mediaSource=this;
    var sourceBuffer = mediaSource.addSourceBuffer('video/mp4';codecs="avc1.42E01E,mp4a.40.2");
    sourceBuffer.addEventListener('updateend',function(){
    mediaSource.endOfStream();
    video.play();
    })
    sourceBuffer.appendBuffer(buf);// buf is the arraybuffer to store the video data
    }

    程式碼解析:建立變數名為video的DOM物件,建立變數名為mediaSource的MediaSource物件。通過函式createObjectURL將video物件的src和mediaSource進行連線,然後通過註冊事件event::sourceopen來觸發當前連線之後的的回撥處理;回撥處理就是需要賦值視訊資料的地方,呼叫MediaSourceBuffer::addSourceBuffer方法來構建一個存放視訊資料的Buffer;在往buffer中存放資料結束後觸發事件updateend。然後呼叫play函式通知瀏覽器播放視訊

  2. MediaSource :mediaSource是Media Source Extensions API表示媒體資源HTMLMediaElement物件的介面。MediaSource物件可以附著在HTMLMediaElement在客戶端進行播放。
    參考網址:

    https://developer.mozilla.org/zh-CN/docs/Web/API/MediaSource

    MediaSource屬性:

    1. MediaSource.sourceBuffers:只讀 ,返回一個SourceBufferList物件,包含了SourceBuffer的列表object associated with this MediaSource.
    2. MediaSource.activeSourceBuffer:只讀
    3. MediaSource.readyState:只讀
    4. mediaSource.duration

      方法:

    5. addSourceBuffer():該事件是在觸發sourceopen監聽時進行的,該動作會建立一個sourceBuffer物件用於資料流的播放處理。如果mediaSource物件無法觸發該事件;則無法通過該擴充套件進行播放的。

    6. removeSourceBuffer():
    7. endOfStream()
  3. MediaSource介面的使用:

    1. 判斷是否mediaSource的擴充套件類,該語句決定了整個播放方式是否可以使用MediaSource介面控制播放器。

      javascript
      window.MediaSource = window.MediaSource || window.WebkitMediaSource;

    2. isTypeSupporteed:判斷是否支援要解碼播放的視訊檔案編碼和型別。

      javascript
      MediaSource.isTypeSupported('video/webm;codecs="vorbis,vp8"');//是否支援webm
      MediaSource.isTypeSupported('video/mp4;codecs="avc1.42E01E,mp4a.40.2"')//是否支援MP4
      MediaSource.isTypeSupported('video/mp2t;codes="avc1.42E01E,mp4a.40.2"')//是否支援ts

    3. addSourceBuffer

      javascript
      mediaSource.addSourceBuffer('video/mp4;codecs="avc1.42E01E,mp4a.40.2"')

    4. appendBuffer:sourceBuffer物件的方法,用於持續資料的新增播放

      javascript
      sourceBuffer.appendBuffer(Uint8array);//媒體二進位制資料

    5. buffered: 型別為TimeRanges,描述了新增進去的所有媒體資料的range資訊。為一個數組,裡邊標示了持續或間斷的時間資訊列表

      javascript
      for(var i=0;i<buffered.length;i++){
      start=buffered.start(i)//第i個range資訊的開始時間
      end=buffered.end(i);//第i個range資訊的結束時間
      }

      如果播放的媒體資料是連續的;則只有一個開始時間點和一個結束時間點。所以如果要計算緩衝中還存在多少時間則可以通過該描述資訊與當前播放時間點進行換算

      javascript
      function play(){
      if(!this.mediaSource){
      this.mediaSource=new MediaSource();
      var me=this;
      this.mediaSource.addEventListener("sourceopen",function(){
      me.onMediaSourceOpen();
      });
      this.mediaSource.addEventListener("sourceended",function(){
      me.onMediaSourceEnded();
      });
      this.mediaSource.addEventListener('sourceclose',function(){
      me.onMediaSourceClose();
      });
      this.mediaSource.addEventListener("error",function(){
      me.onUpdataError();
      });
      this.video=this.createNewVideo();
      this.video.src=window.URL.createObjectURL(this.mediaSource);
      this.video.play();
      }
      if(!this.sourceBuffer){
      return ;
      }
      if(this.sourceBuffer.updating){
      return;//上一塊資料還在新增中
      }
      try{
      this.sourceBuffer.appendBuffer(dataBytes);//新增資料
      }catch(err){}
      }
      function createNewVideo(){
      var newVideo=document.createElement("video");
      newVideo.id="player";
      newVideo.width=this.videoWidth;
      newVideo.height=this.videoHeight;
      return newVideo;
      }
      //事件偵聽
      onMediaSourceOpen:function(){
      //DOMString可以通過轉碼獲得
      var typeNmae='video/mp4;codecs="avc1.42E01E,mp4a.40.2"';
      var issurpport=MediaSource.isTypeSupported(typeName);
      this.mediaSource.duration=this.totalDuration;//設定視訊總時長
      this.sourceBuffer=this.mediaSource.addSourceBuffer(typeName);
      }
      onMediaSourceEnded:function(){
      console.log("source ended");
      }
      onMediaSourceClosed:function(){
      console.log("cource close");
      }
      }

  4. 以下是自己做的一個demo;MP4格式的檔案未成功;webm格式的成功了;

    “`

    <head>
        <meta charset="UTF-8">
        <title>blob</title>
    </head>
    
    <body>
        <video id="video" controls="controls"></video>
        <script type="text/javascript">
            var video = document.querySelector('video');
            var assetURL = 'http://172.16.70.106:8020/Demo/Demo1/audio/test2.webm';
            // Need to be specific for Blink regarding codecs
            // ./mp4info frag_bunny.mp4 | grep Codec
            var mimeCodec = 'video/webm;codecs="vorbis,vp8"';
    
            if('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
                var mediaSource = new MediaSource();
                video.src = URL.createObjectURL(mediaSource);
                mediaSource.addEventListener('sourceopen', sourceOpen);
    
            } else {
                console.error('Unsupported MIME type or codec: ', mimeCodec);
            }
    
            function sourceOpen() {
                console.log(this); // open
                var mediaSource = this;
                var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
                fetchAB(assetURL, function(buf) {
                    console.log(buf)
                    console.log(sourceBuffer);
                    sourceBuffer.addEventListener('updateend', function() {
                        console.log(mediaSource);
                        mediaSource.endOfStream();
    
                        video.play();
                        console.log(mediaSource.readyState); // ended
                    });
                    sourceBuffer.appendBuffer(buf);
                });
            };
            function fetchAB(url, cb) {
                console.log(url);
                var xhr = new XMLHttpRequest;
                xhr.open('get', url);
                xhr.responseType = 'arraybuffer';
                xhr.onload = function() {
                    console.log(xhr.response);
                    cb(xhr.response);
                };
                xhr.send();
            };
        </script>
    </body>
    


    “`