web-dev-qa-db-fra.com

Erreur MediaSource: ce SourceBuffer a été supprimé de la source de média parent

J'expérimente avec la nouvelle API MediaSource disponible dans Chrome.

J'essaie d'ajouter des données binaires à la volée d'un WebSocket à la source multimédia vidéo.

En commençant par l'exemple à https://html5-demos.appspot.com/static/media-source.html , mon code est actuellement:

var websocket = new WebSocket('ws://localhost:8080');
websocket.binaryType = 'arraybuffer';

var mediaSource = new MediaSource();
var buffer;
var queue = [];

var video = $('.video')[0];
video.src = window.URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen', function(e) {
  video.play();

  buffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.64001E"');

  buffer.addEventListener('updatestart', function(e) { console.log('updatestart: ' + mediaSource.readyState); });
  buffer.addEventListener('update', function(e) { console.log('update: ' + mediaSource.readyState); });
  buffer.addEventListener('updateend', function(e) { console.log('updateend: ' + mediaSource.readyState); });
  buffer.addEventListener('error', function(e) { console.log('error: ' + mediaSource.readyState); });
  buffer.addEventListener('abort', function(e) { console.log('abort: ' + mediaSource.readyState); });

  buffer.addEventListener('update', function() { // Note: Have tried 'updateend'
    if (queue.length > 0 && !buffer.updating) {
      buffer.appendBuffer(queue.shift());
    }
  });
}, false);

mediaSource.addEventListener('sourceopen', function(e) { console.log('sourceopen: ' + mediaSource.readyState); });
mediaSource.addEventListener('sourceended', function(e) { console.log('sourceended: ' + mediaSource.readyState); });
mediaSource.addEventListener('sourceclose', function(e) { console.log('sourceclose: ' + mediaSource.readyState); });
mediaSource.addEventListener('error', function(e) { console.log('error: ' + mediaSource.readyState); });

websocket.addEventListener('message', function(e) {
  if (typeof e.data !== 'string') {
    if (buffer.updating || queue.length > 0) {
      queue.Push(e.data);
    } else {
      buffer.appendBuffer(e.data);
    }
  }
}, false);

J'obtiens systématiquement le message d'erreur: InvalidStateError: Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer has been removed from the parent media source. Après un ajout. Il semble que le MediaSource se ferme immédiatement après l'appel à buffer.appendData().

Une façon de le faire avec élégance?

Remarque: chrome: // media-internals/ne renvoie aucune information utile.

27
Chris Nolet

En fin de compte, le problème était que j'envoyais de la vidéo h264 sur le Web. L'API MediaSource ne prend actuellement en charge que MPEG-DASH et VP8 avec des segments d'images clés (sur Chrome 35).

De plus, une fois que j'ai essayé VP8, j'ai vu que j'ajoutais des cadres hors service.

  • L'ajout de if (buffer.updating || queue.length > 0) dans websocket.onmessage Était nécessaire.
  • L'ajout de if (queue.length > 0 && !buffer.updating) dans buffer.addEventListener('update', ...) était également nécessaire.

Remarque: J'ai appliqué les modifications mentionnées ici au code dans la question, donc le seul problème avec le code dans la question est que le codec est incorrect

8
Chris Nolet

Chrome est incroyablement pointilleux en ce qui concerne les codecs SourceBuffer. Pire, il renverra des messages d'erreur inutiles et trompeurs comme dans le cas de l'OP.

Il semble que le MediaSource se ferme immédiatement après l'appel à buffer.appendData()

C'est exactement le cas: Chrome n'est pas satisfait de la vidéo car il n'est pas exactement conforme à ses goûts et ferme simplement le tampon source sans préavis .

Solutions possibles à rechercher:

  1. Transcodez vos fichiers MP4 en utilisant ffmpeg , expliqué ici (titre Fragmentation).
  2. Utilisez mp4file de mp4v2 pour trouver le codec MP4 exact, expliqué ici et ici .
  3. Si vous n'avez pas d'audio, omettez la partie codec audio: par ex. 'video/mp4; codecs="avc1.64001F"' au lieu de 'video/mp4; codecs="avc1.64001F, mp4a.40.2"'.
0
The Conspiracy