web-dev-qa-db-fra.com

Lecture automatique de fichiers audio sur un iPad avec HTML5

J'essaie de lire automatiquement un fichier audio dans Safari sur un iPad. Si je vais à la page en utilisant Safari sur mon Mac, c'est bon. La lecture automatique ne fonctionne pas sur l'iPad.

84
milesmeow

UPDATE: Ceci est un hack qui ne fonctionne plus sur IOS 4.X et plus. Ce script a fonctionné IOS 3.2.X.

Ce n'est pas vrai. Apple ne veut pas lire automatiquement la vidéo et l'audio sur IPad en raison du trafic important que vous pouvez utiliser sur les réseaux mobiles. Je n'utiliserais pas la lecture automatique pour le contenu en ligne. Pour les sites HTML hors connexion, c'est une fonctionnalité intéressante et c'est ce que je l'ai utilisé pour.

Voici une solution de "faux clic javascript": http://www.roblaplaca.com/examples/html5AutoPlay/

Code Copié-Collé du site:

<script type="text/javascript"> 
        function fakeClick(fn) {
            var $a = $('<a href="#" id="fakeClick"></a>');
                $a.bind("click", function(e) {
                    e.preventDefault();
                    fn();
                });

            $("body").append($a);

            var evt, 
                el = $("#fakeClick").get(0);

            if (document.createEvent) {
                evt = document.createEvent("MouseEvents");
                if (evt.initMouseEvent) {
                    evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                    el.dispatchEvent(evt);
                }
            }

            $(el).remove();
        }

        $(function() {
            var video = $("#someVideo").get(0);

            fakeClick(function() {
                video.play();
            });
        });

        </script> 

Ce n'est pas ma source. Je l'ai trouvé il y a quelque temps et j'ai testé le code sur un IPad et un IPhone avec IOS 3.2.X.

33
Fa11enAngel

Je tiens également à souligner que la raison pour laquelle vous ne pouvez pas faire cela est une décision commerciale prise par Apple), et non une décision technique. En d'autres termes, il n'y avait aucune justification technique rationnelle pour Apple pour désactiver le son des applications Web sur l'iPod Touch.Il s'agit d'un périphérique Wi-Fi uniquement, et non d'un téléphone susceptible d'engendrer des frais de bande passante coûteux, de sorte que l'argument n'a aucun mérite pour cet appareil. Gestion du réseau WiFi, mais tout problème de bande passante sur mon réseau WiFi est ma préoccupation, pas celle d’Apple.

En outre, si ce qui les intéressait vraiment était d'éviter une consommation de bande passante excessive et indésirable, ils fourniraient un paramètre permettant aux utilisateurs de choisir les sons des applications Web. En outre, ils feraient quelque chose pour empêcher les sites Web de consommer une bande passante équivalente par d'autres moyens. Mais il n'y a pas de telles restrictions. Un site Web peut télécharger d’énormes fichiers à l’arrière-plan et Apple se moque bien de cela. Enfin, je pense que les sons peuvent être téléchargés de toute façon, donc NO BANDWIDTH IS RÉCUPÉRÉ RÉELLEMENT! Apple ne leur permet tout simplement pas de jouer automatiquement sans interaction de l'utilisateur, ce qui les rend inutilisables pour les jeux, ce qui est bien sûr leur intention réelle.

Apple a bloqué le son car ils ont commencé à remarquer que les applications HTML5 peuvent être aussi performantes que les applications natives, voire davantage. Si vous voulez du son dans les applications Web, vous devez faire pression Apple pour cesser d'être anticoncurrentiel comme Microsoft. Aucun problème technique ne peut être résolu ici.

102
Rick M

Apple rejette de manière agaçante de nombreuses normes Web HTML5 sur ses appareils iOS, pour diverses raisons professionnelles. En fin de compte, vous ne pouvez pas pré-charger ou lire automatiquement des fichiers son avant un événement tactile, il ne lit qu'un son à la fois et ne prend pas en charge Ogg/Vorbis. Cependant, j’ai trouvé une solution de contournement intéressante pour vous permettre d’avoir un peu plus de contrôle sur l’audio.

<audio id="soundHandle" style="display:none;"></audio>

<script type="text/javascript">

var soundHandle = document.getElementById('soundHandle');

