Skip to content

Commit

Permalink
Add playlist feature
Browse files Browse the repository at this point in the history
  • Loading branch information
GeKorm committed May 20, 2020
1 parent 4ef1c8b commit eb2bb0a
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 15 deletions.
43 changes: 43 additions & 0 deletions README.md
Expand Up @@ -205,6 +205,49 @@ export function addCoinSounds() {
};
}
```
### Callbacks
The Howler callbacks `onplay`, `onstop`, and `onend` are currently supported

```javascript
const winPopup = {
type: 'SHOW_WIN_POPUP',
payload: 'You won'
}

const soundsData = {
randomCoins: {
src: ['https://s3.amazonaws.com/bucketName/coin_collection.mp3'],
sprite: {
one: [0, 1000],
two: [1000, 2500],
three: [3500, 10000]
},
onend: (id, dispatch) => dispatch(winPopup)
}
};
```

### Playlist
It is preferable to have your playlist merged as one continuous sounds. If that's not possible, you can
dispatch a "playlist" action like the example below.

```javascript
/* playlist-action.js */
export function playlistSounds() {
return {
type: 'PLAYLIST_SOUNDS',
meta: {
sound: {
list: [
{ play: 'jumps.lowJump' },
{ play: 'jumps.longJump' },
{ play: 'endTurn' }
]
}
}
};
}
```

## Troubleshooting

Expand Down
55 changes: 40 additions & 15 deletions src/howler_integration.js
Expand Up @@ -6,7 +6,7 @@ module.exports = {
Object.keys(this.playing).forEach((key) => this.playing[key].delete(id));
},

initialize(soundsData) {
initialize(soundsData, dispatch) {
let soundOptions;
// { String: Set[Integer] } Map of currently playing ids for each unique sound name
// Can also use `new Map()`
Expand All @@ -32,16 +32,16 @@ module.exports = {
...memo,
[name]: new Howl({
...soundOptions,
onplay: (id) => {
if (soundOptions.onplay) soundOptions.onplay(id, dispatch);
},
onend: (id) => {
if (soundOptions.onend) {
soundOptions.onend(id);
}
if (soundOptions.onend) soundOptions.onend(id, dispatch);
this.notifyend(id);
this.removeId(id);
},
onstop: (id) => {
if (soundOptions.onstop) {
soundOptions.onstop(id);
}
if (soundOptions.onstop) soundOptions.onstop(id, dispatch);
this.removeId(id);
}
})
Expand All @@ -51,7 +51,7 @@ module.exports = {
return this.sounds;
},

add(soundsData) {
add(soundsData, dispatch) {
if (!isObjectWithValues(this.sounds)) return this.initialize(soundsData);
let soundOptions;
const soundNames = Object.getOwnPropertyNames(soundsData);
Expand All @@ -72,24 +72,30 @@ module.exports = {
} else {
this.playing[name] = new Set();
}
return {
const { onplay, onstop, onend } = soundOptions;
const result = {
...memo,
[name]: new Howl({
...soundOptions,
onplay: (id) => {
if (onplay) onplay(id, dispatch);
},
onend: (id) => {
if (soundOptions.onend) {
soundOptions.onend(id);
}
if (onend) onend(id, dispatch);
this.removeId(id);
if (this.playlistIds[id]) this.playlistIds[id](id);
},
onstop: (id) => {
if (soundOptions.onstop) {
soundOptions.onstop(id);
}
if (onstop) onstop(id);
this.removeId(id);
}
})
};
// Delete to keep the action serializable
delete soundOptions.onplay;
delete soundOptions.onend;
delete soundOptions.onstop;
return result;
}, this.sounds);

return this.sounds;
Expand Down Expand Up @@ -126,6 +132,25 @@ module.exports = {
return id;
},

playlist(queue) {
const playlistId = Math.random().toString().slice(2);
this.playlist[playlistId] = {
index: 0,
queue
};
const player = (prevId) => {
// eslint-disable-next-line no-plusplus
this.playlist[playlistId].index++;
const nextTrack = this.playlist[playlistId].queue[this.playlist[playlistId].index];
const nextId = this.play(nextTrack);
this.playlistIds[nextId] = player;
delete this.playlistIds[prevId];
};

const soundId = this.play(queue[0]);
this.playlistIds[soundId] = player;
},

howlMethod(soundName, spriteName = '', method, ...args) {
const sound = this.sounds[soundName];
if (this.playing[soundName + spriteName]) {
Expand Down
4 changes: 4 additions & 0 deletions src/index.js
Expand Up @@ -21,6 +21,10 @@ function soundsMiddleware(soundsData) {
}
// skip action, no Howls initialized
if (!isObjectWithValues(howlerIntegration.sounds)) return;
if (method === 'playlist') {
howlerIntegration.playlist(target);
return;
}
if (Array.isArray(target)) {
const [soundName, spriteName] = target[0].split('.');
howlerIntegration.proxy(
Expand Down

0 comments on commit eb2bb0a

Please sign in to comment.