Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The mediaElement.play() method returns a promise that is rejected

Tags:

I can't play my video on mobile Browsers. When using Safari Remote Debugging, i get the following issue:

Unhandled Promise Rejection: AbortError: The operation was aborted.

I find this solution: https://developers.google.com/web/updates/2017/06/play-request-was-interrupted

But i don't know, how can i use it in my code to fix the problem.

<video muted id="video" class="absolute right-0 bottom-0 min-w-full min-h-full w-auto" controls>
    <source src="/path/to/video.mp4" type="video/mp4">
</video>
let video = document.getElementbyId('video');
let video_cta = document.getElementbyId('video_cta');

//this doesn't fix my problem
var videoPromise = video.play();

if (videoPromise != undefined) {
    videoPromise.then(function(_) {
      video.pause();
      video.currentTime = 0;
  });
}

//start video after click the button
video_cta.addEventListener('click' function() {
    video.play()
})
like image 692
Niklas Avatar asked May 02 '19 13:05

Niklas


People also ask

What does a rejected Promise Return?

The Promise. reject() method returns a Promise object that is rejected with a given reason.

How do you handle rejection promises?

We must always add a catch() , otherwise promises will silently fail. In this case, if thePromise is rejected, the execution jumps directly to the catch() method. You can add the catch() method in the middle of two then() methods, but you will not be able to break the chain when something bad happens.

Why do Promises get rejected?

A Promise rejection indicates that something went wrong while executing a Promise or an async function. Rejections can occur in several situations: throwing inside an async function or a Promise executor/then/catch/finally callback, when calling the reject callback of an executor , or when calling Promise.

Is it possible to have the video element play automatically without user interaction?

Today, most desktop browsers will always allow web pages to begin <video> or <audio> playback via JavaScript without user interaction.


1 Answers

  • First thing is that autoplay attribute is needed.

    <video src='...' controls mutedautoplay></video>

  • When videoPromise is the reference to the video and call to the .play() method, it will work within a Promise.

    const videoPromise = document.querySelector('video').play();

  • Also there is a dependency in OP code .getElementById() was misspent:

    let video = document.getElementbyId('video');
    let video_cta = document.getElementbyId('video_cta');

  • The Google article provided in OP also mentions that the <source> tag will not handle a reject properly:

    Use

    <video src='...'></video>

    Not

    <video> <source src='...'> </video>

  • This should stop the error message:

    Unhandled Promise Rejection: AbortError: The operation was aborted.

Demo 1 uses a Promise and method .then(). Demo 2 uses async/await. The async function is wrapped in an IIFE (Immediately Invoked Function Expression)

Demo 1

Promise

let cta = document.querySelector('#cta');

const videoPromise = document.querySelector('video').play();

if (videoPromise != undefined) {
  videoPromise.then(_ => {
video.play();
  });
}

cta.addEventListener('click', function() {
  video.play();
});
<video src="https://storage04.dropshots.com/photos6000/photos/1381926/20170326/005609.mp4" id="video" class="absolute right-0 bottom-0 min-w-full min-h-full w-auto" controls autoplay muted></video>
<button id='cta'>CTA</button>

Demo 2

async/await

let cta = document.querySelector('#cta');

const video = document.querySelector('video');

(function() {
  playMedia();
})();

async function playMedia() {
  try {
    await video.play();
  } catch (err) {}
}

cta.addEventListener('click', function() {
  video.play();
});
<video src="https://storage04.dropshots.com/photos6000/photos/1381926/20170326/005609.mp4" id="video" class="absolute right-0 bottom-0 min-w-full min-h-full w-auto" controls autoplay muted></video>
<button id='cta'>CTA</button>
like image 67
zer00ne Avatar answered Nov 22 '22 19:11

zer00ne