programing tip

"pause () 호출로 인해 play () 요청이 중단되었습니다"오류를 방지하는 방법은 무엇입니까?

itbloger 2020. 8. 18. 07:25
반응형

"pause () 호출로 인해 play () 요청이 중단되었습니다"오류를 방지하는 방법은 무엇입니까?


사용자가 클릭하면 소리가 나는 웹 사이트를 만들었습니다. 사운드가 겹치는 것을 방지하기 위해 코드를 추가해야했습니다.

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

그러나 그로 인해 오류가 발생합니다. The play() request was interrupted by a call to pause()
사운드 이벤트가 다른 트리거 직후에 트리거 될 때마다 나타납니다. 소리는 여전히 잘 재생되지만이 오류 메시지가 계속해서 표시되는 것을 방지하고 싶습니다. 어떤 아이디어?


최근에도이 문제가 발생했습니다.이 문제는 play()사이의 경쟁 조건 일 수 있습니다 pause(). 이 문제에 대한 언급이 있거나 여기에 관련된 내용이있는 것 같습니다 .

으로 @Patrick는 지적, pause위의 반응 용액 작동하지 않습니다, 약속 (또는 아무것도를) 반환하지 않습니다. MDN에는에 문서가 없지만 Media Elementspause() 에 대한 WC3 초안 에서 다음 과 같이 말합니다.

media.pause ()

paused 속성을 true로 설정하고 필요한 경우 미디어 리소스를로드합니다.

따라서 paused타임 아웃 콜백에서 속성을 확인할 수도 있습니다 .

이 훌륭한 SO 답변을 기반으로 비디오가 실제로 재생되는지 여부를 확인할 수있는 방법이 있으므로 오류없이 안전하게 play ()를 트리거 할 수 있습니다.

var isPlaying = video.currentTime > 0 && !video.paused && !video.ended 
    && video.readyState > 2;

if (!isPlaying) {
  video.play();
}

그렇지 않으면 @Patrick대답 이 작동합니다.


몇 시간의 검색과 작업 끝에 완벽한 해결책을 찾았습니다 .

// 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();
    }
}

그 후에 가능한 한 빨리 재생 / 일시 중지전환 할 수 있으며 제대로 작동 합니다.


나는이 문제를 겪었고 pause () 다음 play ()를 눌러야했지만 pause (). then () 사용할 때 정의되지 않은 경우가 있습니다.

일시 중지 후 150ms 재생을 시작하면 문제가 해결된다는 것을 알았습니다. (곧 Google이 수정되기를 바랍니다.)

playerMP3.volume = 0;
playerMP3.pause();

//Avoid the Promise Error
setTimeout(function () {      
   playerMP3.play();
}, 150);

시도 해봐

n.pause();
n.currentTime = 0;
var nopromise = {
   catch : new Function()
};
(n.play() || nopromise).catch(function(){}); ;

이 정확한 문제에 대한 기사를 https://developers.google.com/web/updates/2017/06/play-request-was-interrupted 에 게시하여 정확히 무슨 일이 일어나고 있으며 어떻게 해결 해야하는지 알려 주었습니다 .


이 솔루션은 저에게 도움이되었습니다.

n.cloneNode(true).play();

원하는 솔루션의 복잡성에 따라 다음이 유용 할 수 있습니다.

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);
    }
}

이것은 약간 과잉이지만 독특한 시나리오에서 Promise를 처리 할 때 도움이됩니다.


여기에서 제안한 솔루션은 저에게 적합하지 않았거나 큰 곳에서 작동하지 않았으므로 다른 것을 찾고 있었고 bountysource.com/issues/에서 @dighan이 제안한 솔루션을 찾았습니다.

내 문제를 해결 한 코드는 다음과 같습니다.

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

여전히 콘솔에 오류가 발생하지만 적어도 비디오가 재생 중입니다. :)


내가 알아 낸 것처럼 이것에 대한 더 나은 해결책 일 것입니다. Spec은 @JohnnyCoder에서 인용 한대로 말합니다.

media.pause ()

paused 속성을 true로 설정하고 필요한 경우 미디어 리소스를로드합니다.

->로드

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

미디어 HAVE_ENOUGH_DATA = 4의 준비 상태를 나타냅니다.

기본적으로 아직로드되지 않은 경우에만 비디오를로드합니다. 동영상이로드되지 않았기 때문에 언급 된 오류가 발생했습니다. 시간 제한을 사용하는 것보다 나을 수도 있습니다.


모든 오류 제거 : (typescript)

audio.addEventListener('canplay', () => {
    audio.play();
    audio.pause();
    audio.removeEventListener('canplay');
}); 

라이브 스트리밍에서 나는 같은 문제에 직면했습니다. 내 수정은 이것입니다. html video TAG에서 "autoplay"제거 하고 아래 코드를 사용하여 재생하십시오.

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;
                    }
                }
            });
        }

Chrome은 최신 버전에서 Promise를 반환합니다. 그렇지 않으면 간단히 :

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

나는 같은 문제가 있으며 마침내 다음과 같이 해결합니다.

video.src = 'xxxxx';
video.load();
setTimeout(function() {
  video.play();
}, 0);

이 코드는 나를 위해 수정되었습니다!

@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();
                }
            };
        };
       }
      });

다음 코드로 수정했습니다.

플레이하려면 다음을 사용하십시오.

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

마찬가지로 일시 중지를 원할 때 :

var video_play = $('#video-play');
video_play.trigger('pause');

video_play.on('canplay', function() {
  video_play.trigger('pause');
});

비디오 다운로드가 매우 느리고 비디오가 버퍼링되지 않았기 때문에 다른 해결책이 있습니다.

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


많은 프로그래머가이 문제에 직면 한 것 같습니다. 해결책은 아주 간단해야합니다. 미디어 요소 Promise는 작업에서 반환 되므로

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

트릭을해야한다


다음은 googler 블로그의 솔루션입니다.

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

All new browser support video to be auto-played with being muted only so please put Something like the this

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

URL of video should match the SSL status if your site is running with https then video URL should also in https and same for HTTP


I ran into the same issue and resolved it by dynamically adding the autoplay attribute rather than using play(). That way the browser figured out to play without running into the race condition.


Trying to get an autoplaying video to loop by calling play() when it ends, the timeout workaround did not work for me (however long the timeout is).

But I discovered that by cloning/replacing the video with jQuery when it ended, it would 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'm using Chrome 54.0.2840.59 (64-bit) / OS X 10.11.6


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

In the below example:

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


When you see an error with Uncaught (in promise) This just means that you need to handle the promise with a .catch() In this case, .play() returns a promise. You can decide if you want to log a message, run some code, or do nothing, but as long as you have the .catch() the error will go away.

var n = new Audio();
n.pause();
n.currentTime = 0;
n.play().catch(function(e) {
  // console.log('There was an error', e);
});

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

and in the function check

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

and in the stop function

audio.pause();
audio = undefined;

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

I used

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

but it didn't work. Thanks.

참고URL : https://stackoverflow.com/questions/36803176/how-to-prevent-the-play-request-was-interrupted-by-a-call-to-pause-error

반응형