Skip to content

etherapis/webmcoder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Background

The Media Source Extension (MSE) is a W3C specification that allows JavaScript to send byte streams to media codecs within web browsers that support HTML5 video. This allows the implementation of client-side prefetching and buffering code for streaming media entirely in JavaScript. ~Wikipedia

To formulate it more clearly, MSE is a way to generate a video stream programatically from JavaScript within a browser. This is an essential feature when the data source behind a video stream is not a simple flat file that the browser can pull from a web server (e.g. multiple sources, AJAX queries, etc).

WebMCoder

Unfortunately, the MSE is experimental at best, each major browser having various issues with assembling and playing chunked streams of video data. These include limited video/audio codec support, the need for specialized stream segmentation, half baked implementations requiring various hacks to work around.

WebMCoder is a tiny tool to solve the painful problem of converting a video file into a format suitable for streaming through the MSE. It should be able to convert most input media streams into the open standard WebM format in a suitable way for streaming via the media source extensions.

Installation and usage

WebMCoder is a Go tool using Docker images. These must be installed prior to being able to use the encoder.

Installing the Go wrapper can be done via:

$ go get github.com/etherapis/webmcoder

Usage

In its crudest form, WebMCoder can be invoked to simply convert an input video file into a MSE suitable output WebM file:

$ webmcoder input.ext output.webm

A few video and audio conversion options are also supported:

  • --achan: Number of audio channels to generate (0 = same as input)
  • --arate: Audio bitrate to encode the output to (0 = same as input)
  • --vrate: Video bitrate to encode the output to (0 = same as input)
  • --vres: Video resolution (WxH) to encode the output to (empty = same as input)

A full command to recode the Elephants Dream movie for streaming via media source extensions with a bit of reprocessing (mono audio, 640 x 360 video resolution, 674 kbit/s video bitrate) would be:

Note, the Elephants Dream HD is a 815MB download!

$ curl -L -O http://video.blendertestbuilds.de/download.blender.org/ED/ED_HD.avi
$ webmcoder --achan=1 --vres=640x360 --vrate=691200 ./ED_HD.avi ./elephants-dream.webm

... Approximately 10 mins later ...

$ ls -al
-rw-r-----  1 karalabe karalabe 854537054 Feb  7 18:00 ED_HD.avi
-rw-r--r--  1 karalabe karalabe 60962855 Feb  7 18:10 elephants-dream.webm

Embedding

Just to provide a rough sketch on how to embed the above generated media stream into a webpage, first an HTML5 video element is needed.

<video id="videosink" width="640" height="360" controls>
  <source src="" type="video/webm">Your browser does not support the video tag.
</video>

After which we need to retrieve our video stream chunks from some arbitrary data source, and assemble them into a MediaSource element. Please note, the below code is only pseudocode highlighting the stream parts, the rest is up to the user to implement.

// Create a new media source to fill with the video stream
var player = document.getElementById("videosink");
var source = new MediaSource;

source.addEventListener('sourceopen', function() {
  // Media source ready, create a video buffer and an async queue to fill with data
  var queue  = [];

  var buffer = source.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
  buffer.addEventListener('updateend', function() {
    if (queue.length > 0) {
      buffer.appendBuffer(queue.shift());
    }
  }, false);

  // Start downloading the video stream, inserting either into the queue or the buffer
  while (!complete) {
    var chunk = downloadNextChunk();

    // Queue up the next chunk or insert directly
    if (queue.length > 0 || buffer.updating) {
      queue.push(data);
    } else {
      buffer.appendBuffer(data);
    }
  }
});

// Initialize the video player with the chunked stream source
player.src = URL.createObjectURL(source);

Credits

The conversion tool is based on:

  • Docker: containerizing the tool dependencies
  • FFmpeg: converting the data streams to WebM
  • mse-tools: prepping WebM files for streaming

License

WebMCoder is licensed under the BSD 3-Clause License. For details please consult the LICENSE file contained within the repository root.

About

Media Source Extension WebM streaming encoder

Resources

License

Stars

Watchers

Forks

Packages

No packages published