Audio fails to start in Safari 14.0.2
See original GitHub issueI’ve been battling with Safari and audio problems for a while, but that seems to be a new issue.
I understand that modern browsers only allow audio to play after there has been some interaction with the user (e.g. a click on a button). In a new experiment, the participants go through the instructions by hitting the spacebar or clicking on a piece of text. Then come some trials using the audio-keyboard-response
plugin. In Firefox and Chrome, the sound plays just fine (whether the user clicks or presses the spacebar), but in Safari, nothing happens, and it just hangs silently.
To unlock it, I had to add an async call-function
trial that displays a button with a callback that calls jsPsych.pluginAPI.audioContext()
:
const is_Safari = /Version\/.*Safari\//.test(navigator.userAgent) && !window.MSStream;
if(is_Safari){
timeline.push({
type: 'call-function',
async: true,
func: function(done){
var display_element = document.getElementById('jspsych-content');
display_element.innerHTML = "<p>Click on the screen to start...</p>";
//var init_button = display_element.querySelector('#safari_audio_init');
function init_audio_files(){
jsPsych.pluginAPI.audioContext();
done();
}
document.addEventListener('touchstart', init_audio_files, false);
document.addEventListener('click', init_audio_files, false);
}
});
}
It is a pain… but it works… I tried to have just a button without the jsPsych.pluginAPI.audioContext()
callback, and it did not work. This is the only combination that worked, and with or without webAudio made no difference.
Honestly, I don’t think there is anything wrong with jsPsych. I don’t know why Safari makes it extra hard and quirky to get audio started… I’m going to make a plugin to deal with this automatically, but if there’s some more insight out there, that’d be great!
Issue Analytics
- State:
- Created 3 years ago
- Comments:16 (7 by maintainers)
Oh boy. @becky-gilbert you’re right, they are two different issues. Turns out that firefox is a little dumber and let me record audio even without having a microphone, but Chrome(ium) does not.
The issue I faced was that jsPsych (use_webaudio: true) is calling the audio after a setTimeout (in TimeoutAPI) and not from the click. The solution I used is to play an empty sound file directly from a click early in the task e.g.: