How to prevent "The request to play () was interrupted by an error calling pause ()"?

I made a site where, if the user clicks, he plays the sound. To prevent the sound from overlapping, I had to add the code:

n.pause(); n.currentTime = 0; n.play(); 

But this causes an error: The play() request was interrupted by a call to pause()
Rise up every time an audio event is triggered immediately after another trigger. The sound still plays fine, but I want this error message to constantly appear. Any ideas?

+96
javascript html google-chrome audio
Apr 22 '16 at 20:55
source share
24 answers

I also recently ran into this problem - it could be a race condition between play() and pause() . There seems to be a link to this problem, or something related here .

As @Patrick points out , pause does not return a promise (or anything else), so the solution above will not work. Although there are no pause() documents in MDN, the WC3 project for Media Elements says:

media.pause ()

Sets the paused attribute to true, loading the media resource if necessary.

That way, you can also check the paused attribute in their timeout callback.

Based on this great SO answer , here you can check if the video is actually playing (or not), so you can safely run play () without error.

 var isPlaying = video.currentTime > 0 && !video.paused && !video.ended && video.readyState > 2; if (!isPlaying) { video.play(); } 

Otherwise, @Patrick's answer should work.

+72
Apr 27 '16 at 18:37
source share
β€” -

After hours of searching and working, I found the perfect solution .

 // Initializing values var isPlaying = true; // On video playing toggle values video.onplaying = function() { isPlaying = true; }; // On video pause toggle values video.onpause = function() { isPlaying = false; }; // Play video function function playVid() { if (video.paused && !isPlaying) { video.play(); } } // Pause video function function pauseVid() { if (!video.paused && isPlaying) { video.pause(); } } 

After that, you can switch the play / pause as fast as you can, it will work correctly .

+60
Nov 01 '16 at 23:16
source share

I ran into this problem and have a case where I needed to press pause (), then play (), but when using pause (). then () I get undefined.

I found that if I started playing for 150 ms after a pause, he solved the problem. (Hope Google gets better soon)

 playerMP3.volume = 0; playerMP3.pause(); //Avoid the Promise Error setTimeout(function () { playerMP3.play(); }, 150); 
+18
May 11 '16 at 19:48
source share

try

 n.pause(); n.currentTime = 0; var nopromise = { catch : new Function() }; (n.play() || nopromise).catch(function(){}); ; 
+5
Dec 22 '16 at 16:08
source share

I just posted an article about this exact issue at https://developers.google.com/web/updates/2017/06/play-request-was-interrupted , which tells you what exactly is happening and how to fix it .

+4
Jun 16 '17 at 8:24
source share

This solution helped me:

 n.cloneNode(true).play(); 
+3
Apr 10 '17 at 11:10
source share

Depending on how complex the solution you want, this may be useful:

 var currentPromise=false; //Keeps track of active Promise function playAudio(n){ if(!currentPromise){ //normal behavior n.pause(); n.currentTime = 0; currentPromise = n.play(); //Calls play. Will store a Promise object in newer versions of chrome; //stores undefined in other browsers if(currentPromise){ //Promise exists currentPromise.then(function(){ //handle Promise completion promiseComplete(n); }); } }else{ //Wait for promise to complete //Store additional information to be called currentPromise.calledAgain = true; } } function promiseComplete(n){ var callAgain = currentPromise.calledAgain; //get stored information currentPromise = false; //reset currentPromise variable if(callAgain){ playAudio(n); } } 

This is a bit overkill, but helps when processing promises in unique scenarios.

+2
Jun 29 '16 at 0:14
source share
The solutions offered here either didn't work for me, or where they were big, so I looked for something else and found the solution suggested by @dighan at bountysource.com/issues/

So here is the code that solved my problem:

 var media = document.getElementById("YourVideo"); const playPromise = media.play(); if (playPromise !== null){ playPromise.catch(() => { media.play(); }) } 

It still causes an error in the console, but at least the video is playing :)

+2
Jan 24 '17 at 7:48
source share

I fixed this with the code below:

When you want to play, use the following:

 var video_play = $('#video-play'); video_play.on('canplay', function() { video_play.trigger('play'); }); 

Similarly, when you want to pause:

 var video_play = $('#video-play'); video_play.trigger('pause'); video_play.on('canplay', function() { video_play.trigger('pause'); }); 
+1
Oct 27 '16 at 2:50
source share

Perhaps the best solution for this, as I understand it. Spec says how @JohnnyCoder is quoted:

media.pause ()

Sets the pause attribute to true, loading the media resource if necessary.

-> Download

 if (videoEl.readyState !== 4) { videoEl.load(); } videoEl.play(); 

indicates the state of readiness of the environment HAVE_ENOUGH_DATA = 4

Basically upload a video if it is not already uploaded. The mentioned error occurred to me because the video was not uploaded. Perhaps better than using a timeout.

+1
Jan 25 '17 at 22:38
source share

all errors removed: (typescript)

 audio.addEventListener('canplay', () => { audio.play(); audio.pause(); audio.removeEventListener('canplay'); }); 
+1
May 15 '17 at 4:09 a.m.
source share

