几个缓冲区后无法附加媒体源缓冲区

时间:2016-11-26 10:26:50

标签: javascript html5 encryption mediastream

我正在开发一个Web应用程序,其中应用程序下载加密的数据块。然后我必须解密并播放视频。但我不能让用户等待所有解密。因此我正在使用Media Stream API。这是工作。但是在解密最后一个块之后我收到了这个错误。

“未捕获DOMException:无法在'MediaSource'上执行'addSourceBuffer':此MediaSource已达到它可以处理的SourceBuffer对象的限制。不能添加其他SourceBuffer对象。(...)”

<script type="text/javascript">

//////////

 var no_of_files = 0;

 var no_of_dlfiles = 0;

 var FilesURL = [];

 var files_str = 'video/vid_1.webm, video/vid_2.webm, video/vid_3.webm, video/vid_4.webm, video/vid_5.webm';

var file_counter = 0;

var mimeCodec = 'video/webm; codecs="vorbis,vp8"';

var passkey = "014bcbc0e15c4fc68b098f9b16f62bb7shahbaz.hansinfotech@gmail.com";

FilesURL = files_str.split(',');

no_of_files = FilesURL.length;

var player = document.getElementById('videoplayer');

if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
 var mediaSource = new MediaSource;
 //console.log(mediaSource.readyState); // closed
 player.src = URL.createObjectURL(mediaSource);
 mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
 console.error('Unsupported MIME type or codec: ', mimeCodec);
}

//////////

function sourceOpen (_) {
console.log("start");
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
sourceBuffer.mode = "sequence";

function WriteDatatoTemp()
{

 //console.log(this.readyState); // open
 if(file_counter<FilesURL.length)  
 {
  console.log(file_counter);
  no_of_dlfiles++;
  $("#decryptionRatio").text(no_of_dlfiles+" of "+no_of_files);
  $("#decryption_status").show();

      getFileObject(FilesURL[file_counter], function (fileObject) {
        //

        var outputFile = fileObject; 

                var reader = new FileReader();

                reader.onloadend = function(e){




              var decrypted_data = JSON.parse(CryptoJS.AES.decrypt(e.target.result, passkey, {format: CryptoJSAesJson}).toString(CryptoJS.enc.Utf8));
                      var byteArray = Base64Binary.decodeArrayBuffer(decrypted_data);  

                      sourceBuffer.addEventListener('updateend', function(){

                        file_counter++;
                       // console.log(file_counter);

                            if(player.paused)
                            {
                              player.play();
                            }


                          if(file_counter == FilesURL.length - 1)
                          {
                            mediaSource.endOfStream();
                          }

                            WriteDatatoTemp();

                });


                try
                {
                  while(!sourceBuffer.updating)
                  {
                    sourceBuffer.appendBuffer(byteArray);
                  }

                }
                catch(e)
                {
                  console.log(e);
                }


      };

      reader.readAsText(outputFile);
        //

    }); 

} 

}


WriteDatatoTemp();

}

 ///


    var getFileBlob = function (url, cb) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.responseType = "blob";
    xhr.addEventListener('load', function() {
        cb(xhr.response);
    });
    xhr.send();
   };

    var blobToFile = function (blob, name) {
    blob.lastModifiedDate = new Date();
    blob.name = name;
    return blob;
    };

   var getFileObject = function(filePathOrUrl, cb) {
   getFileBlob(filePathOrUrl, function (blob) {
      cb(blobToFile(blob, 'vid.webm'));
   });
   };


    </script>

1 个答案:

答案 0 :(得分:0)

SourceBuffer.appendBufferAsync()是返回Promise实例的函数。

您可以将await与as一起使用,以允许附加过程结束其工作。由于出现错误,是因为在追加过程结束之前调用了另一个appendBuffer()

但是不幸的是,此过程仅在少数浏览器中可用(并且Chrome DESKTOP不是其中之一):-appendBufferAsync mdn

在Firefox上,您可以将其与media.mediasource.experimental.enabled = true

一起使用

此解决方案Kida在嵌入Flutter App的音乐应用中与我合作,因为在这里我可以确保系统在Chrome移动版上运行。

如果您找到了可靠的解决方案,请更新,我了解我的解决方案不适合生产

在视频流中,我做了类似的操作,就像您在评论中提到的那样,但是我添加了2个视频元素,而其中一个的ObjectURL正在准备播放,另一个正在播放,反之亦然。为了防止黑屏,我只是将视频流的片段绘制到画布上,在每次流转换过程中,音频中特别明显的延迟仍然很少,但是与仅用一个视频所能做的相比,平滑得多元素。

不幸的是,即使有十多年了,MediaSource上也没有令人满意的文档。