关于blob类型的基础说明

2019-08-02  本文已影响0人  hao102

想下载一个视频时发现是个blob:src形式;不明白这个是个什么鬼,以下是搜索学习的总结

  1. 参考网址:https://creamidea.github.io/static/html/articles/HTML5-Video-Blob.html 。先来段代码熟悉下意思
 <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n7" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">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
    }</pre>  

代码解析:创建变量名为video的DOM对象,创建变量名为mediaSource的MediaSource对象。通过函数createObjectURL将video对象的src和mediaSource进行连接,然后通过注册事件event::sourceopen来触发当前连接之后的的回调处理;回调处理就是需要赋值视频数据的地方,调用MediaSourceBuffer::addSourceBuffer方法来构建一个存放视频数据的Buffer;在往buffer中存放数据结束后触发事件updateend。然后调用play函数通知浏览器播放视频

  1. 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

    方法:

    1. addSourceBuffer():该事件是在触发sourceopen监听时进行的,该动作会创建一个sourceBuffer对象用于数据流的播放处理。如果mediaSource对象无法触发该事件;则无法通过该扩展进行播放的。

    2. removeSourceBuffer():

    3. endOfStream()

  2. MediaSource接口的使用:

    参考网址:http://chenzhaofei.lofter.com/post/1d03c1b7_58d8a79

  3. 判断是否mediaSource的扩展类,该语句决定了整个播放方式是否可以使用MediaSource接口控制播放器。

        <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n35" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">window.MediaSource = window.MediaSource || window.WebkitMediaSource;</pre>
  1. isTypeSupporteed:判断是否支持要解码播放的视频文件编码和类型。
        <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n38" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">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</pre>
  1. addSourceBuffer
        <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n41" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">mediaSource.addSourceBuffer('video/mp4;codecs="avc1.42E01E,mp4a.40.2"')</pre>
  1. appendBuffer:sourceBuffer对象的方法,用于持续数据的添加播放
        <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n44" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">sourceBuffer.appendBuffer(Uint8array);//媒体二进制数据</pre>
  1. buffered: 类型为TimeRanges,描述了添加进去的所有媒体数据的range信息。为一个数组,里边标示了持续或间断的时间信息列表
        <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n47" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">for(var i=0;i<buffered.length;i++){
         start=buffered.start(i)//第i个range信息的开始时间
         end=buffered.end(i);//第i个range信息的结束时间
        }</pre>

如果播放的媒体数据是连续的;则只有一个开始时间点和一个结束时间点。所以如果要计算缓冲中还存在多少时间则可以通过该描述信息与当前播放时间点进行换算

        <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="javascript" cid="n49" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;">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");
         }
        }</pre>
  1. 以下是自己做的一个demo;MP4格式的文件未成功;webm格式的成功了;但是不能跨越
    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm" lang="" cid="n52" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Monaco, Consolas, &quot;Andale Mono&quot;, &quot;DejaVu Sans Mono&quot;, monospace; margin-top: 0px; margin-bottom: 20px; background-color: rgb(51, 51, 51); font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; padding: 10px 10px 10px 30px; width: inherit; background-position: initial initial; background-repeat: initial initial;"><!DOCTYPE html>
    <html>
    ​
     <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>
    </html></pre>

ps:写在最后;有朋友问我大于10M的视频文件是怎么处理的;因为本人不会后台;所以仅仅研究了下前端播放blob文件的处理方法;对后台的处理等有机会研究下会持续更新!!!

上一篇下一篇

猜你喜欢

热点阅读