Skip to content

Latest commit

 

History

History
161 lines (129 loc) · 4.44 KB

CUSTOM_CONNECTIONS.md

File metadata and controls

161 lines (129 loc) · 4.44 KB

Writing Your Own Hifi Connection

Do you need to support a funky audio format that requires a special library, or do you really want to buck this whole HTML5-only strategy and play sounds using Flash? You can make your own hifi connection.

$ ember generate hifi-connection flash-connection

This creates app/hifi-connections/flash-connection.js and a unit test at tests/unit/hifi-connections/flash-connection.js, which you should now customize.

The files created by the blueprint should walk you through what you need to implement, but to be thorough:

  let ClassMethods = Ember.Mixin.create({
    setup() {
      // Do any global setup needed for your third party library.
    },

    canPlayMimeType(/* extension */) {
      // check if connection can play file with this mime type
      return true;
    },

    canUseConnection() {
      // check to see if this connection will work on this browser/platform
      return true;
    }
  });

canPlayMimeType and canUseConnection are called when hifi is looking for connections to try with a url. Give your best guess here. For instance, our built-in HLS.js library won't work on mobile, so canUseConnection returns false on a mobile device and true on a desktop browser. Similary, HLS only plays application/vnd.apple.mpegurl files, so we just check for that extension in canPlayMimeType.

Implement methods to bridge communication between hifi and your third party sound.
  • setup() Wire up your library to trigger the following methods when things happen on your sound:

Required events to be implemented:

  • sound.trigger('audio-ready') - sound is ready to play
  • sound.trigger('audio-load-error', error) - loading sound failed
  • sound.trigger('audio-played')
  • sound.trigger('audio-paused')
  • sound.trigger('audio-ended') - we finished playing the sound

Optional (but nice to have) events:

  • sound.trigger('audio-position-changed') - when the playhead position changes
  • sound.trigger('audio-loading', {percentLoaded: percent}) - when sound is downloading, update the percentLoaded
import flashLibrary from 'your-third-party-library'

let Sound = BaseSound.extend({
  setup() {
    let url   = this.get('url');
    let sound = this;

    let flashSound = new flashLibrary({
      url: url,
      onready: function() {
        // Sound is loaded and ready to go.
        sound.trigger("audio-ready")
      },
      onloaderror: function(error) {
        // Couldn't load this sound. Tell hifi to move on and try another url/connection
        sound.trigger('audio-load-error', error);
      },
      onpause: function() {
        sound.trigger('audio-paused', sound);
      },
      onplay: function() {
        sound.trigger('audio-played', sound);
      },
      onend: function() {
        sound.trigger('audio-ended', sound);
      },
      onseek: function() {
        sound.trigger('audio-position-changed');
      },
      onloading: function(percentLoaded) {
        sound.trigger('audio-loading', {percentLoaded: percentLoaded});
      }
    })

    this.set('flashSound', flashSound);
  }
  • teardown
  // clean up after yourself
  teardown() {
    this.get('flashSound').destroy();
  }

Other required methods to let hifi control your sound

_setVolume(volume) {
  this.get('flashSound').volume(volume);
},

_audioDuration() { // in ms
  // return Infinity if source is an audio stream
  if (this.get('flashSound').isStreaming()) {
    return Infinity
  }
  else {
    return this.get('flashSound').duration    
  }
},

_currentPosition() { // in ms
  return this.get('flashSound').position
},

_setPosition(pos) { // in ms
  return this.get('flashSound').setPosition(pos)
},

play() {
  this.get('flashSound').play();
},

pause() {
  this.get('flashSound').pause();
},

stop() {
  // Stop playback and make sure no more audio is downloading
  this.get('flashSound').stopDownload();
  this.get('flashSound').stop();
}

Usage

Once you have implemented your new connection, you can add it to your app's configuration, like so:

module.exports = function(environment) {
  var ENV = {
    emberHifi:
      debug: true,    // get ready for some deep console messages to help you find your way
      connections: [
        {
          name: 'FlashConnection',
          config: {
            options: { // these options get passed into your class-level setup
              foo: 'bar'
            }
          }
        }
      ]
    }
  }