कैसे रोकने के लिए "खेलने () अनुरोध को रोक ()" त्रुटि के लिए एक कॉल द्वारा बाधित किया गया था?


107

मैंने एक वेबसाइट बनाई जहां अगर उपयोगकर्ता क्लिक करता है, तो यह एक ध्वनि बजाता है। ओवरलैपिंग से ध्वनि को रोकने के लिए, मुझे कोड जोड़ना होगा:

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

लेकिन यह त्रुटि का कारण बनता है: The play() request was interrupted by a call to pause()
प्रत्येक बार ध्वनि की घटना को एक ट्रिगर के ठीक बाद ट्रिगर किया जाता है। आवाज़ अभी भी ठीक खेलता है, लेकिन मैं इस त्रुटि संदेश को लगातार पॉप अप करने से रोकना चाहता हूं। कोई विचार?


क्या यह एक त्रुटि है, या एक नोटिस का अधिक है?
डंडविस

यह एक त्रुटि है, यहां पूरी त्रुटि है: अनकैप्ड (वादे में) DOMException: नाटक () अनुरोध को रोकने के लिए एक कॉल द्वारा बाधित किया गया था ()।
ओवेन एम

7
यह एक नया बग है, इसके बारे में चिंता न करें: bugs.chromium.org/p/chromium/issues/detail?id=593273
dandavis

3
इसके लिए आसान तय यह है कि एक-दूसरे के ठीक बाद प्ले या पॉज़ न करें। विराम देने या खेलने के लिए निर्धारित करने के बजाय मीडिया की घटनाओं का उपयोग करें। उदाहरण: onCanPlay()। ये सभी जवाब गंदे हैक्स हैं।
मार्टिन डॉसन

1
मुझे विपरीत समस्या थी। मैंने n.play() तब कोशिश की n.pause()। उसके लिए, यह वेब फंडामेंटल लेख समाधान का वर्णन करता है। tl; dr:n.play().then(() => { n.pause()})
टोटमेडली

जवाबों:


84

मैंने हाल ही में इस मुद्दे का सामना किया है - यह play()और के बीच एक दौड़ की स्थिति हो सकती है pause()। ऐसा लगता है कि इस मुद्दे का संदर्भ है, या यहां से संबंधित कुछ है

जैसा कि @ पैट्रिक बताता है, pauseएक वादा (या कुछ भी) वापस नहीं करता है, इसलिए उपरोक्त समाधान काम नहीं करेगा। हालांकि MDN pause()में मीडिया तत्वों के लिए WC3 ड्राफ्ट में डॉक्स नहीं है , यह कहता है:

media.pause ()

यदि आवश्यक हो तो मीडिया संसाधन को लोड करने के लिए रुकी हुई विशेषता को सही पर सेट करता है।

तो कोई भी pausedउनके टाइमआउट कॉलबैक में विशेषता की जांच कर सकता है ।

इस महान एसओ जवाब के आधार पर , यहां एक तरीका है जिससे आप जांच सकते हैं कि वीडियो वास्तव में खेल रहा है (या नहीं), इसलिए आप त्रुटि के बिना किसी नाटक () को सुरक्षित रूप से ट्रिगर कर सकते हैं।

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

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

अन्यथा, @ पैट्रिक का जवाब काम करना चाहिए।


1
जैसा कि @ रीजेंसी-सॉफ़्टवेयर कहता है, पॉज़ विधि एक वादा नहीं लौटाती है (.pause () पर डॉक्स नहीं हैं), लेकिन सिर्फ "अपरिभाषित"। तो यह समाधान केवल खेलने पर () तो ठहराव () मामलों पर लागू किया जा सकता है।
स्प्लिट

जानकारी के लिए धन्यवाद - मैंने अपना जवाब अपडेट किया कि क्या @regency सॉफ्टवेयर पोस्ट किया गया था, जो सही था, और उसके पास एक काम का समाधान :-) भी था।
जॉनीकोडर

