Reputation: 41595
I'm trying to play a sound over itself on keydown. In order to do so, I saw the solution is to clone the sound and play the new instance instead:
var promise = sound.cloneNode(true).play();
Reproduction online: https://jsfiddle.net/alvarotrigo/up4c6m95/13/
This seems to be working fine in Chrome and Firefox. However in Safari this results in bad performance.
Try typing very fast with both hands to reproduce the error.
Note I added a gif image that lags when typing very quickly. This can of course be noted as well on the Safari dev tools as can be seen in the picture below:
Whole code here:
var sound = new Audio('https://www.w3schools.com/html/horse.mp3');
document.addEventListener('keydown', playSound);
function playSound() {
//in order to play the same sound over itself
var promise = sound.cloneNode(true).play();
//we just dont want to show the console error when autoplay is disabled :)
if (typeof promise !== undefined) {
promise.then(function() {
// Autoplay started!
}).catch(function(error) {
//error
});
}
}
Upvotes: 2
Views: 963
Reputation: 10922
Safari puts a request every time for the audio file being played, while on the other hand it's not the case for Firefox and Chrome as they tend to load it only once.
In Safari on iOS (for all devices, including iPad) ... no data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action.
I don't think you can get around the slow performance resulting in putting out a request on each keydown.
Upvotes: 2