JavaScript API playSound() issue

Q&A about the latest versions
Post Reply
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

Most browsers these days prevent audio from playing automatically.
This means that if a page tries to start playing without user intervention the browser will throw an error.
In theory this is not a problem, because the developer can catch the error and take an appropriate measure.

Unfortunately, the pano.playSound() doesn't include a way to catch the error, which in this case is this:

Code: Select all

Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
In Firefox and Chrome at least, this has the unfortunate consequence that the player start playing as soon as the user clicks on any button, completely unrelated to the actual play button.

Is there a way to get around this issue ?
User avatar
Hopki
Gnome
Posts: 13005
Joined: Thu Jan 10, 2008 3:16 pm
Location: Layer de la Haye, Essex UK
Contact:

Hi,
If a sound is set to play, then on the first touch or click it will play.
If you want the sound to start playing with a button click then set the sounds Loopto -1.
This will stop the sound from playing until an action is used to play it.
Regards,
Hopki
Garden Gnome Support
If you send an e-mail to support please send a link to the forum post for reference.
support@ggnome.com
https://ggnome.com/wiki/documentation/
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

well, what I mean is that for some panos I'd like the sound to start playing immediately upon page loading,
without user intervention.

Some users don't like that and prevent audio from start playing automatically.
That's why when this is the case the JavaScript engine throws an error.
Normally, in JavaScript I could catch the error and make sure that it does't cause any trouble,
but in this case I haven't been able to figure out how to do that.

-Franco
User avatar
Hopki
Gnome
Posts: 13005
Joined: Thu Jan 10, 2008 3:16 pm
Location: Layer de la Haye, Essex UK
Contact:

Hi Franco,
sound to start playing immediately upon page loading, without user intervention.
The browsers will not allow this, it needs user interaction.
This said Chrome has learning ability, I seem to remember if you go to the same website 7 or 8 times, and each time clicking the play button and listen to the audio for over 7 seconds each time, Chrome will then allow autoplay as it now knows you want to hear the sound.

Safari and Firefox will not allow autoplay and will require user interaction. You can not use JavaScript to get around this, even if you could the browser produces would find a way around this at some point and brake it.
Regards,
Hopki
Garden Gnome Support
If you send an e-mail to support please send a link to the forum post for reference.
support@ggnome.com
https://ggnome.com/wiki/documentation/
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

Hopki,

Sorry for this late reply, but I have been doing a lot of testing around this issue.
Here is what I found out. But first, a few words about my plan:

- Yes, most browsers by default don't allow autoplay, and that's fine. I have no intention to somehow bypass
this setting.
- I have some panos where it would make sense to autoplay a background sound. These panos are set with a loop value of 0;
- For these panos I use the JS API to start playing immediately.
- Now, if the browser requires user intervention, i.e. a click by the user, the JS engine will - correctly - throw an error,
so need to catch it before it causes the entire script to fail.
- There is a way to deal with this situation, it goes like this:

Code: Select all

window.addEventListener('unhandledrejection', function(event) {
  console.log(event.promise); // [object Promise] - the promise that generated the error
  console.log(event.reason); // Error: Whoops! - the unhandled error object
                            // and now do something ...
});
- This code works fine. My script recovers from the error and continue doing its job.

Now it gets interesting:
If a user clicks anywhere on the page, not just on the sound player play button,
the background sound starts playing. As far as I am concerned this is not supposed to happen
and it's a serious issue, as it screws up the entire sound logic.

Best,
Franco
User avatar
Hopki
Gnome
Posts: 13005
Joined: Thu Jan 10, 2008 3:16 pm
Location: Layer de la Haye, Essex UK
Contact:

Hi Franco,
If a sound has a loop of 0 or above, then on "first touch" it will start playing sound.
With regards to the errors, if you set the sound to loops -1 then no sound will try and play.
But I am not sure what information you require?
Regards,
Hopki
Garden Gnome Support
If you send an e-mail to support please send a link to the forum post for reference.
support@ggnome.com
https://ggnome.com/wiki/documentation/
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

Hi Hopki,

