Howler.js: Stop() doesn't stop sounds that are currently loading

Created on 26 Oct 2016  Â·  17Comments  Â·  Source: goldfire/howler.js

My current setup is as such, users click on a song and the following happens

  • Stops previous song
  • Loads the new song
  • Plays new song

So imagine we have two songs, Song A and Song B

If user clicks on Song A and before it has finished loading they click on Song B. The stop() method will not interrupt Song A's loading. And they play over each other.

My solution so far has been to use unload() but these clears the cache which isn't desirable.

Most helpful comment

All 17 comments

Can you provide a test case? Are these different sounds each in their own Howl or in separate Howls? If they are in the same, are you passing the id to stop?

Ok, I think I figured it out and its not Howlers fault but my own instead.

Is it possible to add a global stop function? Similar to how unload works currently but without the cache clearing part.

You can stop a group by calling .stop() with no parameters. Do you mean a global stop like Howler.stop()?

Yes a global stop

One that would stop all audio and loading of audio

The only way to stop loading of audio with HTML5 Audio is to unload it. Web Audio won't be in a state to stop until it has fully loaded. Is the motivation for this more about the loading or stopping of the sound?

Both really. Currently unload() is doing the job but it is clearing the cache.

I'm using howler as a music application. If the user skips a bunch of songs, I don't want them all to load

So maybe an option to unload without clearing the cache makes sense?

Ya. Just cancel current connections and stop all playing sounds but leave cache alone

Any progress on this @goldfire ?

Many thanks, great library!

Having a global "Stop" function i.e. Howler.stop() would be very useful.

What I need is to stop any of several dozen sound effects before playing a new sound (for instance, a speech fragment). This is in the context of a game. If I could define a group "effects" and add all the sound effects to that group - this could be helpful.

However, it seems that "group" refers to a set of sound instances that all have the same source URL and therefore, all have the same audio content. I admit I don't see a lot of need for this type of sound group.

Simply having a global "stop" function would be perfect for this purpose.

I'm reading the examples and the docs and I'm not able to stop all sounds before play a new one.

Looking some code extracted from the radio example: it looks pretty simple, just using .stop() on any instance of Howl.

    play: function(index) {
        var self = this;
        var sound;
        index = typeof index === 'number' ? index : self.index;
        var data = self.stations[index];
        if (data.howl) {
            sound = data.howl;
        } else {
            sound = data.howl = new Howl({
                src: data.src,
                html5: true,
                format: ['mp3', 'aac']
            });
        }
        sound.play();
        self.toggleStationDisplay(index, true);
        self.index = index;
    },
    stop: function() {
        var self = this;
        var sound = self.stations[self.index].howl;
        self.toggleStationDisplay(self.index, false);
        if (sound) {
            sound.stop();
        }
    },

But I must miss something because I can't make it work. Please help @goldfire :)

Here is my file. I have tried both .stop() and .stop(playingID) without success.

import { Howl } from 'howler'

let playingID

function audioPlayer({ src, autoPlay = false, onEnd = () => {}, onPlay = () => {} }) {
  const audio = new Howl({
    src: [src],
    autoplay: false,
    loop: false,
    volume: 0.5,
    onend: onEnd,
    onplay: onPlay,
    html5: true,
  })

  function play() {
    playingID = audio.play()
  }

  function playAlone() {
    audio.stop(playingID)
    playingID = audio.play()
  }

  if (autoPlay) playAlone()

  return {
    playAlone,
    play,
  }
}

export default audioPlayer

playingID.stop();

-----Original Message-----
From: Miguel San Segundo notifications@github.com
To: goldfire/howler.js howler.js@noreply.github.com
Cc: Marty Hirsch mchesspro@aol.com; Comment comment@noreply.github.com
Sent: Thu, Jun 29, 2017 12:45 am
Subject: Re: [goldfire/howler.js] Stop() doesn't stop sounds that are currently loading (#641)

Here is my file. I have tried both .stop() and .stop(playingID) without success.

let playingID

function audioPlayer({ src, autoPlay = false, onEnd = () => {}, onPlay = () => {} }) {
const audio = new Howl({
src: [src],
autoplay: false,
loop: false,
volume: 0.5,
onend: onEnd,
onplay: onPlay,
html5: true,
})

function play() {
playingID = audio.play()
}

function playAlone() {
audio.stop(playingID)
playingID = audio.play()
}

if (autoPlay) playAlone()

return {
playAlone,
play,
}
}

export default audioPlayer```

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

Thanks @martonic but playingID is just the ID not the sound instance. Finally I have fixed my issue keeping in memory my last instance played because I only need a sound at once.

import { Howl } from 'howler'

let lastAudio

function audioPlayer({
  src,
  onStop = () => {},
  onLoad = () => {},
  onEnd = () => {},
  onPlay = () => {},
}) {
  const audio = new Howl({
    src: [src],
    autoplay: false,
    loop: false,
    volume: 0.5,
    onend: onEnd,
    onstop: onStop,
    onplay: onPlay,
    onload: onLoad,
    html5: true,
  })

  function stopLastAudio() {
    if (!lastAudio) return
    lastAudio.stop()
  }

  function playAlone() {
    stopLastAudio()
    audio.play()
    lastAudio = audio
  }

  return {
    playAlone,
  }
}

export default audioPlayer

yes, that looks good

-----Original Message-----
From: Miguel San Segundo notifications@github.com
To: goldfire/howler.js howler.js@noreply.github.com
Cc: Marty Hirsch mchesspro@aol.com; Mention mention@noreply.github.com
Sent: Thu, Jun 29, 2017 12:27 pm
Subject: Re: [goldfire/howler.js] Stop() doesn't stop sounds that are currently loading (#641)

Thanks @martonic but playingID is just the ID not the sound instance. Finally I have fixed my issue keeping in memory my last instance played because I only need a sound at once.
import { Howl } from 'howler'

let lastAudio

function audioPlayer({
src,
onStop = () => {},
onLoad = () => {},
onEnd = () => {},
onPlay = () => {},
}) {
const audio = new Howl({
src: [src],
autoplay: false,
loop: false,
volume: 0.5,
onend: onEnd,
onstop: onStop,
onplay: onPlay,
onload: onLoad,
html5: true,
})

function stopLastAudio() {
if (!lastAudio) return
lastAudio.stop()
}

function playAlone() {
stopLastAudio()
audio.play()
lastAudio = audio
}

return {
playAlone,
}
}

export default audioPlayer

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

Hello. Anything new on this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sibelius picture sibelius  Â·  3Comments

joshbruce picture joshbruce  Â·  4Comments

proyb6 picture proyb6  Â·  4Comments

FFankias picture FFankias  Â·  3Comments

indexofrefraction picture indexofrefraction  Â·  4Comments