-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to make same sound initiate multiple times (overlap) on user input? #51
Comments
Hi @rifkegribenes, I put together a quick example of the way I'd probably do overlapping sounds with a single ReactHowler instance. The trick is to call the howler method play() (vs. the ReactHowler method). In my example I'm keeping track of the IDs so I can stop each one individually. If you don't need to do that you could simplify the example even more. import React from 'react'
import ReactHowler from 'ReactHowler'
class OverlappingSound extends React.Component {
constructor (props) {
super(props)
this.state = {
playing: false,
soundIds: []
}
this.handlePlay = this.handlePlay.bind(this)
this.handleStop = this.handleStop.bind(this)
this.handleStopOldest = this.handleStopOldest.bind(this)
this.sound = null
}
handlePlay () {
// Calling sound.howler.play() here calls play() on the Howl object itself
// without an ID which creates a new sound (i.e. overlap) and return an ID
const newId = this.sound.howler.play()
// console.log("New ID:", id)
this.setState({
playing: true,
soundIds: [...this.state.soundIds, newId]
})
}
handleStop () {
// Calling sound.stop() (with no id) will stop all sounds
this.sound.stop()
}
handleStopOldest () {
// If you want to stop an individual sound you need to keep track
// of each ID returned from this.sound.howler.play()
// and stop a specific ID
this.sound.stop(this.state.soundIds[0]);
const newSoundIds = this.state.soundIds.slice(1);
this.setState({
soundIds: newSoundIds,
playing: newSoundIds.length > 0
})
}
render () {
return (
<div>
<ReactHowler
src={['sound.ogg', 'sound.mp3']}
playing={this.state.playing}
ref={node => this.sound = node}
/>
<button onClick={this.handlePlay}>Play</button>
<button onClick={this.handleStop}>Stop All</button>
<button onClick={this.handleStopOldest}>Stop Oldest</button>
</div>
)
}
}
export default OverlappingSound |
I'm going to close this off. Please reopen if more discussion is needed. |
I'm preloading all my sounds by mapping over an manifest of sound urls and rendering a
<Howler />
for each one, setting thesrc
for each component from the manifest. I'm setting theplaying
prop asthis.state.playing.includes(sound.id)
, so that I can have more than one sound playing at a time. When user input triggersplaySound()
I'm pushing that sound'sid
into theplaying
array and callingsetState()
. Then I added anonEnd()
method to remove the sound from the array when it's finished playing.This is all working fine except that there is one sound that I want to be able to overlap -- start playing a new instance of it before the last one has finished, if the user triggers it while another instance is still playing. That doesn't seem to be possible the way I have this set up. Is there a way to do what I'm describing? Overlapping sounds were working fine when I was just calling
.play()
on each sound as it was triggered, but I was trying outreact-howler
because I wanted to preload everything ahead of time.The text was updated successfully, but these errors were encountered: