Lecture automatique de fichiers audio sur un iPad avec HTML5

88

J'essaie d'obtenir un fichier audio à lire automatiquement dans Safari sur un iPad. Si je vais sur la page en utilisant Safari sur mon Mac, ça va. Sur l'iPad, la lecture automatique ne fonctionne pas.

Milesmeow
la source
1
Ce n'est pas une réponse mais juste une observation. Lorsque j'ai mis WireShark sur ma connexion à l'iPad, j'ai remarqué qu'il ne serait pas lu automatiquement mais que le fichier Wave était toujours téléchargé. Le premier HTTP Get demande simplement les 2 premiers octets du fichier, mais l'iPad demande ensuite le reste du fichier Wave dans d'autres requêtes Get. Ce qui est encore plus étrange, c'est que lorsque vous cliquez sur le bouton «Lecture» du composant Audio, l'iPad recharge à nouveau le fichier Wave.
Javamann le

Réponses:

34

MISE À JOUR: Ceci est un hack et cela ne fonctionne plus sur IOS 4.X et au-dessus. Celui-ci fonctionnait sur IOS 3.2.X.

Ce n'est pas vrai. Apple ne souhaite pas lire automatiquement la vidéo et l'audio sur l'iPad en raison de la quantité élevée de trafic 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 ligne, c'est une fonctionnalité intéressante et c'est pour cela que je l'ai utilisée.

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

Copiez et collez le code 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. J'ai trouvé cela il y a quelque temps et testé le code sur un iPad et un iPhone avec IOS 3.2.X.

Fa11enAngel
la source
1
Voici une autre solution de contournement: codeblog.co/getting-autoplay-working-on-ios Je viens de vérifier que cela fonctionne sur iPad avec iOS 3.2.
Ciryon
49
Ne perdez pas votre temps avec cela car il ne fonctionne plus avec iOS 4+
jcampbell1
104

Je voudrais également souligner que la raison pour laquelle vous ne pouvez pas le faire est une décision commerciale prise par Apple, et non une décision technique. Pour wit, il n'y avait aucune justification technique rationnelle pour Apple de désactiver le son des applications Web sur l'iPod Touch. Il s'agit uniquement d'un appareil WiFi, pas d'un téléphone qui peut entraîner des frais de bande passante coûteux, de sorte que cet argument n'a aucun mérite pour cet appareil. Ils peuvent dire qu'ils aident à la 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.

De plus, si ce qui leur tenait vraiment à cœur était d'éviter une consommation de bande passante excessive et indésirable, ils fourniraient un paramètre permettant aux utilisateurs d'accepter 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 des fichiers énormes en arrière-plan encore et encore et Apple s'en fiche. Et enfin, je crois que les sons peuvent quand même être téléchargés, donc AUCUNE BANDE PASSANTE N'EST RÉELLEMENT SAUVEGARDÉE! 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 véritable intention.

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

Rick M
la source
N'est-ce pas pareil pour Android?
Rune Jeppesen
1
@Rune Jeppesen Non. J'ai une application PhoneGap / Cordova qui a un lecteur audio et qui fonctionne parfaitement sur Android. La seule raison pour laquelle j'ai atteint ce sujet ici dans StackOverflow est les restrictions d'iOS concernant la lecture audio.
Ulysses Alves
Maintenant, Chrome pour Android et pour ordinateur de bureau ont une politique similaire à iOS
Ore4444
28

Apple rejette de manière agaçante de nombreuses normes Web HTML5 sur ses appareils iOS, pour diverses raisons commerciales. En fin de compte, vous ne pouvez pas pré-charger ou lire automatiquement les fichiers audio avant un événement tactile, il ne joue qu'un son à la fois et il ne prend pas en charge Ogg / Vorbis. Cependant, j'ai trouvé une solution de contournement astucieuse 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>

En gros, vous commencez la lecture du fichier audio dès le tout premier événement tactile, puis vous le mettez en pause immédiatement. Maintenant, vous pouvez utiliser les commandes soundHandle.play () et soundHandle.pause () dans tout votre Javascript et contrôler l'audio sans événements tactiles. Si vous pouvez parfaitement le chronométrer, faites juste une pause juste après la fin du son. Ensuite, la prochaine fois que vous le rejouerez, il reviendra au début. Cela ne résoudra pas tout le gâchis qu'Apple a créé ici, mais c'est une solution.

kaleazy
la source
Je n'ai pas encore essayé cela, mais si cela fonctionne vraiment, c'est génial.
courtsimas
3
Étonné que plus de gens ne soient pas intéressés par cela.
aoeu256
Cela fonctionne-t-il toujours? Je peux sembler être en mesure de faire fonctionner cela ...
zillaofthegods
@MastaBaba Cela devrait être la réponse acceptée. Pourquoi? Cela ne répond pas à la question, car c'est ce que demande OP: j'essaie d'obtenir un fichier audio à lire automatiquement dans Safari et cette réponse n'aide pas avec la lecture automatique.
débute
23

À partir d'iOS 4.2.1, ni le faux clic ni l'astuce .load () ne fonctionneront pour lire automatiquement l'audio sur n'importe quel appareil iOS. La seule option que je connaisse est que l'utilisateur exécute réellement une action de clic et commence la lecture dans le gestionnaire d'événements de clic sans encapsuler l'appel .play () dans quoi que ce soit d'asynchrone (ajax, setTimeout, etc.).