$(document).ready(function() {
    addEventListener('touchstart', function (e) {
        soundHandle.src = 'audio.mp3';
        soundHandle.loop = true;
        soundHandle.play();
        soundHandle.pause();
    });
});

</script>

Fondamentalement, vous commencez à lire le fichier audio dès le premier événement tactile, puis vous le suspendez immédiatement. Désormais, vous pouvez utiliser les commandes soundHandle.play () et soundHandle.pause () tout au long de votre Javascript et contrôler l'audio sans événement tactile. Si vous pouvez chronométrer parfaitement, faites simplement une pause après la fin du son. Ensuite, lors de la prochaine lecture, la lecture reprendra au début. Cela ne résoudra pas tous les dégâts que Apple a créés ici, mais c’est une solution.

27
kaleazy

Depuis iOS 4.2.1, ni le faux clic ni l'astuce .load () ne fonctionneront pour lire automatiquement l'audio sur n'importe quel périphérique iOS. La seule option que je connaisse est de demander à l'utilisateur d'exécuter une action de clic et de commencer la lecture dans le gestionnaire d'événements click sans en encapsulant l'appel .play () dans un environnement asynchrone (ajax, setTimeout, etc.).

Quelqu'un s'il vous plaît dites-moi si je me trompe. Avant la mise à jour la plus récente, j’avais des échappatoires pour iPad et iPhone. Elles semblent toutes avoir été fermées.

23
David Gouldin

Je confirme que l'audio ne fonctionne pas comme décrit (au moins sur un iPad sous 4.3.5). Le problème spécifique est que l'audio ne se chargera pas dans une méthode asynchrone (ajax, événement timer, etc.) mais sera lu s'il a été préchargé. Le problème est que la charge doit être sur un événement déclenché par l'utilisateur. Donc, si vous pouvez avoir un bouton pour que l'utilisateur lance le jeu, vous pouvez faire quelque chose comme:

function initSounds() {
    window.sounds = new Object();
    var sound = new Audio('assets/sounds/clap.mp3');
    sound.load();
    window.sounds['clap.mp3'] = sound;
}

Ensuite, pour le jouer, par exemple dans une requête ajax, vous pouvez faire

function doSomething() {
    $.post('testReply.php',function(data){
        window.sounds['clap.mp3'].play();
    }); 
}

Ce n’est pas la meilleure solution, mais cela peut aider, en particulier si le coupable est la fonction de chargement dans un événement non déclenché par l’utilisateur.

Edit: J'ai trouvé l'explication d'Apple et cela concerne iOS 4+: http://developer.Apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html

9
Jacob Mouka

Essayez d'appeler la méthode .load () avant la méthode .play () sur la balise audio ou video ... qui sera respectivement HTMLAudioElement ou HTMLVideoElement. C'était la seule façon pour moi que cela fonctionne sur l'iPad!

7
Brian Brown

La lecture automatique ne fonctionne pas sur l'iPad ou l'iPhone, que ce soit pour les balises vidéo ou audio. Ceci est une restriction définie par Apple) pour économiser la bande passante de l'utilisateur.

5
Andrew

Il me semble que la réponse à cette question est (au moins maintenant) clairement documentée sur le docs Safari HTML5 :

Contrôle utilisateur des téléchargements sur les réseaux cellulaires

Dans Safari sur iOS (pour tous les appareils, y compris l'iPad), où l'utilisateur peut être sur un réseau cellulaire et être facturé par unité de données, le préchargement et la lecture automatique sont désactivés. Aucune donnée n'est chargée jusqu'à ce que l'utilisateur l'ait initiée. Cela signifie que les méthodes JavaScript play () et load () sont également inactives jusqu'à ce que l'utilisateur lance la lecture, à moins que la méthode play () ou load () ne soit déclenchée par une action de l'utilisateur. En d'autres termes, un bouton de lecture lancé par l'utilisateur fonctionne, mais pas l'événement onLoad = "play ()".

Cela lit le film: <input type="button" value="Play" onClick="document.myMovie.play()">

Cela ne fait rien sur iOS: <body onLoad="document.myMovie.play()">

5
Adrian

Je suis perplexe à ce sujet tout en développant un prototype d’application Web rapide sous iOS4.2 (dev build). La solution est en fait assez simple. Notez que vous ne pouvez pas sembler avoir déjà la balise dans votre page HTML, vous devez en fait l'insérer dynamiquement dans le document (notez que cet exemple utilise Prototype 1.7 pour une plus grande netteté du code Javascript):

this.soundFile = new Element("audio", {id: "audio-1", src: "audio-1.mp3", controls: ""});
document.body.appendChild(this.soundFile);
this.soundFile.load();
this.soundFile.play();

Comme vous n'avez pas défini de contrôleur, il ne devrait pas être nécessaire de faire une astuce avec CSS pour le cacher/le positionner hors écran.

Cela semble fonctionner parfaitement.

2
Jon Jardine

Apple ne prend pas complètement en charge la norme, mais il existe une solution de contournement. Leur justification est une congestion du réseau cellulaire, peut-être parce que vous allez atterrir sur des pages qui lisent des fichiers audio aléatoires. Ce comportement ne change pas lorsqu'un appareil passe en wifi, peut-être par souci de cohérence. À propos, ces pages sont de toute façon une mauvaise idée. Vous ne devriez pas essayer de mettre une bande son sur chaque page Web. C'est juste faux. :)

