Skip to content
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

"play" event fired twice in playing a stream #899

Closed
tbessie opened this issue Feb 7, 2018 · 10 comments
Closed

"play" event fired twice in playing a stream #899

tbessie opened this issue Feb 7, 2018 · 10 comments

Comments

@tbessie
Copy link

tbessie commented Feb 7, 2018

I'm using Howler for the first time, as I need to be able to stream audio from a server and have it start playback immediately, even with large sound files.

I've added all of the available event callbacks to monitor what's happening. Here's a simplified version of what I'm doing:

var player = new $wnd.Howl({
    src: url,
    html5: true, // A live stream can only be played through HTML5 Audio.
    format: ['webm', 'opus', 'mp3', 'aac'],
    autoplay: false
    });

player.on('play', function(id) {
       console.log('playing!');
});

player.play();

I get the "playing!" message twice. Is this a known issue?

@jmo84
Copy link

jmo84 commented Feb 7, 2018

Not sure if it's a known issue but I confirmed that setting "autoplay" to false and "html5" to true causes the "play" event to be emitted twice. Browsers that don't support Web Audio will also be affected.

https://jsfiddle.net/q2ydhvxx/

@tbessie
Copy link
Author

tbessie commented Feb 7, 2018

Hmm, jmo84, I tried your jsfiddle page and the music played, but I didn't see the console messages appear. Do I need to click on something else to see them?

@m-przybylski
Copy link

I faced the same issue and spend some time to debug it and it seems to be a bug is code. What you try to do is autoplay. in other words you create Howl object and after that execute play method - no interaction between. What happens in that scenario, howler caches all actions in _queue variable and starts processing queue when canplaythrough event occurs. However in play for HTML5 there is manual execution of processing queue then promise from browser play resolves.

There are 2 possible ways to solving that issue:

  1. fix library not sure why this code exists at first place:
play.then(function () { 
  self._playLock = false; 
  self._loadQueue();
})
  1. wait for load event to trigger your play:
var player = new $wnd.Howl({
    src: url,
    html5: true, // A live stream can only be played through HTML5 Audio.
    format: ['webm', 'opus', 'mp3', 'aac'],
    autoplay: false
    onload: () => { /* trigger play - somehow */ }
    });

player.on('play', function(id) {
       console.log('playing!');
});

// player.play();

BTW. when you use autoplay it will trigger event twice as well :-)

@jmo84
Copy link

jmo84 commented Feb 7, 2018

@tbessie The log messages show for me in IE11, Chrome, Firefox, and Safari...but IE11 and Safari do not show duplicate play messages, just one.

What browser are you using?

@tbessie
Copy link
Author

tbessie commented Feb 7, 2018

@jmo84 I'm using the latest version of Chrome on Windows 7 x64. I'll try again a bit later on another computer and see if it works. I am running some plugins that might be getting in the way.

@tbessie
Copy link
Author

tbessie commented Feb 7, 2018

@jmo84 Ah, sorry - I had thought that jfiddle would show me console output onscreen, not in the usual browser console. I see it now, thanks! I also see that we get an "end" event. In my code, I never get an "end" even either (I've created a separate ticket for that).

@jmo84
Copy link

jmo84 commented Feb 7, 2018

@tbessie No problem. That is strange you are not getting the "end" event emitted.

@tbessie
Copy link
Author

tbessie commented Feb 7, 2018

@jmo84 I subscribe to all the events before I call play(). It's still not being called for some reason.
I changed the code to use the sample file above, and it worked; but when I use my local servlet call, it doesn't. I recently modified the code in the servlet in a different codeline to stream slightly differently, and it's more scrupulous about explicitly flushing the stream after each chunk it sent. I'll see if that makes a difference.

@tbessie
Copy link
Author

tbessie commented Feb 7, 2018

I found out what the issue is; if the file (webm/opus in this case) doesn't contain any duration information, I never get the "end" event. If it does, I do. This leads me to believe that Howler is using the duration information in the audio file header to determine when the audio ends, as opposed to when it reaches the end of file/buffers. This isn't the best way of determining this. I'll mention this in the other ticket.

@goldfire
Copy link
Owner

goldfire commented Feb 9, 2018

Thanks for spotting this, it should now be fixed on master.

goldfire added a commit that referenced this issue Feb 10, 2018
ringcrl pushed a commit to ringcrl/howler.js that referenced this issue Apr 21, 2019
ringcrl pushed a commit to ringcrl/howler.js that referenced this issue Apr 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants