2

Ich möchte Webm abspielen, dessen Dauer> 5s (1,32 Min.) Ist. this webm.Fehler beim Versuch, webm mit MSE abzuspielen, Chunks nicht anhängend, Video stopp

I'have versucht, diesem Beispiel zu ändern, wenn ich es laufen, Chunks nicht anhängen und Video stoppt an einem gewissen Punkt, und ich bekomme diese Fehlermeldung:

InvalidStateError: Es wurde versucht, zu verwenden, ein Objekt, das nicht oder nicht mehr verwendbar ist sourceBuffer.appendBuffer (neues Uint8Array (e.target.result));

Könnte jemand bitte klären?

<script> 
    var FILE = 'test2.webm'; //that webm 
    var NUM_CHUNKS = 10; 
    var video = document.querySelector('video'); 

    window.MediaSource = window.MediaSource || window.WebKitMediaSource; 
    if (!!!window.MediaSource) { 
     alert('MediaSource API is not available'); 
    } 

    var mediaSource = new MediaSource(); 

    //document.querySelector('[data-num-chunks]').textContent = NUM_CHUNKS; 

    video.src = window.URL.createObjectURL(mediaSource); 

    function callback(e) { 
     var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"'); 

     logger.log('mediaSource readyState: ' + this.readyState); 

     GET(FILE, function(uInt8Array) { 
      var file = new Blob([uInt8Array], { 
       type: 'video/webm' 
      }); 
      var chunkSize = Math.ceil(file.size/NUM_CHUNKS); 

      logger.log('num chunks:' + NUM_CHUNKS); 
      logger.log('chunkSize:' + chunkSize + ', totalSize:' + file.size); 

      // Slice the video into NUM_CHUNKS and append each to the media element. 
      var i = 0; 
      (function readChunk_(i) { 
       var reader = new FileReader(); 

       // Reads aren't guaranteed to finish in the same order they're started in, 
       // so we need to read + append the next chunk after the previous reader 
       // is done (onload is fired). 
       reader.onload = function(e) { 
        sourceBuffer.appendBuffer(new Uint8Array(e.target.result)); 
        logger.log('appending chunk:' + i); 
        if (i == NUM_CHUNKS - 1) { 
         mediaSource.endOfStream(); 
        } else { 
         if (video.paused) { 
          video.play(); // Start playing after 1st chunk is appended. 
         } 
         readChunk_(++i); 
        } 
       }; 

       var startByte = chunkSize * i; 
       var chunk = file.slice(startByte, startByte + chunkSize); 

       reader.readAsArrayBuffer(chunk); 
      })(i); // Start the recursive call by self calling. 
     }); 
    } 

    mediaSource.addEventListener('sourceopen', callback, false); 
    mediaSource.addEventListener('webkitsourceopen', callback, false); 

    mediaSource.addEventListener('webkitsourceended', function(e) { 
     logger.log('mediaSource readyState: ' + this.readyState); 
    }, false); 

    function GET(url, callback) { 
     var xhr = new XMLHttpRequest(); 
     xhr.open('GET', url, true); 
     xhr.responseType = 'arraybuffer'; 
     xhr.send(); 

     xhr.onload = function(e) { 
      if (xhr.status != 200) { 
       alert("Unexpected status code " + xhr.status + " for " + url); 
       return false; 
      } 
      callback(new Uint8Array(xhr.response)); 
     }; 
    } 
</script> 
<script> 
    function Logger(id) { 
     this.el = document.getElementById('log'); 
    } 
    Logger.prototype.log = function(msg) { 
     var fragment = document.createDocumentFragment(); 
     fragment.appendChild(document.createTextNode(msg)); 
     fragment.appendChild(document.createElement('br')); 
     this.el.appendChild(fragment); 
    }; 

    Logger.prototype.clear = function() { 
     this.el.textContent = ''; 
    }; 

    var logger = new Logger('log'); 
</script> 
<script> 
    var _gaq = _gaq || []; 
    _gaq.push(['_setAccount', 'UA-22014378-1']); 
    _gaq.push(['_trackPageview']); 

    (function() { 
     var ga = document.createElement('script'); 
     ga.type = 'text/javascript'; 
     ga.async = true; 
     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
     var s = document.getElementsByTagName('script')[0]; 
     s.parentNode.insertBefore(ga, s); 
    })(); 
</script> 

Antwort

1

Ihr Video funktioniert gut in meinem Player basierend auf dem von Ihnen bereitgestellten Beispiel. Ich rufe mediaSource.endOfStream() nicht auf; und ich schneide keine Datei mit der FileReader-Klasse (unbrauchbar).

Verwenden Sie Range-HTTP-Header, um direkt von Ihrem Webserver Segmente zu erhalten.

Beispiel:

function GET(url, from = 0, to = '') { 
    return new Promise((accept, reject) => { 
     var xhr = new XMLHttpRequest(); 
     xhr.open('GET', url, true); 
     xhr.responseType = 'arraybuffer'; 
     xhr.setRequestHeader("Range", `bytes=${from}-${to}`); 
     xhr.send(); 

     xhr.onload = function(e) { 
      if (xhr.status != 200 && xhr.status != 206) { 
       alert("Unexpected status code " + xhr.status + " for " + url); 
       reject(e); 
      } 
      accept(xhr.response); 
     }; 
    }); 
}