MediaSource refuses to play additional segments

I’m trying to build a simple video player base on MediaSource. I’ve got it working playing the first segment. However, as soon as I append the next segment playback stops.

Any ideas what I might be doing wrong? I’m not getting any errors anywhere.

Here is the javascript:

/* eslint-disable */

var videoElement = document.querySelector('video')

var mediaSource = new window.MediaSource()
var videoSource = null
var url = URL.createObjectURL(mediaSource)

videoElement.pause()
videoElement.src = url

function setupVideo(cb) {
  mediaSource.addEventListener('sourceopen', function() {
    videoSource = mediaSource.addSourceBuffer('video/webm;codecs="vp8"')

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

    cb(null, videoSource)
  }, false)
}

function loadHeader(cb) {
  loadBuffer('/test.hdr', cb)
}

function loadSegment(idx, cb) {
  loadBuffer('/test-' + idx + '.chk', cb)
}

setupVideo(function(err) {
  loadHeader(function(err, header) {

    videoSource.appendBuffer(header)

    loadSegment(0, function(err, segment) {
      console.log(0, err)
      videoSource.appendBuffer(segment)
      // Works if I remove the following:
      loadSegment(1, function(err, segment) {
        console.log(1, err)
        videoSource.appendBuffer(segment)
      })
    })
  })
})


function loadBuffer(url, cb) {
  ajax({
    url: url,
    responseType: 'arraybuffer'
  }, function(err, data) {
    if (err) {
      return cb(err)
    } else {
      cb(null, new Uint8Array(data))
    }
  })
}

function ajax(params, callback) {
  var url = params.url
  var responseType = params.responseType
  var xhr = new XMLHttpRequest()
  xhr.open('GET', url)
  xhr.send()
  xhr.responseType = responseType
  try {
    xhr.addEventListener('readystatechange', function() {
      if (xhr.readyState === xhr.DONE) {
        callback(null, xhr.response)
      }
    })
  } catch (err) {
    callback(err)
  }
}

And here is how I generate the source files:

ffmpeg -i media/test.mov -map 0:0 -vcodec libvpx -f webm_chunk -header public/test.hdr  public/test-%d.chk


Source: html5

Leave a Reply