developer.chrome.com
Open in
urlscan Pro
2a00:1450:400a:808::2011
Public Scan
Submitted URL: https://goo.gl/LdLk22
Effective URL: https://developer.chrome.com/blog/play-request-was-interrupted/
Submission: On October 06 via manual from US — Scanned from DE
Effective URL: https://developer.chrome.com/blog/play-request-was-interrupted/
Submission: On October 06 via manual from US — Scanned from DE
Form analysis
0 forms found in the DOMText Content
Skip to content Home Docs Blog Articles Home Docs Blog Articles Blog DOMEXCEPTION - THE PLAY() REQUEST WAS INTERRUPTED Published on Wednesday, June 14, 2017 • Updated on Thursday, May 6, 2021 François Beaufort Dives into Chromium source code Table of contents * What is causing this * How to fix it * Play promise support * Danger zone * <source> within <video> makes play() promise never rejects Did you just stumble upon this unexpected media error in the Chrome DevTools JavaScript Console? Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). or Uncaught (in promise) DOMException: The play() request was interrupted by a new load request. You're in the right place then. Have no fear. I'll explain what is causing this and how to fix it. # WHAT IS CAUSING THIS Here's some JavaScript code below that reproduces the "Uncaught (in promise)" error you're seeing: Don't <video id="video" preload="none" src="https://example.com/file.mp4"></video> <script> video.play(); // <-- This is asynchronous! video.pause(); </script> The code above results in this error message in Chrome DevTools: _Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). As the video is not loaded due to preload="none", video playback doesn't necessarily start immediately after video.play() is executed. Moreover since Chrome 50, a play() call on an a <video> or <audio> element returns a Promise, a function that returns a single result asynchronously. If playback succeeds, the Promise is fulfilled and the playing event is fired at the same time. If playback fails, the Promise is rejected along with an error message explaining the failure. Now here's what happening: 1. video.play() starts loading video content asynchronously. 2. video.pause() interrupts video loading because it is not ready yet. 3. video.play() rejects asynchronously loudly. Since we're not handling the video play Promise in our code, an error message appears in Chrome DevTools. Note: Calling video.pause() isn't the only way to interrupt a video. You can entirely reset the video playback state, including the buffer, with video.load() and video.src = ''. # HOW TO FIX IT Now that we understand the root cause, let's see what we can do to fix this. First, don't ever assume a media element (video or audio) will play. Look at the Promise returned by the play function to see if it was rejected. It is worth noting that the Promise won't fulfill until playback has actually started, meaning the code inside the then() will not execute until the media is playing. Do Example: Autoplay <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> Do Example: Play & Pause <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> That's great for this simple example but what if you use video.play() to be able to play a video later? I'll tell you a secret. You don't have to use video.play(), you can use video.load() and here's how: Do Example: Fetch & Play <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> Warning Don't make your onButtonClick function asynchronous with the async keyword. You'll lose the "user gesture token" required to allow your video to play later. # PLAY PROMISE SUPPORT At the time of writing, HTMLMediaElement.play() returns a promise in Chrome, Edge, Firefox, Opera, and Safari. # DANGER ZONE # <SOURCE> WITHIN <VIDEO> MAKES PLAY() PROMISE NEVER REJECTS For <video src="not-existing-video.mp4"\>, the play() promise rejects as expected as the video doesn't exist. For <video><source src="not-existing-video.mp4" type='video/mp4'></video>, the play() promise never rejects. It only happens if there are no valid sources. Chromium Bug Last updated: Thursday, May 6, 2021 Improve article Table of contents * What is causing this * How to fix it * Play promise support * Danger zone * <source> within <video> makes play() promise never rejects Follow us Contribute * File a bug * View source Related content * web.dev * Case studies * Podcasts Connect * Twitter * YouTube * GitHub Chrome Firebase All products Privacy Terms Choose language ENGLISH (en) Content available under the CC-BY-SA-4.0 license We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience. More details Ok, Got it.