Quelqu'un s'il vous plaît dites-moi si je me trompe. J'avais des failles de travail pour iPad et iPhone avant la mise à jour la plus récente, et elles semblent toutes avoir été fermées.

David Gouldin
la source
5
Je peux vérifier que mon code fonctionnait pour lire automatiquement l'audio sans intervention de l'utilisateur sur l'iPad et l'iPod touch, avant la version 4.2.1. Je viens de mettre à jour mon iPad vers la version 4.2.1 aujourd'hui (au milieu du test de mon préchargeur audio) et j'ai regardé avec horreur alors qu'il cessait de fonctionner.
Jason Kester
2
Sur <video>avec 4.2.1, je l' ai vérifié que tant que le .load()puis .play()viennent dans un synchrone gestionnaire clic / robinet, il fonctionnera. Sinon, cela échoue.
N Rohler
1
Il semble que le contrôle programmatique des éléments multimédias (audio et vidéo) soit activé après l'interaction de l'utilisateur par élément multimédia . C'est-à-dire que si vous avez les éléments audio A et B et que vous commencez la lecture de A via le code dans le cadre d'un gestionnaire d'événements click (ou touch), cela fonctionne. Mais cela ne signifie pas que vous pouvez ultérieurement commencer la lecture de B en dehors de la portée d'un gestionnaire d'événements Click. Traitez les éléments multimédias dans iOS comme un singleton et échangez les sources sur une instance plutôt que de multiplier les instances par les sources.
Tim Erickson
9

Je confirme que l'audio ne fonctionne pas comme décrit (au moins sur iPad exécutant 4.3.5). Le problème spécifique est que l'audio ne se chargera pas dans une méthode asynchrone (ajax, événement de minuterie, etc.) mais il 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 la lecture, 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 lire, 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 en sachant que 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 affecte iOS 4+: http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html

Jacob Mouka
la source
C'est la réponse d'or. Vous pouvez remplir l'objet de sons avec plusieurs sons. Et après l'appel ajax en cas de succès / erreur, jouez ce que vous voulez. Fonctionne pour moi sur tous les appareils! Gros tnx !!!
Andris
7

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

Brian Brown
la source
Selon les documents des développeurs Apple, ni .load ni .play ne fonctionneront sauf lorsqu'ils sont déclenchés par un utilisateur.
Jeffrey Van Alstine
5

La lecture automatique ne fonctionne pas sur l'iPad ou l'iPhone pour la vidéo ou les balises audio. Il s'agit d'une restriction mise en place par Apple pour économiser la bande passante des utilisateurs.

Andrew
la source
5

Il me semble que la réponse à cette question est (au moins maintenant) clairement documentée sur la documentation 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, la précharge et la lecture automatique sont désactivées. Aucune donnée n'est chargée tant que l'utilisateur ne le lance pas. 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 un événement onLoad = "play ()".

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

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

Adrian
la source
2

J'ai été perplexe à ce sujet lors du développement d'un prototype d'application Web rapide sous iOS4.2 (version de développement). La solution est en fait assez simple. Notez que vous ne pouvez pas sembler déjà avoir la balise dans votre page HTML, vous devez en fait insérer la balise dans le document de manière dynamique (notez que cet exemple utilise Prototype 1.7 pour un peu plus de snazziness 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 quoi que ce soit d'astuce avec CSS pour le masquer / le positionner hors de l'écran.

Cela semble fonctionner parfaitement.

Jon Jardine
la source
2

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

html5 audio 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. Au lieu d'un lien qui ouvre une page qui lit de l'audio, vous avez besoin de ce lien pour la lire sur la page en cours, sans changement de page. Cette règle d '"interaction utilisateur" s'applique aux méthodes html5 que vous pouvez appeler sur un élément audio ou vidéo. Les appels retournent 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.

bmidgley
la source
1

Ma solution est le déclenchement d'un événement tactile réel dans un menu précédent. Ils ne vous obligent pas à utiliser une interface de lecteur spécifique bien sûr. Pour mes besoins, cela fonctionne bien. Si vous n'avez pas d'interface existante à utiliser, afaik vous êtes enculé. Vous pourriez peut-être essayer des événements d'inclinaison ou quelque chose comme ça ...

Luke Stanley
la source
1

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

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

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

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

Et puis chargez le fichier dans Safari mobile (iPad ou iPhone), vous verrez le 'suspendu' se connecter dans la console du développeur. Selon la spécification HTML5, cela signifie: «L'agent utilisateur ne récupère pas intentionnellement les données multimédias, mais n'a pas téléchargé l'intégralité de la ressource multimédia».

Appeler un a.load () ultérieur, tester l'événement "canplay" puis utiliser a.play () semble être une méthode appropriée pour déclencher automatiquement le son.

Vince
la source
J'ai essayé cela mais cela ne semble pas fonctionner. Toute mise à jour? sandbox.coolaj86.info/html5-audio-tag-ios4.html
coolaj86
0

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.

Adrian
la source
3
Ne fonctionne pas sur iPad 1 iOS 5.1.1 ... bien que fonctionne sur iPod 6.0 et iPhone
morgan_il
0

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');
            });
    });
}
Andrew Hancox
la source
0

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>

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

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

John Coles
la source
@ NisseEngström Il me semble que le fichier mp3 n'est pas archivé non plus, donc cette modification du lien d'archive est assez discutable.
Au revoir StackExchange
@FrankerZ: Il y a un lien mp3? J'ai manqué ça. Merci.
Nisse Engström