With streaming I ran into the same problem. and my fix is ​​this. From the html TAG video, make sure to remove β€œauto play ” and use this code below to play.

 if (Hls.isSupported()) { var video = document.getElementById('pgVideo'); var hls = new Hls(); hls.detachMedia(); hls.loadSource('http://wpc.1445X.deltacdn.net/801885C/lft/apple/TSONY.m3u8'); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play(); }); hls.on(Hls.Events.ERROR, function (event, data) { if (data.fatal) { switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: // when try to recover network error console.log("fatal network error encountered, try to recover"); hls.startLoad(); break; case Hls.ErrorTypes.MEDIA_ERROR: console.log("fatal media error encountered, try to recover"); hls.recoverMediaError(); break; default: // when cannot recover hls.destroy(); break; } } }); } 
+1
May 29 '17 at 5:21 a.m.
source share

Chrome returns Promise in the latest versions. Otherwise, simply:

  n.pause(); n.currentTime = 0; setTimeout(function() {n.play()}, 0); 
+1
Oct 17 '17 at 20:24
source share

I have the same problem, finally I solve:

 video.src = 'xxxxx'; video.load(); setTimeout(function() { video.play(); }, 0); 
+1
Nov 05 '17 at 3:12
source share

This piece of code has been fixed for me!

Modified Code @JohnnyCoder

HTML:

  <video id="captureVideoId" muted width="1280" height="768"></video> <video controls id="recordedVideoId" muted width="1280" style="display:none;" height="768"></video> 

JS:

  var recordedVideo = document.querySelector('video#recordedVideoId'); var superBuffer = new Blob(recordedBlobs, { type: 'video/webm' }); recordedVideo.src = window.URL.createObjectURL(superBuffer); // workaround for non-seekable video taken from // https://bugs.chromium.org/p/chromium/issues/detail?id=642012#c23 recordedVideo.addEventListener('loadedmetadata', function () { if (recordedVideo.duration === Infinity) { recordedVideo.currentTime = 1e101; recordedVideo.ontimeupdate = function () { recordedVideo.currentTime = 0; recordedVideo.ontimeupdate = function () { delete recordedVideo.ontimeupdate; var isPlaying = recordedVideo.currentTime > 0 && !recordedVideo.paused && !recordedVideo.ended && recordedVideo.readyState > 2; if (isPlaying) { recordedVideo.play(); } }; }; } }); 
+1
Feb 15 '18 at 20:40
source share

Here is another solution if the reason is that your video download is very slow and the video is not buffered:

if (videoElement.state.paused) { videoElement.play(); } else if (!isNaN(videoElement.state.duration)) { videoElement.pause(); }

0
Apr 05 '17 at 6:19 06:19
source share

It seems that many programmers have run into this problem. The solution should be pretty simple. media element returns Promise from actions, therefore

 n.pause().then(function(){ n.currentTime = 0; n.play(); }) 

gotta do the trick

0
Jul 05 '17 at 17:50
source share

here is the solution from googler blog:

 var video = document.getElementById('#video') var promise = video.play() //chrome version 53+ if(promise){ promise.then(_=>{ video.pause() }) }else{ video.addEventListener('canplaythrough', _=>{ video.pause() }, false) } 
0
Jul 15 '17 at 5:14
source share

All new browsers support video for automatic playback with muted audio, so please install something like this

 <video autoplay muted="muted" loop id="myVideo"> <source src="https://wrglob.net/Coastline-3581.mp4" type="video/mp4"> </video> 

The video URL must match the SSL status, if your site works with https, then the video URL must also be in https and the same for HTTP

0
Feb 08 '19 at 10:11
source share

I ran into the same problem and resolved it by dynamically adding an autoplay attribute rather than using play() . Thus, the browser decided to play without running into a race condition.

-one
Jul 23 '16 at 16:38
source share

Trying to get auto- play() video in a loop by calling play() when it ends, the timeout workaround doesn't work for me (no matter how long the timeout is).

But I found that by cloning / replacing a video with jQuery, when it ends, it will loop properly.

For example:

 <div class="container"> <video autoplay> <source src="video.mp4" type="video/mp4"> </video> </div> 

and

 $(document).ready(function(){ function bindReplay($video) { $video.on('ended', function(e){ $video.remove(); $video = $video.clone(); bindReplay($video); $('.container').append($video); }); } var $video = $('.container video'); bindReplay($video); }); 

I am using Chrome 54.0.2840.59 (64-bit) / OS X 10.11.6

-one
Oct 20 '16 at 11:00
source share

I think they updated the html5 video and some codecs are deprecated. It worked for me after removing the codecs.

In the example below:

 <video> <source src="sample-clip.mp4" type="video/mp4; codecs='avc1.42E01E, mp4a.40.2'"> <source src="sample-clip.webm" type="video/webm; codecs='vp8, vorbis'"> </video> must be changed to <video> <source src="sample-clip.mp4" type="video/mp4"> <source src="sample-clip.webm" type="video/webm"> </video> 
-one
Oct 26 '16 at 6:51
source share

When you see an error with Uncaught (in promise) it just means that you need to process the promise with .catch() . In this case .play() returns a promise. You can decide whether you want to register a message, run some code or do nothing, but as long as you have .catch() , the error will disappear.

 var n = new Audio(); n.pause(); n.currentTime = 0; n.play().catch(function(e) { // console.log('There was an error', e); }); 
-one
Dec 22 '16 at 18:43
source share

I used a trick to counter this problem. Define a global variable var audio;

and in the check function

 if(audio === undefined) { audio = new Audio(url); } 

and in the stop function

 audio.pause(); audio = undefined; 

so the next call is audio.play , the sound will be ready from '0' currentTime

I used

 audio.pause(); audio.currentTime =0.0; 

but it didn’t work. Thank.

-5
Aug 05 '16 at 12:15
source share



All Articles