Hi,
Sometimes, I've got this error when I load the page :
undefined:1 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
It's happens randomly and when the message is displayed in console : I can't edit dropdown list and text area.
Here is my call code and it happens just after :
console.log('INJECT BLOCKLY')
@blockly = Blockly.inject('blocklyDiv', {
toolbox: @opts.toolbox
zoom:
controls: true,
wheel: false,
startScale: 0.7,
maxScale: 3,
minScale: 0.3,
scaleSpeed: 1.2
grid:
spacing: 25
length: 3
colour: '#ddd'
snap: true
})
I've tried to delay inject with a setTimeout, but it doesn't change anything.
For information, I use "page.js" for this UI.
Thanks by advance if you've a solution.
I have the exact same issue, thought it was somehow related to the sounds made by Blocky.
Ah, that makes sense. Try adding a return statement at the top of Blockly.WorkspaceSvg.prototype.preloadAudio_ or comment out the body of that function.
Which browser/OS does this affect? I assume there's no stack track to point back to a line in Blockly that's throwing an error?
Just have tried in private navigation mode, without any plugins and problem is the same.
My chrome version is : Version 50.0.2661.49 beta (64-bit) under OSX 10.11
@NeilFraser > Audio sounds to be the issue : no more problems when commentating internal preloadAudio_
And sounds when dropping elements are stil working.
Blockly.WorkspaceSvg.prototype.preloadAudio_=function(){
console.log("Sounds : ", JSON.stringify(this.SOUNDS_));
/*
for(var a in this.SOUNDS_){
var b=this.SOUNDS_[a];
b.volume=.01;
b.play();
b.pause();
if(goog.userAgent.IPAD||goog.userAgent.IPHONE)
break;
}
*/
};
This is a recent bug in Chromium. Since they appear to be working on it, I don't think we need to think about a workaround at our end. Especially since this is just console spam, with no user impact.
https://bugs.chromium.org/p/chromium/issues/detail?id=593273
The linked bug is not really related to this issue.
In the chrome bug the used code is:
a.pause();
a.play();
But in this case it's:
a.play();
a.pause();
In your case it's expected to get such error message, so this needs to be fixed in the Blockly.WorkspaceSvg.prototype.preloadAudio_ function.
Submit a pull request https://github.com/google/blockly/pull/471 to fix this issue, because is impacting error checking (with catch() { ... }) if you want to make sure that everything is loaded without any errors.
@MarkusBordihn : fix local sources, it seems to solve issues :)
Note that #471 breaks sounds on iOS.
Is valid to simply disable sound preload ? i make this change to my code and everything seems to be ok:
Blockly.WorkspaceSvg.prototype.preloadAudio_ = function() {};
Disabling preload works, but sounds awful when that first click is offset by up to a second.
I'm still monitoring the open bug on Chrome, https://bugs.chromium.org/p/chromium/issues/detail?id=593273
thanks!
For info, I've just published an article about this exact issue at https://developers.google.com/web/updates/2017/06/play-request-was-interrupted that tells you exactly what is happening and how to fix it.
Will play() always return undefined in older browsers that might not return a promise?
I think this have been fixed. I'm using the last version from the repo and it didn't happened
I'm still seeing this on develop.
@beaufortfrancois the solution you suggest doesn't work cross-platform.
I'm guessing we can test for the Promise result from .play(), and toggle between calling .pause() (when no return value) and @beaufortfrancois's promise based solution.
I'm no longer seeing these error messages on the published demos (master release) in Chrome 67 Mac.
In fact, if I attempt to implement @beaufortfrancois's suggestions, I get new error messages: "workspace_audio.js:120 Error loading sound "delete" DOMException: play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD"
Is there any background on why preload="auto" is not a sufficient solution to preloading these files?
Is there any background on why
preload="auto"is not a sufficient solution to preloading these files?
The definitive story was in a long email I send @rachel-fenichel a couple of years ago. Unless she retained it, it's gone now. The short version is I tried everything, and the existing scheme is the only one that actually worked cross-platform five years ago.
Of particular note is iOS which only plays (played?) one sound. Loading a second sound corrupted the first, if I recall correctly. Since the 'click' is by far the most important sound, I made sure that it and only it was loaded.
The other issue is that the timing of the 'click' sound is critical. If it plays a quarter second late the first time, it sounds awful. If I recall, the preloading scheme provided by browsers was rarely honoured, thus requiring a more forceful preload.
If anyone wants to dive down the rabbit hole again, feel free. I have a recollection that someone tried making changes a couple of years ago, broke things, and it all had to be rolled back.
Since I know I'll get complaints about console spam in our implementation, I took a stab at finding a solution. Surprisingly Promise.resolve(b.play()).then(() => {b.pause();}); will also fail as if Chrome resolves the promise for play even when it still hasn't played yet and calling b.pause() will throw the error anyway.
While poking around this, I also noticed that even with the volume set to 0.01, I could still hear the 'preload' click whenever I made a change that didn't pause the sound which was more annoying than the console spam.
Eventually, I came up with this monkey patch:
Blockly.WorkspaceAudio.prototype.preload = function() {
for (var a in this.SOUNDS_) {
var b = this.SOUNDS_[a];
b.load();
if (goog.userAgent.IPAD || goog.userAgent.IPHONE)
break
}
}
This works in the following browsers:
Google Chrome Version 67.0.3396.99 (Official Build) (64-bit)
Internet Explorer 11.0.9600.19080
Firefox 61.0.2 (64-bit)
Using load() to silently load the audio seems like it'd be an obvious first choice solution for this, so perhaps I'm missing something? I don't have the means at the moment to test on mobile platforms, nor do I have to support them at the moment.
Does .load() actually preload the sound as advertised? In other words,
with a cleared cache when running on a remote server (not localhost or the
file system) does the first real connection click happen exactly when the
block is dropped? As of a few years ago that was not the case.
Sent (awkwardly) from an Android device.
>
It seems to, at least in the 3 browsers I tried. I also checked the network tab in Chrome and found it made the request for the file during this method and not later, like during the first click from moving a block.
I believe this was fixed by https://github.com/google/blockly/pull/2614. Please let me know if anyone is still seeing this on develop.
Most helpful comment
Is valid to simply disable sound preload ? i make this change to my code and everything seems to be ok: