NEW 212125
Disconnecting a ScriptProcessorNode from AudioDestination permanently mutes the audio even after reconnecting the ScriptProcessorNode
https://bugs.webkit.org/show_bug.cgi?id=212125
Summary Disconnecting a ScriptProcessorNode from AudioDestination permanently mutes t...
Luigi Pulcini
Reported 2020-05-19 21:51:18 PDT
You can test this behavior at the following website: www.waveplayer.info This seems to happen in every version of Safari, in both mobile and desktop environments, while it works just fine in any other browser, including Chrome in both mobile and desktop devices. How to reproduce the issue: – when pressing play, the player starts playing back and the waveform animation works as expected – when pressing pause and then play again, the waveform animation restarts as expected but the audio is muted and there is no way to get it back until reloading the page There are no errors reported in the browser console. None of the following actions solves the issue: – setting the audio element volume; – setting the GainNode level; – resuming the AudioContext The only possible solution I could find was avoiding to disconnect the ScriptProcessorNode. This solution might degrade the user performance since it would keep the onAudioProcess callback running, even when the audio element is not playing. The following class will give you a rough idea of how my audio player works. Please note that the player is much more complex than this, but this is the main workflow and it works perfectly fine in every browser except Safari. Please also note that this problem is not related to bug#211394 because it only happens in Safari (211394 occurs in every browser under iOS13) but in every environment (any version of Safari in both mobile and desktop environments). class MyAudioPlayer { constructor() { this.audio = new Audio() this.audioCtx = new (window.AudioContext || window.webkitAudioContext)() this.source = this.audioCtx.createMediaElementSource(this.audio) this.source.connect(this.gain) this.gain.connect(this.audioCtx.destination) this.scriptProcessor = this.audioCtx.createScriptProcessor(2048, 1, 1) this.scriptProcessor.onaudioprocess = this.onAudioProcess.bind(this) } onAudioProcess() { // a function using the getByteFrequencyData function of the analyser // to analyze the audio streaming from the source } createAnalyser() { this.analyser = this.audioCtx.createAnalyser() this.source.connect(this.analyser) this.analyser.connect(this.scriptNode) } destroyAnalyser() { this.analyser = this.audioCtx.createAnalyser() this.source.connect(this.analyser) this.analyser.connect(this.scriptNode) } play() { this.audio.play() this.source.connect(this.scriptNode) this.scriptProcessor.connect( this.audioCtx.destination ) this.createAnalyser() } pause() { this.audio.pause() this.source.disconnect(this.scriptNode) this.scriptProcessor.disconnect( this.audioCtx.destination ) this.destroyAnalyser() } }
Attachments
Radar WebKit Bug Importer
Comment 1 2020-05-20 16:59:11 PDT
Luigi Pulcini
Comment 2 2020-06-06 15:37:14 PDT
Any update on this would be much appreciated. Any app using the ScriptProcessor Node the way it was described above makes the app unusable in any version of Safari. Please give us a feedback in this regard. Thanks.
Luigi Pulcini
Comment 3 2020-06-16 15:21:01 PDT
This bug has not been acknowledged yet and bug #211394 did not make it to a public release yet. I am sorry for keeping pushing about this but the two bugs combined make any player using these WebAudio API techniques useless in the whole MacOS/iOS universe, which is somehow 20/25% of the whole market. I cannot stress enough how this is creating a problem to our business, especially when there is no effective way of mitigating this bug#212125 without limiting any other browser. Can please somehow verify this bug and, at least, report if they manage to reproduce it?
Luigi Pulcini
Comment 4 2020-07-01 14:30:32 PDT
Was this bug ever reproduced by any of you? My customers are complaining that the player is not working in Safari and I can't do anything to fix this. Please advise.
Khushpreet
Comment 5 2020-07-20 07:16:20 PDT
Hi, I checked https://www.waveplayer.info/ and seems like this issue doesn't persists anymore. Audio also starts playing as expected along with waveform animation after 'Pause' and 'Play'. Tested on iOS 13.6 on iPad mini 4, if this is of any help :-)
Khushpreet
Comment 6 2020-07-20 07:29:38 PDT
Tested on Safari (13) and also, on Safari in Mac(version 10.15.6).
Luigi Pulcini
Comment 7 2020-07-20 07:41:24 PDT
Hi, Khushpreet. Thank you so much for checking this. Since the website I initially linked here is used to promote the player, I had to implement a different strategy where the scriptProcessorNode always stay connected even when pressing the pause button. This is the only way to make it work with Safari. If you want to verify the wrong behavior, you can check the following staging website: https://www.staging2.waveplayer.info Thanks again for checking this. Best, Luigi.
Khushpreet
Comment 8 2020-07-20 08:05:05 PDT
Hi Luigi, Yes, I was able to reproduce the issue here - https://www.staging2.waveplayer.info and console doesn't throw any error. Just curious, if you are catching 'NotAllowedError' exception when resuming the audio? Because I had the same issue on play because I was using the callback before playing mediaElement something like as follows: mediaElementSource.context.resume().then( function() { mediaElementSource.mediaElement.play(); } ) and since, play() also returns a promise, I wasn't able to actually hear the audio, (played on mute). I had come across an online resource which said that audioContext only needs to be resume once, also not to loose user gesture, So, I changed the code in my play() as below: mediaElementSource.context.resume(); mediaElemntSource.mediaElement.play(); and resume the context in my Pause(). I have implemented the player same way and disconnect the scriptProcessor node. Play and pause works as expected. If this is of any help again :) Regards, Khushpreet
Note You need to log in before you can comment on or make changes to this bug.