sorry for this late reply. My understanding is that for most browsers,
the user can decide to allow autoplay when a page loads.
By default, autoplay is turned off in the browser settings, but it can be changed.

In the case of my application, I wanted to autoplay (NOT merely play on touch)
some background sound. That's easy enough to do.

If the browser doesn't allow that to happen, javascript will
throw an error. So JS will tell me (in the console) that something went wrong with
executing playSound().

Now, if I don't do anything in response to this error the sound script in my application
will be disrupted. Normally that's easy enough to take care of. But in this case I don't know
how to deal with this situation because I have no idea what's going on in the playSound() API.

I guess what I am saying is that it would be helpful if one of your developers could let me
know how to deal with this situation.

Best,
Franco
christoph
Gnome
Posts: 108
Joined: Mon Aug 20, 2012 3:01 pm

Hi Franco!
The player function playSound() basically just calls the play() function of the HTML AUDIO element (https://www.w3schools.com/jsref/met_audio_play.asp)

Regards,
Christoph
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

Thank you Christoph,

I kind of suspected that. Now, could you tell me how to handle this Promise Rejection coming from the soundPlayer:

Code: Select all

Unhandled Promise Rejection: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Thanks,
Franco
christoph
Gnome
Posts: 108
Joined: Mon Aug 20, 2012 3:01 pm

Hi Franco!
We do not handle the promise returned from the play() function in the player playSound() function, we do this somewhere else (when we try to auto-play sounds when opening a new node).

But what you could do:
Our player provides a function 'getMediaObject(id)', which returns the media object of the given sound element, where you then can call the play() function and handle the promise yourself. (The id of the background sound would be '_background')

So something like:

Code: Select all

var soundObj = player.getMediaObject('_background');
var playPromise = soundObj.play();
....
You may be losing a few things the playSound() function does (like counting the current loop number, etc.), but if you just want to play a background sound, this should work...

Regards,
Christoph
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

Thank you Christoph, I'll give it a try.

Best,
Franco
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

Hi Christoph,

It really would be great if your pano.play() function would return a promise.
As it stands now, there is simply no way for me as developer to check if a browser allows autoplay or not.

The fact that your API does this internally is only a partial solution.
I think it is quite important for a user to decide by himself if he wants to play a background sound or not.
If the browser settings prevents autoplay, the user should be presented with a play/pause button.
(Well, actually he should always be presented with that button)
This is pretty much a standard practice on any site that includes sound.
As of now, I cannot implement this feature, so a user can hear a background sound ONLY if the browser settings allow it.

Thank you very much for taking this suggestion into consideration.

-Franco
MajPG
Posts: 11
Joined: Sat Jun 20, 2020 5:11 pm

Hopki wrote: Thu Feb 06, 2020 6:52 pm Hi Franco,
If a sound has a loop of 0 or above, then on "first touch" it will start playing sound.
With regards to the errors, if you set the sound to loops -1 then no sound will try and play.
But I am not sure what information you require?
Regards,
Hopki
Hi Hopki,
I read a bunch of older blog posts regarding that exact issue:
What I gathered was that the sounds should be set to Loop -1: "This stops the sound playing when the project opens.
Other wise even though the sounds are set to volume to 0 they are all still playing taking up valuable resources."
I know that at some point you integrated the "start on first touch" option for relevant (touch-) devices.
Does your blog post here mean that with Pano2VR 6.1.8 sounds will generally (EXCEPT for -1) only start on "first touch" (or "first click" if a mouse is involved) on every operating system?
If so: Good for me, because I was still looking for a way to install an action doing exactly that for all the other operating systems / devices, which I needed to start sound set to loop -1 user friendly. Now I would switch to 0 or above without having to set an action to start the sound.
christoph
Gnome
Posts: 108
Joined: Mon Aug 20, 2012 3:01 pm

@Franco:
in Version 7, the playSound() function will return a Promise....

Regards,
Christoph
ffurger
Posts: 102
Joined: Mon Mar 24, 2014 11:45 am

@christoph - that’s good news ... and now for the harder question - when would that be?
Post Reply