41 votes

Pas de son sur l'API Web Audio iOS 6

J'étais vraiment excité de voir iOS 6 prend en charge l'API Web Audio, depuis que nous faisons HTML5 jeux. Cependant, je ne peux pas obtenir de l'iOS 6 pour jouer, aucun son à l'aide de l'API Web Audio avec des exemples qui fonctionnent bien dans de bureau Chrome.

Voici un HTML5 jeu avec des contrôles tactiles et la lecture audio via l'API Web Audio (si présent - si non il va retomber HTML5 audio):

http://www.scirra.com/labs/sbios6b/

Edit: @Srikumar a proposé quelques solutions de contournement. J'ai appliqué à la version ci-dessous. Il ne fonctionne toujours pas!

http://www.scirra.com/labs/sbios6f/

Tout ce joue très bien sur de bureau Chrome, mais iOS 6 n'émet aucun son. Je vais avoir de la difficulté à le débogage parce que je ne fais que du développement de Windows et iOS 6 a remplacé le mode de débogage à distance de l'inspecteur web, qui, apparemment, n'est pas disponible sur Safari pour Windows. À l'aide de quelques alertes je n'ai trouver qu'il identifie correctement l'API Web Audio, utilise, détecte pas de Vorbis appui, afin de revient de l'audio en AAC, décode un tampon, puis la joue, et aucune erreur n'est renvoyée, mais je n'entends rien. Et, bien sûr, j'ai essayé de tourner le volume au max :)

Il ne devrait pas être un problème de codec, parce que iOS 6 peut lire les fichiers AAC, juste des beaux - que vous pouvez parcourir à la une de la .m4a est le jeu joue et il joue fine visité directement à partir de Safari.

En regardant l'API Web Audio exemples ici sur iOS 6: http://chromium.googlecode.com/svn/trunk/samples/audio/samples.html - certains d'entre eux travaillent, et les autres ne sont pas. Par exemple, le Chrome Audio Visualizer fonctionne, mais Javascript Drone n'est pas.

Il doit y avoir une subtile incompatibilité entre la bande Audio sur iOS 6 et de bureau Chrome. Ce qui me manque?

51voto

AshleysBrain Points 11439

Eh bien, désolé de répondre à mes propres bounty question, mais après des heures de débogage, j'ai enfin trouvé la réponse. Safari sur iOS 6 efficace commence avec l'API Web Audio en sourdine. Il ne sera pas en sourdine jusqu'à ce que vous essayez de jouer un son dans une entrée de l'utilisateur de l'événement (à créer une zone tampon à la source, le connecter à la destination, et appelez noteOn()). Après cela, il rétablit et audio joue sans restriction et comme il se doit. C'est un sans-papiers aspect du fonctionnement de l'API Web Audio fonctionne sur iOS 6 (Apple doc est ici, j'espère qu'ils le mettre à jour avec une mention de cela bientôt!)

L'utilisateur peut toucher l'écran est beaucoup, engagés dans le jeu. Mais il reste silencieux. Vous avez à jouer à l'intérieur d'une entrée de l'utilisateur de l'événement comme touchstart, une fois, puis tous les fichiers audio désactiver. Après cela, vous pouvez lire des fichiers audio à tout moment (ne pas être dans une entrée de l'utilisateur de l'événement).

Remarque c'est différent pour les restrictions sur HTML5 audio: en général, vous ne pouvez démarrer audio à une entrée de l'utilisateur de l'événement, et seulement jouer un son à la fois; l'API Web Audio entièrement rétablit après le premier jeu-en-entrée utilisateur, de sorte que vous pouvez jouer des sons à tout moment, et puis vous pouvez les mélanger d'une manière polyphonique, processus de superbes effets, etc.

Cela signifie beaucoup de jeux déjà sur le web à l'aide de l'API Web Audio ne sera jamais à la lecture de l'audio, car ils n'arrivent pas à émettre un noteOn dans un événement tactile. Vous avez à régler pour attendre que la première entrée d'utilisateur de l'événement.

Il ya quelques façons de contourner cela: ne jouez pas votre titre de la musique jusqu'à ce que l'utilisateur touche l'écran; avoir une première touche pour activer l'audio de l'écran " et de jouer un son, puis commencer le jeu quand ils touchent; etc. J'espère que cela va aider quelqu'un d'autre ayant le même problème d'économiser du temps à essayer de le corriger!

