How to create a live video player on the web

For showing a Bambuser broadcast in a web app you have two options:

Iframe embed

The easiest way to embed Bambuser content is using an iframe, with a signed resourceUri in the url. The controls in the iframe embed have been designed by us and cannot be changed by your application. If you want to use the browser's built-in controls for <video> elements, check out the Javascript player below.


  style="border: none"


The iframe embed supports various options, provided via url parameters (appended to the URL, separated by an ampersand &):

name type description
autoplay boolean Start playing immediately after the page has loaded. Note: will not work in all browsers.
volume number Set default volume to a value between 0 and 1.
muted boolean Set to 1 to mute the player.
noFullscreen boolean Disallow the player from going fullscreen.
broadcastState string Allow playback only if the broadcast is in a specific state; either live or archived.


A full-width player with a 16:9 aspect-ratio

<div style="width: 100%; padding-bottom: 56.25%; position: relative">
    style="position: absolute; width: 100%; height: 100%; border: none"

Listening to player events

While the page that embeds the iframe player does not have direct access to the player's internal state, some events are dispatched to the parent page. These events are sent from the iframe to the parent page using Window.postMessage().

This allows a page using the iframe player to react to events emitted by the internal video element and keep itself up to date with what is going on inside the black box.


window.addEventListener('message', function(event) {
  if (event.origin !== '') {
    // Don't trust messages from other origins
  var videoEvent =;
  if (videoEvent) {
    console.log('video event:',;
}, false);

JavaScript player

The JavaScript API lets you embed a player and control the player using Javascript. This is the ideal option if you want to build your own UI.

Getting started

Load the bambuser-video-iframeapi.min.js library and initialize a player instance by calling BambuserPlayer.create(<target element>, <resourceUri>). The returned object behaves much like an HTML5 <video> element, exposing a similar API and similar events.

Import the javascript and prepare an HTML element where you want to render the BambuserPlayer:

<script src=""></script>
<div id="player"></div>

When creating the BambuserPlayer, pass it the target HTML element, a signed resourceUri and optional parameters.


var resourceUri = '';

var player = BambuserPlayer.create(document.getElementById('player'), resourceUri, {
  noFullscreen: true // Do not allow fullscreen

// Listen to player events
player.addEventListener('pause', function() {
  console.log('player paused');
player.addEventListener('timeupdate', function() {
  console.log('current time', player.currentTime);

 * Controlling the player programmatically

// Hide the UI provided by the native player (see the note below regarding iDevices).
player.controls = false;

// Seek a few minutes into the video.
player.currentTime = 300;

// Start the video immediately.;
// NOTE: Setting player.autoplay=true would have the same effect.
// However, calling play() or setting player.autoplay=true will not
// work on many handheld devices (see the note below).

// Make the video play/pause when the user clicks on the container div.
document.getElementById('player').addEventListener('click', function() {
  return player.paused ? : player.pause();
// NOTE: on many handheld devices play() will only work when called
// inside an event handler for a user gesture (like we did here).

// NOTE: iDevices insist on us using their own controls and will not let
// us start playback using the play() method, even when called from an event
// handler as described above.
if (navigator.userAgent.match(/iPad|iPhone|iPod/) && !window.MSStream) {
  player.controls = true;


A note regarding iOS devices. Being able to start playback programmatically, either using play() or the autoplay property works poorly on iPhones, iPads and iPods. While recent versions of iOS does honor the play() method and autoplayproperty under certain circumstances (read more here), it does not seem to do so when the target video element exists inside an iframe.


The BambuserPlayer.create() function takes an optional third argument with an object containing additional options.

name type description
noFullscreen boolean Disables fullscreen
timeshift boolean Enables seeking in live broadcasts, but disables low-latency viewing. It is recommended to enable timeshifting only when necessary, as it involves higher latency, and playback performance may suffer on very long broadcasts.

Object methods

  • play()
  • pause()
  • addEventListener()
  • removeEventListener()

Object properties

Supported HTML5 video properties: autoplay, buffered controls, currentTime, duration, ended, error, paused, poster, seeking, volume

Custom properties

name type description
isLive boolean Tells whether the broadcast is live rather than viewed on-demand.
viewers object Shows the number of current and total viewers on the broadcast (see example below).
timeshift boolean Get/set the current timeshift configuration. This property is settable only if timeshift mode has been enabled through the player constructor. Switching it off will essentially seek to the end. This property will not switch to low-latency mode. For low-latency mode, a new player must be constructed without timeshift-mode.
scaleMode string Get/set the current scale-mode to one of: aspectFill, aspectFit, fill (see descriptions below).

Example value of the viewers property

  "current": 1,
  "total": 10

Scale modes

name description
aspectFill Preserve the video's aspect ratio and fill the player's bounds.
aspectFit Preserve the video's aspect ratio and fit the video within the player's bounds.
fill Stretch the video to fill the player's bounds.


Supported HTML5 video events: canplay, durationchange, ended, error, loadedmetadata, pause, play, playing, progress, seeked, seeking, timeupdate, volumechange, waiting