Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append data to a html5 video dynamically

Is it possible to append data into a HTML5 video player dynamically? Example:
I have the video A with 30 sec of duration and video B with 30 sec too.
I want to play the video A and 10 seconds before finish append the video B, but the player video length now have to show 1 minute of length.

Edit:

I looked at the example above and modified to append the entire demo video 5 times but doesn´t work. The video result is always 5.24 sec (the original video is 6sec) I want to append the original video 5 times to get a video result of 30sec. It is possible?

This is my code

var FILE = 'files/test.webm';
var NUM_CHUNKS = 15;
var G_VIDEO;
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));
        // here i append the entire video locate in the global var G_VIDEO
        sourceBuffer.appendBuffer(new Uint8Array(G_VIDEO));

        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;
      //here i guess is where the video is truncate
      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;
    }
    G_VIDEO = xhr.response;
    callback(new Uint8Array(xhr.response));
  };
}
like image 393
Jota Pey Avatar asked Sep 29 '22 11:09

Jota Pey


1 Answers

Yes you can definitely add the video source into a HTML5 video element dynamically using the Media Source Extensions mechanism.

This essentially replaces the 'src' file of the video element with a reference to a Javascript function. In the function you dynamically fill in the video element's source buffer.

In this way you can effectively do anything you want to the video before it is played. One of the key drivers for the mechanism is to enable adaptive bit rate streaming - the Javascript function chooses the best bit rate stream to request depending on the bandwidth of your connection, and can switch to a different stream if the connection gets congested or more bandwidth is available.

There is a nice demo of the mechanism here:

  • http://html5-demos.appspot.com/static/media-source.html

Look at it in any browser which support MSE (lasts version of Chrome, Firefox and IE should)

like image 137
Mick Avatar answered Oct 03 '22 11:10

Mick