आप प्रतीक्षा समय के रूप में 150ms पर कैसे पहुंचे? लगता है कि एक क्रोम मुद्दा है: bugs.chromium.org/p/chromium/issues/detail?id=593273
कनेक्ट

टाइमआउट कारण के लिए @Rearios सॉफ़्टवेयर का उत्तर देखें । मैंने उनके उत्तर पर विस्तार किया, जो एक अच्छा समाधान था। साथ ही, मेरा उत्तर आपके द्वारा उत्तर की शुरुआत में दिए गए लिंक का संदर्भ देता है।
जॉनीकोडर

यह वीडियो स्ट्रीमिंग के लिए काम नहीं करेगा। अगर मैंने WebRTC वीडियो को इनिशियलाइज़ किया है, तो यह अभी भी कंसोल को अपवाद देता है।
Stepan Yakovenko

70

घंटों तक काम करने और काम करने के बाद, मुझे सही समाधान मिला ।

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

उसके बाद, आप जितनी तेजी से खेल / ठहराव टॉगल कर सकते हैं, यह ठीक से काम करेगा


1
इस तरह मैंने समस्या को हासिल किया। मुझे लगता है कि टाइमआउट पर भरोसा करने की तुलना में यह बहुत बेहतर उपाय है
मैल्कोर

@Malcor धन्यवाद, यह हर किसी के लिए समस्या का समाधान हो
नेबोज्सा Sapic

क्या कुछ कृपया इस उत्तर पर एक प्रतिबन्ध लगा सकते हैं ताकि इसे तेजी से बढ़ाया जा सके?
१२olor१ at को जोड़ना

1
इसे सही उत्तर के रूप में चिह्नित क्यों नहीं किया गया है? निश्चित रूप से यह एक समाधान है, टाइमआउट के साथ हैक नहीं।
जीरॉन-डायोविस

15
दो चर क्यों आवश्यक हैं? मैं यह नहीं कह रहा हूं कि यह एक बुरा समाधान है। बस इसे टटोलने की कोशिश की जा रही है।
benevolentprof

20

मैंने इस मुद्दे को मारा है, और एक ऐसा मामला है जहां मुझे पॉज़ () हिट करने की आवश्यकता है, तब खेलें () लेकिन जब पॉज़ () का उपयोग कर रहे हों तब () मैं अपरिभाषित हो जाता हूं।

मैंने पाया कि अगर मैंने पॉज़ करने के बाद 150ms खेलना शुरू किया, तो यह समस्या हल हो गई। (उम्मीद है कि गूगल जल्द ही ठीक कर देगा)

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

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

यदि आप 150ms का मतलब है? मैंने कुछ अलग मूल्यों की कोशिश की, और अपने उद्देश्य के लिए इस पर बस गया। मैं क्रोम और एंड्रॉइड को लक्षित कर रहा था और यह मेरे ऐप की जरूरतों को पूरा करता है। यह कम होने में सक्षम हो सकता है।
पैट्रिक

3
तो यह लगभग यादृच्छिक मूल्य है जैसा कि आपके निहितार्थ के अलावा और किसी चीज से संबंधित नहीं है। स्पष्टीकरण के लिए धन्यवाद !
y_nk

मुझे लगता है कि आप एक ही तत्व का उपयोग कई ध्वनियों को खेलने के लिए कर रहे हैं? जो लोड के मुद्दे की व्याख्या करेगा; एक ध्वनि अभी भी भरी हुई है जबकि एक ही तत्व के माध्यम से दूसरी ध्वनि खेलने की कोशिश की जा रही है। एक देरी "इसे रोक सकती है" हालांकि इसका एक क्लूडी फिक्स और लंबे / छोटे देरी का उपयोग बेहतर / सर्वोत्तम अनुभव के लिए किया जा सकता है। फ़्लाई पर तत्वों को साफ़ करना और उनका पुन: निर्माण करना मेरा SOP रहा है जो कि कई ऑडियो / वीडियो और मेमोरी लीक को छोड़ देता है।
पेड़

