/ivy-videojs

A set of Ember components for the video.js HTML5 video player.

Primary LanguageJavaScriptMIT LicenseMIT

ivy-videojs

Latest NPM release TravisCI Build Status

Simple Ember integration for the video.js HTML5 video player.

NOTE: Currently only the HTML5 video tech is supported. The Flash player is broken due to the fact that video.js removes the (Ember-managed) <video> element from the DOM when using anything other than the native HTML5 video tech.

Installation

From the root of your ember-cli application:

ember install ivy-videojs

Usage

Use the ivy-videojs component as you would a video tag, either by passing in the src as a string:

{{ivy-videojs src="/path/to/video.mp4"}}

or binding the src to an object:

{{ivy-videojs src=src}}
import Ember from 'ember';

export default Ember.Controller.extend({
  src: { src: '/path/to/video.mp4', type: 'video/mp4' }
});

or even to an array:

import Ember from 'ember';

export default Ember.Controller.extend({
  src: [
    { src: '/path/to/video.mp4', type: 'video/mp4' },
    { src: '/path/to/video.webm', type: 'video/webm' }
  ]
});

The src can be anything supported by video.js. See the Player API docs for examples.

Responsive Videos

As of video.js 5.0, there is now native support for responsive videos. To use this, set the fluid property to true:

{{ivy-videojs fluid=true src="/path/to/video.mp4"}}

See the Player API docs for more details.

Advanced Usage

If you need more control over the video player, there's also an ivy-videojs-player component that exposes a lower-level interface to the video.js player. This can be useful if, for instance, you're using video.js plugins and need to change the way your application interacts with the video.js player. In fact, the ivy-videojs component is actually just a thin wrapper around the ivy-videojs-player component.

The ivy-videojs-player does not bind any properties, but it does set up event handlers for the following:

  • abort
  • canplay
  • canplaythrough
  • durationchange
  • emptied
  • ended
  • error
  • loadeddata
  • loadedmetadata
  • loadstart
  • pause
  • play
  • playing
  • progress
  • ratechange
  • resize
  • seeked
  • seeking
  • stalled
  • suspend
  • timeupdate
  • useractive
  • userinactive
  • volumechange
  • waiting

Generally if you're using ivy-videojs-player, you'll set up a handler for the "ready" action, and then use that time to configure the player and set up any custom events or property bindings.

The setup Property

If, for some reason, you need to pass in arguments to the initial videojs initialization call, you can do so through a setup property. For instance, if you wanted to enable the playback rate menu, you could pass in setup in your template:

{{ivy-videojs setup=setup}}

And then in your controller, define setup like so:

import Ember from 'ember';

export default Ember.Controller.extend({
  setup: {
    playbackRates: [0.5, 1, 1.5, 2]
  }
});

This is exactly what the demo app does.

Binding Properties

Here's a basic example that binds the "src" attribute:

{{ivy-videojs-player ready="ready" src=src}}
import Ember from 'ember';

export default Ember.Controller.extend({
  src: 'http://vjs.zencdn.net/v/oceans.mp4',

  actions: {
    ready(player, component) {
      // This is pretty much the minimum required for a useful video player.
      component.bindPropertyToPlayer(player, 'src');
    }
  }
});

The above just tells ivy-videojs-player that its "src" property should be bound to the player's "src" property. This is fine if the component property and the player property have the same name, but what if they're different? Not to worry, that's what the optional third argument is for:

{{ivy-videojs-player ready="ready" sources=sources}}
import Ember from 'ember';

export default Ember.Controller.extend({
  sources: 'http://vjs.zencdn.net/v/oceans.mp4',

  actions: {
    ready(player, component) {
      // This will set the player's "src" property based on the component's "sources" property.
      component.bindPropertyToPlayer(player, 'sources', 'src');
    }
  }
});

So in the above example, the "sources" property of the component is bound to the "src" property of the player. You can think of this as essentially calling the following whenever the component's "sources" property changes:

player.src(this.get('sources'));

Handling Events

Much like properties, you can also handle custom player events. To do this, call the component's sendActionOnPlayerEvent method inside your "ready" action handler:

{{ivy-videojs-player ready="ready" tada="tada"}}
import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    ready(player, component) {
      // When a "tada" event is triggered on the player, a corresponding "tada"
      // action will be sent.
      component.sendActionOnPlayerEvent(player, 'tada');
    },

    tada(/* player, component */) {
      // Action handlers are given any arguments passed on from video.js, but
      // the first two arguments are always the video.js player and the
      // component.
    }
  }
});

As above, if the action name differs from the name of the player event, you can pass a third argument to indicate what the event name is:

import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    ready(player, component) {
      // Now, if a "someevent" event is triggered on the player, a "tada"
      // action will be sent.
      component.sendActionOnPlayerEvent(player, 'tada', 'someevent');
    }
  }

Upgrading

See UPGRADING.md

Development

Installation

  • git clone this repository
  • yarn
  • yarn run bower install

Running

Running Tests

  • ember test
  • ember test --server

Building

  • ember build

For more information on using ember-cli, visit http://www.ember-cli.com/.