Comment gérer "Exception DOMException non interceptée (en promesse): play () a échoué car l'utilisateur n'a pas d'abord interagi avec le document." sur le bureau avec Chrome 66?

122

Je reçois le message d'erreur.

Uncaught (in promise) DOMException: play () a échoué car l'utilisateur n'a pas d'abord interagi avec le document.

..lorsque vous essayez de lire une vidéo sur un bureau à l'aide de la version 66 de Chrome.

J'ai trouvé une annonce dont la lecture a commencé automatiquement sur un site Web, mais en utilisant le code HTML suivant:

<video
    title="Advertisement"
    webkit-playsinline="true"
    playsinline="true"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="http://ds.serving-sys.com/BurstingRes/Site-2500/Type-16/1ff26f6a-aa27-4b30-a264-df2173c79623.mp4"
    autoplay=""></video>

Donc , est-circuitant le bloqueur autoplay de V66 Chrome vraiment aussi facile que d' ajouter les webkit-playsinline="true", playsinline="true"et les autoplay=""attributs de l' <video>élément? Y a-t-il des conséquences négatives à cela?

Steven
la source
2
Je pense que le jeu en ligne est une chose iOS.
Josh Lee

Réponses:

125

Pour que la lecture automatique sur les éléments html 5 fonctionne après la mise à jour de chrome 66, il vous suffit d'ajouter la mutedpropriété à l'élément vidéo.

Donc, votre vidéo HTML actuelle

<video
    title="Advertisement"
    webkit-playsinline="true"
    playsinline="true"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
    autoplay=""></video>

Juste des besoins muted="muted"

<video
    title="Advertisement"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
    autoplay="true"
    muted="muted"></video>

Je pense que la mise à jour de chrome 66 essaie d'arrêter les onglets créant un bruit aléatoire sur les onglets des utilisateurs. C'est pourquoi la propriété muet fait à nouveau fonctionner la lecture automatique.

Joe
la source
après m'être arraché les cheveux pendant une heure. cela a résolu mon problème
Andy McCormick
Existe-t-il un moyen d'activer l'audio juste après le début de la lecture de la vidéo? La suppression de l' muteattribut ou de l' attribut de paramètre volumen'aide pas.
nikitahl
Sur MacOs Chrome Version 74.0.3729.131, les deux extraits donnent un écran noir
Kamil Kiełczewski
@ KamilKiełczewski La vidéo montrait un écran noir car le srcn'était pas valide. J'ai mis à jour l'extrait srcpour que la vidéo soit lue automatiquement.
Joe
2
Je devais faire à la muted="true"place
tgordon18
13

La meilleure solution que j'ai trouvée est de couper le son de la vidéo

HTML

<video loop muted autoplay id="videomain">
  <source src="videoname.mp4" type="video/mp4">
</video>
Moiz
la source
12
  1. Ouvert chrome://settings/content/sound
  2. Réglage Aucun geste d'utilisateur est requis
  3. Relancer Chrome
Ming
la source
6
Modifications de la politique de lecture automatique. Cliquez sur moi
Ming
4
Il ne sert qu'aux développeurs de tester localement le comportement de la politique de lecture automatique de Chrome. developer.google.com/web/updates/2017/09/…
Tuan Nguyen
5
J'ai trouvé que l'indicateur de ligne de commande --autoplay-policy=no-user-gesture-requiredest le moyen par programme d'atteindre ce paramètre.
nickiaconis
27
Cela ne fonctionne que pour votre navigateur, tout le monde sera toujours affecté
koosa
39
Qui vote pour cette réponse? Ce n'est pas superuser.com. Une solution pour votre machine locale ne peut pas être une réponse acceptable.
adripanico
11

Répondre à la question actuelle ...
Non, il ne suffit pas d'avoir ces attributs, pour pouvoir lire automatiquement un média avec audio, vous devez avoir un geste d'utilisateur enregistré sur votre document.