1
एक क्रोम बग की तरह दिखता है: bugs.chromium.org/p/chromium/issues/detail?id=593273
20

8
दौड़ की स्थिति को हल करने के लिए मनमाना सेटटाइमआउट अवधि का उपयोग नहीं किया जाना चाहिए।
गैजेट ब्लास्टर

6

मैंने अभी इस सटीक मुद्दे के बारे में https://developers.google.com/web/updates/2017/06/play-request-was-interrupted पर एक लेख प्रकाशित किया है जो आपको बताता है कि वास्तव में क्या हो रहा है और इसे कैसे ठीक किया जाए


5

कोशिश करो

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


2

आप अपने समाधान को कितना जटिल चाहते हैं, इसके आधार पर, यह उपयोगी हो सकता है:

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

यह थोड़ा ओवरकिल है, लेकिन अद्वितीय परिदृश्यों में एक वादा को संभालने में मदद करता है।


2

समाधान या तो यहाँ प्रस्तावित बड़े काम नहीं किया था मेरे लिए या जहां, इसलिए मैं कुछ और के लिए देख रहा था और पाया समाधान पर @dighan द्वारा प्रस्तावित bountysource.com/issues/

तो यहाँ कोड है कि मेरी समस्या हल है:

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

यह अभी भी कंसोल में एक त्रुटि फेंकता है, लेकिन कम से कम वीडियो चल रहा है :)


1

शायद इस के लिए एक बेहतर समाधान के रूप में मुझे लगा। जैसा कि @JohnnyCoder से उद्धृत किया गया है:

media.pause ()

यदि आवश्यक हो तो मीडिया संसाधन को लोड करने के लिए रुकी हुई विशेषता को सही पर सेट करता है।

-> इसे लोड कर रहा हूं

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

मीडिया की तत्परता की स्थिति इंगित करता है HAVE_ENOUGH_DATA = 4

मूल रूप से केवल तभी वीडियो लोड करें यदि वह पहले से लोड नहीं है। मेरे लिए उल्लेखित त्रुटि आई, क्योंकि वीडियो लोड नहीं हुआ था। शायद टाइमआउट का उपयोग करने से बेहतर है।


1

सभी त्रुटियों को हटाया: (टाइपस्क्रिप्ट)

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

1

लाइव स्ट्रीमिंग के साथ मैं उसी मुद्दे का सामना कर रहा था। और मेरा फिक्स यह है Html वीडियो TAG से "ऑटोप्ले" निकालना सुनिश्चित करें और खेलने के लिए नीचे दिए गए कोड का उपयोग करें।

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
महान समाधान !!
जुनैद मुख्तार

1

Chrome नवीनतम संस्करणों में एक वादा देता है। अन्यथा, बस:

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

1

मैं एक ही मुद्दा है, अंत में मैं द्वारा हल:

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

1

मेरे लिए तय किया गया कोड का यह टुकड़ा!

@ जॉनीकोडर का संशोधित कोड

HTML:

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

जे एस:

  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

मैंने इसे कुछ कोड bellow के साथ तय किया है:

जब आप खेलना चाहते हैं, तो निम्नलिखित का उपयोग करें:

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

0

यहाँ एक और समाधान है यदि कारण यह है कि आपका वीडियो डाउनलोड सुपर धीमा है और वीडियो बफर नहीं किया है:

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


0

ऐसा लगता है कि बहुत सारे प्रोग्रामर्स को इस समस्या का सामना करना पड़ा। एक समाधान काफी सरल होना चाहिए। मीडिया तत्व Promiseकार्रवाई से लौटते हैं

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

चाल चलनी चाहिए


0

यहाँ 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)
}

0

सभी नए ब्राउज़र वीडियो को केवल म्यूट होने के साथ ऑटो-प्ले करने का समर्थन करते हैं इसलिए कृपया कुछ इस तरह से रखें

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

वीडियो का URL SSL स्थिति से मेल खाना चाहिए यदि आपकी साइट https के साथ चल रही है तो वीडियो URL को भी https और HTTP के लिए भी होना चाहिए


