No sound on iOS 6 Web Audio API

后端 未结 12 1320
灰色年华
灰色年华 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条回答
  • 2020-12-02 10:21

    I have come across the audio restrictions with HTML5 Audio on iOS and worked around the problem by:

    1) Creating an Audio Element with a silent audio file and playing it initially with a touch event (e.g. 'begin game' button) and then immidietly pausing it.

    2) Building a sound-switcher function which switches the Audio src and then plays the Audio element after a short timeout.

    3) Calling the sound-switcher function on any events (doesn't need to be a touch event).

    This works because the Audio Element is un-muted on first touch, with the silent audio file, and remains un-muted, so the source can be switched on-the-fly.

    switchSound: (id) ->
            @soundSwitch.pause()
            @soundSwitch.src = @sounds[id]._src
    
            clearTimeout @switchSoundDelay
            @switchSoundDelay = setTimeout =>
                # @soundSwitch.volume = 1
                @soundSwitch.play()
            ,50 
    
    0 讨论(0)
  • 2020-12-02 10:23

    This isn't an actual answer, just a direction to look if things still aren't working. iOS6 has audio issues on some devices (particularly the 64gb 4s manufactured during a particular period, though I've seen others so it may not actually be hardware related) and will mysteriously stop playing some kinds of sounds (not ringtones or voice, for some reason, but many other sounds), and it's volume sliders will vanish. I've found it notoriously difficult to debug as it will usually (thought not always, sometimes you can catch it) happen only when not connected with a power cord.

    Look in the console for ASSERTION FAILURE messages from the VirtualAudio_Device and with various codecs. This may have nothing whatsoever to do with your particular issue, but then again, a bug in one area of the sound device may be related to another. At minimum, it's an area to investigate if nothing else is helping.

    0 讨论(0)
  • 2020-12-02 10:30

    I managed to figure out a simple solution which I'm sure must have been documented elsewhere - but sometimes we have to spend hours figuring these things out for ourselves...

    So it seems many tutorials (such as this one on html5rocks) instruct you to do the following steps :

    • Create an instance of window.AudioContext and if that doesn't exist (which it doesn't on iOS) then create window.webkitAudioContext.

    • Create an XMLHttpRequest to load your sound file

    • On the load event run context.decodeAudioData(....) and then createBufferSource(), filling it with the decoded data, and finally source.start(0) to play the sound.

    As others have pointed out you must create the AudioContext (which incidentally you must store and use for the lifetime of the page) as a result of a user interaction (click or touchstart).

    HOWEVER : For iOS to 'unlock' its audio capabilities you MUST have audio data available when you create the AudioContext. If you load the data asynchronously there's nothing for it to play. It is not sufficient to merely create the AudioContext inside a click event.

    Here's two solutions for reliable iOS playback:

    • 1) You must load at least one sound file before you even initialize the AudioContext, and then run all the above steps for that sound file immediately within a single user interaction (eg click).

    • OR 2) Create a sound dynamically in memory and play it.

    This is how I did that second option:

    REMEMBER - MUST BE within click / touch event for iOS:

     window.AudioContext = window.AudioContext || window.webkitAudioContext;
     var context = new window.AudioContext();
    
     // you should null check window.AudioContext for old browsers to not blow up
    
     // create a dummy sound - and play it immediately in same 'thread'
     var oscillator = context.createOscillator();
     oscillator.frequency.value = 400;
     oscillator.connect(context.destination);
     oscillator.start(0);
     oscillator.stop(.5);    // you can set this to zero, but I left it here for testing.
    
     // audio context is now 'unlocked' and ready to load and play sounds asynchronously
     // YOU MUST STORE 'context' for future usage. DON'T recreate more AudioContexts
    

    I imagine this is a common mistake - and I'm surprised after 3 years that nobody seems to have pointed this out or discovered it :-/

    0 讨论(0)
  • 2020-12-02 10:34

    The API appears to be broken on iOS 6.1, or at least, has a breaking change that means no sites currently work with it.

    0 讨论(0)
  • 2020-12-02 10:35

    So, I think I've figured it out.

    It's a issue of Apple requiring an user action before sound can be allowed to play. It turns out, at least for me, that you shouldn't create the audio context at all except when the user calls for it. It's not enough to create the context when the page loads and then use createGainNode or similar on an user action.

    In your case I'd create the context when the user clicks the "Touch to begin" button.

    0 讨论(0)
  • 2020-12-02 10:37

    I've got trouble using all simple solutions. Especially, when I want to play a sound multiple times.

    So I'm using this js library: http://pupunzi.open-lab.com/2013/03/13/making-html5-audio-actually-work-on-mobile

    0 讨论(0)
提交回复
热议问题