Mais cette limitation est très faible: si vous avez reçu ce geste d'utilisateur sur le document parent et que votre vidéo a été chargée à partir d'une iframe, vous pouvez la lire ...

Alors prenons par exemple ce violon , qui n'est que

<video src="myvidwithsound.webm" autoplay=""></video>

Au premier chargement, et si vous ne cliquez nulle part, il ne fonctionnera pas, car nous n'avons encore enregistré aucun événement.
Mais une fois que vous avez cliqué sur le bouton "Exécuter" , le document parent (jsfiddle.net) a reçu un geste de l'utilisateur, et maintenant la vidéo est lue, même si elle est techniquement chargée dans un document différent.

Mais l'extrait de code suivant, puisqu'il vous oblige à cliquer sur le bouton Exécuter l'extrait de code , sera lu automatiquement.

<video src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" autoplay=""></video>

Cela signifie que votre annonce a probablement pu être lue, car vous avez fourni un geste d'utilisateur vers la page principale.


Maintenant, notez que Safari et Mobile Chrome ont des règles plus strictes que cela et vous obligeront à déclencher au moins une fois la play()méthode par programme sur l' élément <video>ou à <audio>partir du gestionnaire d'événements utilisateur lui-même.

Et si vous n'avez pas besoin de l'audio, ne le joignez tout simplement pas à votre média, une vidéo avec seulement une piste vidéo est également autorisée à être lue automatiquement et réduira l'utilisation de la bande passante de votre utilisateur.

Kaiido
la source
11

Pour moi (dans le projet Angular), ce code a aidé:

En HTML, vous devez ajouter autoplay muted

Dans JS / TS

playVideo() {
    const media = this.videoplayer.nativeElement;
    media.muted = true; // without this line it's not working although I have "muted" in HTML
    media.play();
}
Eutrepe
la source
1
Absolument vrai et incroyable, même avec Ng8, dernière version Angular. Angular ne se soucie tout simplement pas de ce qui se passe sur le modèle HTML du composant!
Pedro Ferreira
2
Et, avec la nouvelle façon d'utiliser Angular, @ViewChild()vous devez définir l'option sttatic sur true: @ViewChild('videoPlayer', {static: true}) videoplayer: ElementRef; video: HTMLVideoElement; Et puis: this.video = this.videoplayer.nativeElement;@ngOnInit()
Pedro Ferreira
1
C'était mon problème, mis en sourdine en HTML est complètement ignoré et j'ai dû le forcer par JS. + 1M à votre réponse après des jours de recherche
Ignacio Bustos
C'est la bonne réponse dans mon cas, a parfaitement fonctionné
Harry .Naeem
Wow, je ne peux pas croire que j'avais réellement besoin de la mise en sourdine côté javascript pour les vues post-chargement Angular SSR. Pendant tout ce temps, j'ai pensé que le HTML était le problème.
arao6
7

Essayez d'utiliser l'événement mousemove lisentner

var audio = document.createElement("AUDIO")
document.body.appendChild(audio);
audio.src = "./audio/rain.m4a"

document.body.addEventListener("mousemove", function () {
    audio.play()
})
時 雨 初
la source
4

Étendre l'élément DOM, gérer l'erreur et dégrader en douceur

Ci-dessous, j'utilise la fonction prototype pour envelopper la fonction de lecture DOM native, saisir sa promesse, puis la dégrader en bouton de lecture si le navigateur lève une exception. Cette extension résout les lacunes du navigateur et est plug-n-play dans n'importe quelle page avec la connaissance du ou des éléments cibles.

// JavaScript
// Wrap the native DOM audio element play function and handle any autoplay errors
Audio.prototype.play = (function(play) {
return function () {
  var audio = this,
      args = arguments,
      promise = play.apply(audio, args);
  if (promise !== undefined) {
    promise.catch(_ => {
      // Autoplay was prevented. This is optional, but add a button to start playing.
      var el = document.createElement("button");
      el.innerHTML = "Play";
      el.addEventListener("click", function(){play.apply(audio, args);});
      this.parentNode.insertBefore(el, this.nextSibling)
    });
  }
};
})(Audio.prototype.play);