0

सबसे साफ और सरल उपाय:

var p = video.play();
if (p !== undefined) p.catch(function(){});

0

कारण एक - हल करने के लिए वादे के इंतजार के बिना ठहराव बुला रहा है

इस परिदृश्य के लिए बहुत सारे उत्तर, इसलिए मैं उस मुद्दे के लिए सबसे अच्छे डॉक्टर का उल्लेख करूंगा:

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

कारण दो - जब टैब केंद्रित न हो तो कॉलिंग प्ले

इस स्थिति में, ब्राउज़र तब playकॉल करके बाधित कर सकता है pauseजब टैब फोकस नहीं होता है। सक्रिय टैब के लिए संसाधनों को बचाने के लिए।

इसलिए आप खेलने के लिए कॉल करने से पहले ध्यान केंद्रित किए जाने वाले टैब का इंतजार कर सकते हैं:


async function waitForTabFocus() {
  return new Promise((resolve, reject) => {
    const onFocus = () => { resolve(); window.removeEventListener('focus', onFocus) };
    window.addEventListener('focus', onFocus)
  })
}
if (!document.hasFocus()) await this.waitForTabFocus();
videoEl.play();

-1

मैं एक ही मुद्दे में भाग गया और इसे गतिशील रूप autoplayसे उपयोग करने के बजाय विशेषता जोड़कर हल किया play()। इस तरह से ब्राउज़र दौड़ की स्थिति में भागे बिना खेलने के लिए तैयार हो गया।


-1

play()यह समाप्त होने पर कॉल करके लूप को एक ऑटोप्ले वीडियो प्राप्त करने की कोशिश करना , टाइमआउट वर्कअराउंड मेरे लिए काम नहीं करता था (हालांकि समय समाप्त हो गया है)।

लेकिन मुझे पता चला कि वीडियो को jQuery के साथ क्लोनिंग / रिप्लेस करके जब यह समाप्त हो गया, तो यह ठीक से लूप करेगा।

उदाहरण के लिए:

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

तथा

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

मैं Chrome 54.0.2840.59 (64-बिट) / OS X 10.11.6 का उपयोग कर रहा हूं


-1

मुझे लगता है कि उन्होंने html5 वीडियो को अपडेट किया और कुछ कोडेक्स को हटा दिया। कोडेक्स हटाने के बाद इसने मेरे लिए काम किया।

नीचे दिए गए उदाहरण में:

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


-1

जब आपको इसके साथ कोई त्रुटि दिखाई देती Uncaught (in promise)है, तो इसका मतलब है कि आपको .catch()इस मामले में वादे को संभालने की आवश्यकता है , .play()एक वादा लौटाता है। आप तय कर सकते हैं कि क्या आप एक संदेश लॉग करना चाहते हैं, कुछ कोड चलाएं, या कुछ भी नहीं करें, लेकिन जब तक आपके पास .catch()त्रुटि है तब तक चले जाएंगे।

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

यह एक वादा वापस नहीं करता है
मार्टिन डॉसन

@MartinMazzaDawson यह एक वादा वापस करता है। यदि आप प्रश्न में xxx की स्पष्ट टिप्पणी को देखते हैं, तो वह कहता है, "यह एक त्रुटि है, यहां पूर्ण त्रुटि है: अनकहा (वादे में) DOMException: नाटक () अनुरोध को रोकने के लिए एक कॉल द्वारा बाधित किया गया था ()।"
22

-5

मैंने इस मुद्दे का मुकाबला करने के लिए एक चाल का उपयोग किया है। एक वैश्विक चर संस्करण ऑडियो को परिभाषित करें;

और फ़ंक्शन चेक में

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

और स्टॉप फ़ंक्शन में

audio.pause();
audio = undefined;

इसलिए, अगली कॉल audio.play'0' करंटटाइम से ऑडियो तैयार होगी

मैंनें इस्तेमाल किया

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

लेकिन यह काम नहीं किया। धन्यवाद।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.