DOMException: Se interrumpió la solicitud play().

François Beaufort
François Beaufort

¿Te encontraste con este error inesperado de medios en las Herramientas para desarrolladores de Chrome? Consola de JavaScript?

o

Estás en el lugar correcto. No se preocupe. Explicaré la causa del problema y cómo solucionarlo.

¿A qué se debe este problema?

A continuación, puedes ver parte del código JavaScript que reproduce el error "Un detected (in Promise)" que ves:

Qué no debes hacer
<video id="video" preload="none" src="https://example.com/file.mp4"></video>

<script>
  video.play(); // <-- This is asynchronous!
  video.pause();
</script>

El código anterior muestra este mensaje de error en las Herramientas para desarrolladores de Chrome:

_Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().

Como el video no se carga debido a preload="none", la reproducción no se reproduce deben comenzar inmediatamente después de que se ejecute video.play().

Además, desde Chrome 50, una llamada play() en un <video> o <audio> el elemento muestra una promesa, una función que devuelve un solo resultado de forma asíncrona. Si la reproducción se realiza con éxito, la promesa se cumple y el El evento playing se activa al mismo tiempo. Si la reproducción falla, la promesa se rechazadas junto con un mensaje de error que explica el error.

Esto es lo que sucede:

  1. video.play() comienza a cargar contenido de video de manera asíncrona.
  2. video.pause() interrumpe la carga del video porque aún no está listo.
  3. video.play() rechaza en voz alta de forma asíncrona.

Como no manejamos la promesa de reproducción de video en nuestro código, aparece un mensaje de error en Herramientas para desarrolladores de Chrome.

Cómo resolverlo

Ahora que entendemos la causa raíz, veamos qué podemos hacer para solucionar esto.

En primer lugar, nunca des por sentado que se reproducirá un elemento multimedia (video o audio). Mira La promesa que devuelve la función play para ver si se rechazó Sí vale la pena señalar que la promesa no se cumplirá hasta que la reproducción haya iniciado, lo que significa que el código dentro de then() no se ejecutará hasta que el contenido está sonando.

Qué debes hacer

Ejemplo: Reproducción automática

<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>
Qué debes hacer

Ejemplo: Jugar y Pausar

<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>

Eso es genial para este ejemplo simple, pero ¿qué sucede si usas video.play() para reproducir un video más tarde?

Te contaré un secreto. No es necesario que uses video.play(). video.load(). A continuación, te indicamos cómo hacerlo:

Qué debes hacer

Ejemplo: Recuperar Reproducir

<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>

Compatibilidad con Play Promise

Al momento de escribir, HTMLMediaElement.play() muestra una promesa en Chrome, Edge, Firefox, Opera y Safari.

Zona de peligro

<source> dentro de <video> hace que la promesa de play() nunca se rechace.

En <video src="not-existing-video.mp4"\>, la promesa play() se rechaza como se espera, ya que el video no existe. Para <video><source src="not-existing-video.mp4" type='video/mp4'></video>, la promesa play() nunca rechaza. Solo sucede si no hay fuentes válidas.

Error de Chromium