l'audio html5 sera lu s'il est démarré à la suite d'une action de l'utilisateur. Le chargement d'une page ne compte pas. Vous devez donc restructurer votre application Web pour en faire une application tout-en-une page. Au lieu d'un lien qui ouvre une page qui lit l'audio, vous avez besoin de ce lien pour le lire sur la page en cours, sans changement de page. Cette règle "interaction utilisateur" s'applique aux méthodes html5 que vous pouvez appeler sur un élément audio ou vidéo. Les appels sont renvoyés sans aucun effet s'ils sont déclenchés automatiquement au chargement de la page, mais ils fonctionnent lorsqu'ils sont appelés à partir de gestionnaires d'événements.

2
bmidgley

Ma solution est de déclencher un événement tactile réel dans un menu précédent. Ils ne vous obligent évidemment pas à utiliser une interface de lecteur spécifique. Pour mes besoins, cela fonctionne bien. Si vous n'avez pas d'interface existante à utiliser, autant que vous soyez, vous êtes dérouté. Peut-être que vous pourriez essayer des événements d'inclinaison ou quelque chose ...

1
Luke Stanley

Si vous créez un élément audio en utilisant:

var a = new Audio("my_audio_file.wav");

Et ajoutez un écouteur d'événement suspend via:

a.addEventListener("suspend", function () {console.log('suspended')}, false);

Ensuite, chargez le fichier dans Safari mobile (iPad ou iPhone). Vous verrez alors le message "suspendu" enregistré dans la console du développeur. Selon la spécification HTML5, cela signifie que "l'agent utilisateur ne récupère pas intentionnellement les données multimédia, mais ne télécharge pas l'intégralité de la ressource multimédia".

L'appel d'un a.load () ultérieur, le test de l'événement "canplay" puis l'utilisation de a.play () semblent être une méthode appropriée pour déclencher automatiquement le son.

1
Vince

J'ai géré cela en attachant un gestionnaire d'événements pour tous les événements pour lesquels vous êtes autorisé à déclencher l'audio sur l'élément body, ce qui déclenche la lecture de tous les éléments audio html avec lecture automatique.

var mobile = /iPad|iPhone|iPod|Android/.test(navigator.userAgent) && !window.MSStream;
if (mobile) {
    $('body').on('touchstart click doubleclick keydown', function() {
        $("audio[autoplay='autoplay']").each(
            function(){
                this.play();
                this.removeAttribute('autoplay');
            });
    });
}
0
Andrew Hancox

Cela semble fonctionner:

<html>
<title>
iPad Sound Test  - Auto Play
</title>
</head>
<body>
<audio id="audio" src="mp3test.mp3" controls="controls" loop="loop">
</audio>
<script type="text/javascript"> 
    window.onload = function() {
        var audioPlayer = document.getElementById("audio");
        audioPlayer.load();
        audioPlayer.play();
    };
    </script> 

</body>
</html>

Voir en action ici: http://www.johncoles.co.uk/ipad/test/1.html (Archivé)

Depuis iOS 4.2, cela ne fonctionne plus. Désolé.

0
John Coles

Fonctionne avec jQuery, testé sur Ipad v.5.1.1

$('video').get(0).play();

Vous devez ajouter/supprimer l'élément vidéo de la page.

0
Adrian