7voto

Srikumar Points 211

Vous pouvez essayer de débogage à l'aide de l'Inspecteur Web de Safari 6 sur un mac.

  1. Activer "Webkit Inspecteur" dans le navigateur Safari Mobile paramètres/avancé.
  2. Connectez l'appareil à un Mac exécutant Safari 6 à l'aide d'un câble USB.
  3. Chargement de votre page/jeu
  4. Allez dans le menu Développer->[nom de périphérique]->[pageurl]

Il ne fonctionne pas hors de la boîte pour moi, mais avec quelques essais, il peut aider à réduire le problème.

Apparemment, il y a aussi la chose que l'audio ne peut être déclenchée que par une action de l'utilisateur. Je ne suis pas sûr que c'est vrai parce qu'un peu de code qui fonctionne sur iOS6 sur iPhone4 ne pas jouer n'importe quel son sur un iPad (également iOS6).

Mise à jour: un Certain succès avec web audio sur iPhone4+iOS6. Trouvé que le "currentTime" reste bloqué à 0 pour un temps dès que vous créez un nouveau contexte sonore sur iOS6. Pour l'obtenir, vous devez d'abord effectuer un mannequin appel d'API (comme createGainNode() et jeter le résultat). Sons jouer que lorsque currentTime commence à courir, mais la planification des sons exactement à currentTime ne semble pas fonctionner. Ils doivent être un peu dans le futur (ex: 10ms). Vous pouvez utiliser l' createAudioContext fonction d'attendre jusqu'à ce que le contexte est prêt à faire du bruit. Action de l'utilisateur ne semble pas être nécessaire sur l'iPhone, mais pas un tel succès sur iPad pour l'instant.

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();
}

Par la suite, lors de la lecture d'une note, ne pas appeler à l' .noteOn(ac.currentTime), mais n' .noteOn(ac.currentTime + 0.01) à la place.

S'il vous plaît ne me demandez pas pourquoi vous avez à faire tout ça. C'est juste la façon dont il est pour le moment - c'est à dire fou.

3voto

Oskar Eriksson Points 925

Donc, je pense que je l'ai compris.

C'est un problème d'Apple nécessitant une action de l'utilisateur avant que le son puisse être autorisé à jouer. Au moins pour moi, il s’avère que vous ne devez pas du tout créer le contexte audio, sauf lorsque l’utilisateur l’appelle. Il ne suffit pas de créer le contexte lors du chargement de la page, puis d'utiliser createGainNode ou similaire pour une action de l'utilisateur.

Dans votre cas, je créerais le contexte lorsque l'utilisateur clique sur le bouton "Toucher pour commencer".

1voto

Enrico MRK Points 11

Répondant à la question initiale , je peux confirmer certains problèmes liés aux formats de fichier sur iPhone 4S / iOS 6 et MacOSX. Si un fichier MP3 n'est "pas bon" pour Safari, le décodage va mal et appeler AudioContext.createBuffer (array, bool) vous donnera une erreur.

La chose étrange est à propos de l'erreur: "SYNTAX_ERR, DOM Exception 12", comme l'ont souligné d'autres. Cela me fait penser que c'est un bug ....

Même comportement également sur MacOS, avec Safari 6.0 (7536.25).

1voto

Jack Wild Points 95

J'ai trouver l'audio restrictions avec HTML5 Audio sur iOS et contourné le problème en:

1) Création d'un Élément Audio avec un silencieux fichier audio et de jouer d'abord avec une touche de l'événement (par exemple, "commencer le jeu" bouton) puis immidietly de la mettre en attente.

2) la Construction d'un son de commutateur de fonction qui passe de l'Audio src et joue alors l'élément Audio après un court délai d'attente.

3) en Appelant le son de commutateur de fonction sur tous les événements (n'a pas besoin d'être un événement tactile).

Cela fonctionne parce que l'Élément Audio est non-coupé sur la première touche, avec le silence de fichier audio, et non-coupé, de sorte que la source peut être commuté à la volée.

switchSound: (id) ->
        @soundSwitch.pause()
        @soundSwitch.src = @sounds[id]._src

        clearTimeout @switchSoundDelay
        @switchSoundDelay = setTimeout =>
            # @soundSwitch.volume = 1
            @soundSwitch.play()
        ,50 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X