admin管理员组

文章数量:1359263

I have a web app that plays audio samples successfully on all platforms except iOS.

Here's my minimal reproducible example, with additional context below.

const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();

async function loadAudioSample(url) {
    const response = await fetch(url);
    const arrayBuffer = await response.arrayBuffer();
    const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
    return audioBuffer;
}

function playSample(audioBuffer) {
    const source = audioContext.createBufferSource();
    source.buffer = audioBuffer;
    source.connect(audioContext.destination);
    source.start(0);
}

// make sure user interacts with document first
document.addEventListener('click', async () => {
    let buf = await loadAudioSample('./sample.mp3');
    if (audioContext.state === 'suspended') {audioContext.resume();}
    // logging es up normal
    console.log(audioContext.state, buf);
    playSample(buf);
});

Additional notes:

  • If I play sample.mp3 from an audio element via new Audio() using .play() it does work, so I don't think the file format is an issue. (But I need the Web Audio API for higher precision and synchronizability).
  • The audio file is hosted on my own domain, so it's not CORS
  • Testing on iOS 16 devices, iPhone and iPad
  • Edit: in case it was the encoding, I've also tried a 16 bit .wav file encoded at 44.1kHz and 48kHz.
  • Edit 2: I suspect the problem has to do with user interaction requirements on iOS not allowing the audio context to be initialized, because audioContext.state logs "running" right away on mac, but "suspended" for the first couple of presses on iOS -- but I'm having trouble pinning it down. Even when "running" on iOS, no sound.

What am I doing wrong?

I have a web app that plays audio samples successfully on all platforms except iOS.

Here's my minimal reproducible example, with additional context below.

const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();

async function loadAudioSample(url) {
    const response = await fetch(url);
    const arrayBuffer = await response.arrayBuffer();
    const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
    return audioBuffer;
}

function playSample(audioBuffer) {
    const source = audioContext.createBufferSource();
    source.buffer = audioBuffer;
    source.connect(audioContext.destination);
    source.start(0);
}

// make sure user interacts with document first
document.addEventListener('click', async () => {
    let buf = await loadAudioSample('./sample.mp3');
    if (audioContext.state === 'suspended') {audioContext.resume();}
    // logging es up normal
    console.log(audioContext.state, buf);
    playSample(buf);
});

Additional notes:

  • If I play sample.mp3 from an audio element via new Audio() using .play() it does work, so I don't think the file format is an issue. (But I need the Web Audio API for higher precision and synchronizability).
  • The audio file is hosted on my own domain, so it's not CORS
  • Testing on iOS 16 devices, iPhone and iPad
  • Edit: in case it was the encoding, I've also tried a 16 bit .wav file encoded at 44.1kHz and 48kHz.
  • Edit 2: I suspect the problem has to do with user interaction requirements on iOS not allowing the audio context to be initialized, because audioContext.state logs "running" right away on mac, but "suspended" for the first couple of presses on iOS -- but I'm having trouble pinning it down. Even when "running" on iOS, no sound.

What am I doing wrong?

Share Improve this question edited May 20, 2023 at 22:07 ultraGentle asked May 19, 2023 at 17:47 ultraGentleultraGentle 6,3672 gold badges26 silver badges58 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

I can't believe I'm writing this, but the mute/silent switch was on. I checked the volume a million times, but it's apparently separate from the switch.

On the other hand, there are things I still don't understand: other websites like YouTube played audio during my testing; how? Maybe because those are HTML5 new Audio() .play() elements, instead of using the Web Audio API?

On iOS the webAudio (as opposed to media audio) is connected to the ringer settings. See: https://bugs.webkit/show_bug.cgi?id=237322

本文标签: javascriptNo sound on iOS only (Web Audio API)Stack Overflow