Skip to content

Instantly share code, notes, and snippets.

@dmlap
Last active August 29, 2015 14:13
Show Gist options
  • Save dmlap/b70dbdbcaccc6707c531 to your computer and use it in GitHub Desktop.
Save dmlap/b70dbdbcaccc6707c531 to your computer and use it in GitHub Desktop.
Media Playlists

Media Playlists

Goals

  1. Single video plugins are compatible without needing to be playlist-aware
  2. Playlist events provide a consistent and predictable lifecycle for upstream developers

API

// load a playlist into a player
player.playlist([{
  sources: [firstMp4, firstOgv],
  poster: '//example.com/poster.jpg'
}, {
  sources: [secondMp4, secondOgv],
  textTracks: [{
    kind: 'captions'
    language: 'en'
  }]
}]);

// the current item is available
console.assert(player.playlist.item() === 0);
player.playlist.item(7); // change the current item to 7
console.assert(player.playlist[player.playlist.item()].indexOf(player.currentSrc()) >= 0);
console.log(player.playlist[1]); // the media object for playlist item 1
console.log(player.playlist.length); // print the number of items in the playlist

// playlist capabilities
// advance to the next media item in the playlist
player.playlist.next();
// return to the previous media item in the playlist
player.playlist.previous();
// advance to the next media item in the playlist as soon as the current item ends
player.playlist.autoadvance(0);
// advance to the next media item in the playlist 15 seconds after the current item ends
player.playlist.autoadvance(15);
// cancel auto-advance behavior
player.playlist.autoadvance(null);

// when the ended event fires for the last video in a playlist, playlistended fires
player.on('playlistended', function() {
  alert("We're all out of videos! Check back soon.");
});

Autoadvance

Autoadvance is off by default. If autoadvance is set to a negative number, an error is thrown. If autoadvance is set to zero, the next playlist item will be automatically loaded and begin playback when the ended event fires for the current item. If autoadvance is set to a number greater than zero, advancing the playlist and playing the next item will be delayed the specified number of seconds after the ended event. During the period between the firing of the ended event and advancing to the next playlist item, autoadvance behavior can be cancelled by calling the autoadvance method with any argument.

Ads Enhancements

One of the primary challenges with developing a playlist plugin is interacting safely with ad libraries. To simplify this process, we will prefix player events that happend during ad playback. This will ensure that plugins that do not wish to be aware of ads will see an event stream that is consistent with single video playback while still providing the notification to developers who need it.

The ended event will require special handling. It is not always possible for an ad integration to know before ended that a postroll is available and configured. That means contrib-ads may not be able to make the decision to bubble the ended event synchronously. We propose adding another timeout to the end of video playback and delaying the ended event until:

  • the ad integration has played a postroll and called endLinearAdMode()
  • the ad integration has indicated there is no postroll
  • the postroll timeout has expired

After these changes, the playlist plugin can treat playback with and without ads identically and use standard HTML5 video events to manage its state.

Timeline

Playlists should allow the creation of players that include:

  1. Zero or more pre-content segments. This can include advertisements, start slates, or bumpers for instance.
  2. A content video with zero or more interstitial segments. A mid-roll advertisement is an example of an interstitial segment.
  3. Zero or more post-content segments. Post-roll advertisements and end-slates are examples.
  4. An optional autoadvance delay.

Ad Timeline

Representation

Playlists will be accessible through a Javascript API. There will be no DOM representation.

VideoJS Playlist Plugins

@pcting
Copy link

pcting commented Feb 26, 2015

@dmlap, is there working code for this playlist proposal already? i'm in the middle of implementing a playlist plugin on a heavily modified a forked of videojs-playLists. i'm hoping to conform to this spec.

with regards to @mboles point #1, maybe a new property "loop" can be introduced for toggling between wrapping to the start/end of the playlist:

var nextIndex_ = function(i, len) {
  return Math.min(len - 1, i + 1);
};

var loopNextIndex_ = function(i, len) {
  if (i >= len - 1) {
    return 0;
  } else {
    return nextIndex_(i, len);
  }
};

var previousIndex_ = function(i, len) {
  return Math.max(0, i - 1);
};

var loopPreviousIndex_ = function(i, len) {
  if (i <= 0) {
    return len - 1;
  } else {
    return previousIndex_(i, len);
  }
};

player.playlist.next = function() {
  var func = options.loop ? loopNextIndex_ : nextIndex_;
  setItem_(func(options.index, options.items.length));
  player.trigger('next');
};

player.playlist.previous = function() {
  var func = options.loop ? loopPreviousIndex_ : previousIndex_;
  setItem_(func(options.index, options.items.length));
  player.trigger('previous');
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment