最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Append data to a html5 video dynamically - Stack Overflow

programmeradmin1浏览0评论

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));
  };
}

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));
  };
}
Share Improve this question edited Jun 29, 2015 at 13:49 Dimitri Dewaele 10.7k21 gold badges83 silver badges130 bronze badges asked Mar 24, 2015 at 5:34 Jota PeyJota Pey 631 silver badge4 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4

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./static/media-source.html

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

发布评论

评论列表(0)

  1. 暂无评论