web-dev-qa-db-fra.com

HTML5 Audio ne peut pas lire via Javascript sauf s'il est déclenché manuellement une fois

J'essaie d'obtenir un petit fichier son à jouer automatiquement en utilisant une balise et javascript pour l'initier.

<audio id="denied" preload="auto" controls="false">
    <source src="sound/denied.wav" />
 </audio>

Et puis via javascript, au moment opportun:

$('#denied')[0].play()

Fonctionne bien sur Chrome sur mon bureau. Dans Android 4.1.1, le son ne sera pas lu, sauf si je clique sur "play" sur les commandes audio HTML5 avant javascript essaie de le lire.

Donc, fondamentalement, le navigateur Android (stock ou Dolphin) ne lira pas l'audio à moins que l'utilisateur ne l'initialise à un moment donné avant le javascript. Est-ce prévu? Y a-t-il un moyen de contourner cela?

35
Jonah H.

Eh bien, pour mes besoins, voici ce que j'ai fait:

Heureusement, avant que l'utilisateur puisse déclencher le comportement pour démarrer l'audio, il doit cliquer sur un bouton. J'ai réglé le volume de l'élément sur 0,0 et je l'ai "joué" quand ils cliquent sur ce bouton.

Une fois le son joué en silence, je redéfinis simplement la propriété de volume sur 1.0, et il joue sans intervention de l'utilisateur très bien.

10
Jonah H.

Dans mon cas, c'était une solution simple:
https://stackoverflow.com/a/28011906/4622767
Copiez et collez ceci dans votre chrome:

chrome://flags/#autoplay-policy

Mon application Web a de nombreuses pages rechargées, je ne peux donc pas forcer l'utilisateur à appuyer sur un bouton à chaque fois; mais c'est pour un usage interne, donc je peux forcer les utilisateurs à utiliser chrome et configurer cette option.

15
FRa

Je sais que dans un safari mobile, tout appel javascript à play () doit être dans la même pile d'appels qu'un événement de clic initialisé tilisateur. Usurper le clic avec un déclencheur javascript ne fonctionnera pas non plus.

Sur mon nexus 7, je peux confirmer qu'à moins que le javascript ait été déclenché par un clic d'utilisateur, il ne joue pas.

9
Rob Lynch

Le principal problème est que le son (sur iOS et Android) doit être déclenché par un clic de l'utilisateur. Ma solution de contournement était très simple. Attachez la audio.play() à un écouteur d'événements de clic, puis suspendez-la immédiatement. À partir de là, le son fonctionne parfaitement.

var myAudio = new Audio('assets/myAudio.mp3');
...
button.addEventListener("click", function() {
    myAudio.play();
    myAudio.pause();
    ...
});
6
Eli Mashiah

Voici un article de blog sur la raison et comment le surmonter en chargeant tous les fichiers audio lors de la première interaction avec l'utilisateur et en les lisant plus tard de manière programmée: https://blog.foolip.org/2014/02/ 10/media-playback-restrictions-in-blink / En adoptant cette approche, un petit module javascript est disponible sur GitHub https://github.com/MauriceButler/simple-audio

J'ai essayé cette approche simple par moi-même - travaillé de manière transparente et génial!

4
makechaos

Heureusement pour moi, l'application html5 sur laquelle je travaille n'a besoin de fonctionner qu'en Android 4.1, mais si vous essayez de créer quelque chose de multiplateforme, vous devrez l'adapter légèrement. régler le volume à 0,0 puis revenir ou la lecture automatique sur le contrôle a fonctionné pour moi. J'ai également essayé de couper le son et cela n'a pas fonctionné non plus. Ensuite, je me suis dit, que se passerait-il si je définissais la durée et ne jouais qu'une minuscule quantité du fichier? Voici encore une autre script piraté qui a réellement fonctionné:

