Ti sei appena imbattuto in questo errore multimediale imprevisto in Chrome DevTools Console JavaScript?
o
Allora sei nel posto giusto. Non temere. Ti spiegheremo la causa e come risolvere il problema.
Causa
Di seguito è riportato del codice JavaScript che riproduce il messaggio "Uncaught (in Promessa)" che ricevi:
<video id="video" preload="none" src="https://example.com/file.mp4"></video> <script> video.play(); // <-- This is asynchronous! video.pause(); </script>
Il codice riportato sopra genera questo messaggio di errore in Chrome DevTools:
_Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
Poiché il video non è stato caricato a causa dell'errore preload="none"
, la riproduzione del video non
iniziano necessariamente subito dopo l'esecuzione di video.play()
.
Inoltre, a partire da Chrome 50, una chiamata play()
su un dispositivo <video>
o <audio>
restituisce una funzione Promise, ovvero una funzione che restituisce un singolo risultato
in modo asincrono. Se la riproduzione va a buon fine, la Promessa viene rispettata e le
playing
evento viene attivato contemporaneamente. Se la riproduzione non va a buon fine, la Promessa viene
viene rifiutata insieme a un messaggio che spiega l'errore.
Ecco cosa sta succedendo:
video.play()
avvia il caricamento dei contenuti video in modo asincrono.video.pause()
interrompe il caricamento del video perché non è ancora pronto.video.play()
rifiuta in modo asincrono.
Dal momento che non gestiamo la riproduzione del video Promise nel nostro codice, viene visualizzato un messaggio di errore viene visualizzato in Chrome DevTools.
Come risolvere il problema
Ora che abbiamo capito la causa principale, vediamo cosa possiamo fare per risolvere il problema.
Innanzitutto, non dare per scontato che venga riprodotto un elemento multimediale (video o audio). Guarda
la promessa restituita dalla funzione play
per vedere se è stata rifiutata. È
vale la pena notare che la Promessa non si completa finché la riproduzione
avviato, il che significa che il codice all'interno di then()
non verrà eseguito fino a quando
è in riproduzione.
Esempio: riproduzione automatica
<video id="video" preload="none" src="https://example.com/file.mp4"></video> <script> // Show loading animation. var playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(_ => { // Automatic playback started! // Show playing UI. }) .catch(error => { // Auto-play was prevented // Show paused UI. }); } </script>
Esempio: Play & Mettere in pausa
<video id="video" preload="none" src="https://example.com/file.mp4"></video> <script> // Show loading animation. var playPromise = video.play(); if (playPromise !== undefined) { playPromise.then(_ => { // Automatic playback started! // Show playing UI. // We can now safely pause video... video.pause(); }) .catch(error => { // Auto-play was prevented // Show paused UI. }); } </script>
Questo è ottimo per questo semplice esempio, ma cosa succede se usi video.play()
per
in grado di riprodurre un video in un secondo momento?
Ti dirò un segreto. Non è necessario utilizzare video.play()
, puoi usare
video.load()
ed ecco come fare:
Esempio: Recupera e Riproduzione
<video id="video"></video> <button id="button"></button> <script> button.addEventListener('click', onButtonClick); function onButtonClick() { // This will allow us to play video later... video.load(); fetchVideoAndPlay(); } function fetchVideoAndPlay() { fetch('https://example.com/file.mp4') .then(response => response.blob()) .then(blob => { video.srcObject = blob; return video.play(); }) .then(_ => { // Video playback started ;) }) .catch(e => { // Video playback failed ;( }) } </script>
Assistenza nelle promesse di Google Play
Al momento della scrittura, HTMLMediaElement.play()
restituisce una promessa in
Chrome, Edge, Firefox, Opera e Safari.
Zona pericolosa
<source>
in <video>
fa la promessa di play()
non rifiutare mai
Per <video src="not-existing-video.mp4"\>
, la promessa play()
viene rifiutata come
previsto perché il video non esiste. Per <video><source
src="not-existing-video.mp4" type='video/mp4'></video>
, la promessa play()
non rifiuta mai. Questo accade solo se non ci sono fonti valide.