// Try automatically playing our audio via script. This would normally trigger and error.
document.getElementById('MyAudioElement').play()

<!-- HTML -->
<audio id="MyAudioElement" autoplay>
  <source src="https://www.w3schools.com/html/horse.ogg" type="audio/ogg">
  <source src="https://www.w3schools.com/html/horse.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>
Bernesto
la source
C'est une approche très intelligente, qui ne rompt aucune politique (puisque la lecture ne démarre pas de toute façon), et évite d'avoir des erreurs. +1
loretoparisi
3

Dans mon cas, je devais faire ça

 // Initialization in the dom
 // Consider the muted attribute
 <audio id="notification" src="path/to/sound.mp3" muted></audio>


 // in the js code unmute the audio once the event happened
 document.getElementById('notification').muted = false;
 document.getElementById('notification').play();
Shobi
la source
2

Chrome a besoin d'une interaction de l'utilisateur pour que la vidéo soit lue automatiquement ou lue via js (video.play ()). Mais l'interaction peut être de n'importe quelle sorte, à tout moment. Si vous cliquez simplement sur aléatoire sur la page, la vidéo sera lue automatiquement. J'ai résolu alors, en ajoutant un bouton (uniquement sur les navigateurs Chrome) qui dit "activer la lecture automatique de la vidéo". Le bouton ne fait rien, mais le simple fait de cliquer dessus est l'interaction utilisateur requise pour toute autre vidéo.

Alarik
la source
1

J'ai rencontré une erreur similaire lors de la tentative de lecture d'un fichier audio. Au début, cela fonctionnait, puis cela a cessé de fonctionner lorsque j'ai commencé à utiliser la markForCheckméthode de ChangeDetector dans la même fonction pour déclencher un nouveau rendu lorsqu'une promesse se résout (j'ai eu un problème avec le rendu de vue).

Quand je changé le markForCheckpour detectChangeselle a commencé à travailler à nouveau. Je ne peux vraiment pas expliquer ce qui s'est passé, j'ai juste pensé laisser ça ici, peut-être que ça aiderait quelqu'un.

Roi James Enejo
la source
1

Vous devriez avoir ajouté un mutedattribut à l'intérieur de votre videoElementpour que votre code fonctionne comme prévu. Regardez ci-dessous.

<video id="IPcamerastream" muted="muted" autoplay src="videoplayback%20(1).mp4" width="960" height="540"></video>

N'oubliez pas d'ajouter un lien vidéo valide comme source

GNETO DOMINIQUE
la source
0

J'ai rencontré des problèmes pour jouer sur un téléphone Android. Après quelques essais, j'ai découvert que lorsque Data Saver est activé, il n'y a pas de lecture automatique:

Il n'y a pas de lecture automatique si le mode d' économie de données est activé. Si le mode Économiseur de données est activé, la lecture automatique est désactivée dans les paramètres Média.

La source

Je fais
la source
-6

Tapez Chrome: // flags dans la barre d'adresse

Recherche: lecture automatique

Politique de lecture automatique

Politique utilisée pour décider si l'audio ou la vidéo est autorisé à être lu automatiquement.

- Mac, Windows, Linux, Chrome OS, Android

Définissez ceci sur " Aucun geste de l'utilisateur n'est requis "

Relancez Chrome et vous n'avez à modifier aucun code

DARKSETH23
la source
24
Vous ne pouvez pas demander à chaque utilisateur de modifier les paramètres.
Ashish Jhanwar
2
Cela pourrait résoudre le problème pour certaines personnes (kiosques, sites Web privés et locaux ...), mais le drapeau a été supprimé dans Chrome 76. Maintenant, la seule solution est cette réponse
Milan Švehla