function myAjaxFunction() {
  clearTimeout(rstTimer); //timer that resets the page to defaults
  var snd=document.getElementById('snd');
  snd.currentTime=snd.duration-.01; //set seek position of audio near end
  snd.play(); //play the last bit of the audio file
  snd.load(); //reload file
  document.getElementById('myDisplay').innerHTML=defaultDisplay;
  var AJAX=new XMLHttpRequest(); //won't work in old versions of IE
  sendValue=document.getElementById('myInput').value;
  AJAX.open('GET', encodeURI('action.php?val='+sendValue+'&fn=find'), true);
  AJAX.send();
  AJAX.onreadystatechange=function() {
    if (AJAX.readyState==4 && AJAX.status==200) {
      document.getElementById('myDisplay').innerHTML=AJAX.responseText;
      if (document.getElementById('err')) { //php returns <div id="err"> if fail
        rstTimer = setTimeout('reset()', 5000); //due to error reset page in 5 seconds
        snd.play(); //play error sound
        document.getElementById('myInput').value=''; //clear the input
      }
    }
  }
}
3
MaKR

Vous n'avez pas besoin de JavaScript pour la lecture automatique, et je vois plusieurs problèmes dans votre code:

<audio id="denied" preload="auto" controls="false">
    <source src="sound/denied.wav" />
</audio>

Je le changerais (en HTML5, vous n'avez pas besoin de la syntaxe attribute = "value" dans certains cas, c'est pour XHTML):

<audio id="denied" autobuffer controls autoplay>
    <source src="sound/denied.wav" />
</audio>
<a href="#" id="play-button">play!</a>

Dans la lecture automatique iOS est désactivée, vous devez cliquer sur le bouton de lecture ou mettre un événement de clic utilisateur sur des contrôles personnalisés comme celui-ci avec JavaScript:

var audio = document.getElementById('denied');
var button = document.getElementById('play-button');
button.addEventListener('click',function(){
    audio.play();
});

ou avec jQuery:

$('#play-button').click(function(){ audio.play(); });}

Modifier

Gardez à l'esprit que HTML5 est une technologie assez récente (au moins certaines fonctionnalités), donc la compatibilité et les fonctionnalités du navigateur changent de temps en temps.

J'encourage tout le monde à se tenir informé de l'état actuel, car parfois les choses commencent à être moins dépendantes du piratage, ou l'inverse.

Un bon point de départ: http://caniuse.com/#feat=audio (vérifiez les onglets en bas).

Aussi pour une solution audio globale, je recommande d'utiliser SoundManager2 bibliothèque JS

3
aesede

Ça m'est aussi arrivé. Voici comment j'ai piraté cela:

J'ai réglé l'audio sur autoplay et réglé le volume sur 0. Lorsque j'en ai besoin pour jouer, j'utilise la méthode load() et elle s'exécutera automatiquement. C'est un fichier mp3 léger et il joue toutes les heures/deux heures, donc cela fonctionne bien pour moi.

2
Marks

J'ai rencontré le même problème dans mon application. Le scénario d'utilisation de mon application était le suivant:

  1. cliquez sur le bouton pour afficher un tableau avec des informations (action de l'utilisateur)
  2. afficher le tableau et actualiser les données qu'il contient par AJAX
  3. jouer du son lorsque les données ont été modifiées

Heureusement, j'ai eu l'action de l'utilisateur (étape 1), j'ai donc pu "initier" le son par lui, puis le jouer en javascript sans que l'action de l'utilisateur soit nécessaire. Voir le code.

HTML

<audio id="kohoutAudio">
    <source src="views/images/kohout.mp3">
</audio>

<button id="btnShow">Show table</button>

Javascript

$("#btnShow").click(function () {
    //some code to show the table
    //initialize the sound
    document.getElementById('kohoutAudio').play();
    document.getElementById('kohoutAudio').pause();
});

function announceChange(){
    document.getElementById('kohoutAudio').play();
};
2
Luboš Miřatský