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
.
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 playsound.trigger('audio-load-error', error)
- loading sound failedsound.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 changessound.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();
}
_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();
}
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'
}
}
}
]
}
}