No sound on iOS 6 Web Audio API

后端 未结 12 1358
灰色年华
灰色年华 2020-12-02 09:41

I was really excited to see iOS 6 supports the Web Audio API, since we make HTML5 games. However, I cannot get iOS 6 to play any sound at all using the Web Audio API with e

12条回答
  •  Happy的楠姐
    2020-12-02 10:39

    You can try to debug it using the Web Inspector on Safari 6 on a mac.

    1. Enable "Webkit Inspector" in Mobile Safari settings/advanced.
    2. Connect device to a Mac running Safari 6 using a USB cable.
    3. Load your page/game
    4. Go to menu Develop->[devicename]->[pageurl]

    It doesn't work out of the box for me, but with a few tries it can help narrow down the problem.

    Apparently there is also the thing that audio can only be triggered by a user action. I'm not sure this is true 'cos some code that works on iOS6 on iPhone4 doesn't play any sound on an iPad (also iOS6).

    Update: Some success with web audio on iPhone4+iOS6. Found that the "currentTime" remains stuck at 0 for a while as soon as you create a new audio context on iOS6. In order to get it moving, you first need to perform a dummy API call (like createGainNode() and discard the result). Sounds play only when currentTime starts to run, but scheduling sounds exactly at currentTime doesn't seem to work. They need to be a little bit into the future (ex: 10ms). You can use the following createAudioContext function to wait until the context is ready to make noise. User action doesn't seem to be required on iPhone, but no such success on iPad just yet.

    function createAudioContext(callback, errback) {
        var ac = new webkitAudioContext();
        ac.createGainNode(); // .. and discard it. This gets 
                             // the clock running at some point.
    
        var count = 0;
    
        function wait() {
            if (ac.currentTime === 0) {
                // Not ready yet.
                ++count;
                if (count > 600) {
                    errback('timeout');
                } else {
                    setTimeout(wait, 100);
                }
            } else {
                // Ready. Pass on the valid audio context.
                callback(ac); 
            }
        }
    
        wait();
    }
    

    Subsequently, when playing a note, don't call .noteOn(ac.currentTime), but do .noteOn(ac.currentTime + 0.01) instead.

    Please don't ask me why you have to do all that. That's just the way it is at the moment - i.e. crazy.

提交回复
热议问题