DOMअपवाद - play() अनुरोध रोका गया

François Beaufort
François Beaufort

क्या आपको Chrome DevTools में मीडिया से जुड़ी इस अनचाही गड़बड़ी के बारे में पता चला JavaScript कंसोल?

या

तो, आप सही जगह पर हैं. डरें नहीं. हम आपको बताएंगे कि इसकी वजह क्या है और इसे कैसे ठीक किया जा सकता है.

इसकी वजह क्या है

यहां नीचे दिया गया कुछ JavaScript कोड दिया गया है, जो "Uncaught (छद्म से)" जैसा कुछ फिर से जनरेट करता है. गड़बड़ी दिखाई दे रही है:

यह न करें
<video id="video" preload="none" src="https://example.com/file.mp4"></video>

<script>
  video.play(); // <-- This is asynchronous!
  video.pause();
</script>

Chrome DevTools में ऊपर दिए गए कोड से गड़बड़ी का यह मैसेज दिखता है:

_Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().

preload="none" की वजह से वीडियो लोड नहीं हो रहा है. इसलिए, वीडियो नहीं चल रहा ज़रूरी है कि video.play() लागू होने के तुरंत बाद शुरू हो.

इसके अलावा, Chrome 50 के बाद से, <video> या <audio> पर play() कॉल आ रहा है एलिमेंट Promise नतीजे देता है. यह फ़ंक्शन एक ही नतीजा दिखाता है एसिंक्रोनस रूप से. अगर प्लेबैक कामयाब होता है, तो प्रॉमिस पूरा हो जाता है और playing इवेंट उसी समय ट्रिगर होता है. अगर प्लेबैक नहीं होता है, तो वादा यह होगा को अस्वीकार कर दिया गया है. साथ ही, गड़बड़ी का एक मैसेज दिखाया गया है, जिसमें गड़बड़ी के बारे में बताया गया है.

अब यहां बताया गया है कि क्या हो रहा है:

  1. video.play(), वीडियो कॉन्टेंट को एसिंक्रोनस रूप से लोड करना शुरू कर देता है.
  2. फ़िलहाल, video.pause() के लोड होने की वजह से वीडियो लोड नहीं हो पा रहा है.
  3. video.play(), एसिंक्रोनस रूप से तेज़ आवाज़ में अनुरोध अस्वीकार करता है.

हम अपने कोड में, वीडियो चलाने का वादा नहीं कर रहे हैं, इसलिए गड़बड़ी का एक मैसेज मिलेगा Chrome DevTools में दिखता है.

इसे कैसे ठीक करें

अब हमने इसकी असल वजह समझ ली है, चलिए देखते हैं कि हम इसे ठीक करने के लिए क्या कर सकते हैं.

सबसे पहले, यह न सोचें कि कोई मीडिया एलिमेंट (वीडियो या ऑडियो) चलेगा. इसे देखें प्रॉमिस को play फ़ंक्शन से लौटाया जाता है, ताकि यह देखा जा सके कि प्रॉमिस को अस्वीकार किया गया है या नहीं. हां यह जान लें कि प्रॉमिस तब तक पूरा नहीं होगा, जब तक कि प्लेबैक शुरू किया है, इसका मतलब है कि then() में मौजूद कोड तब तक काम नहीं करेगा, जब तक कि मीडिया खेल रहा है.

यह करें

उदाहरण: वीडियो अपने-आप चलने की सुविधा

<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>
यह करें

उदाहरण: खेलें & पॉज़ करें

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

इस साधारण उदाहरण के लिए यह बहुत बढ़िया है, लेकिन क्या होगा अगर आप video.play() का इस्तेमाल बाद में वीडियो नहीं चला पा रहे हैं?

मैं तुम्हें एक राज़ बताती हूँ. आपको video.play() का इस्तेमाल करने की ज़रूरत नहीं है, आप इसका इस्तेमाल कर सकते हैं video.load() और यहां इसका तरीका देखें:

यह करें

उदाहरण: फ़ेच और चलाएं

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

Play प्रॉमिस सपोर्ट

लिखते समय, HTMLMediaElement.play() जवाब में प्रॉमिस देता है Chrome, Edge, Firefox, Opera, और Safari.

डेंजर ज़ोन

<video> में मौजूद <source>, play() का वादा कभी अस्वीकार नहीं करता

<video src="not-existing-video.mp4"\> के लिए, play() प्रॉमिस इस तरह अस्वीकार करता है: उम्मीद है कि वीडियो मौजूद नहीं है. <video><source src="not-existing-video.mp4" type='video/mp4'></video> के लिए, play() का प्रॉमिस कभी अस्वीकार नहीं करता. ऐसा सिर्फ़ तब होता है, जब कोई मान्य सोर्स मौजूद न हो.

Chromium बग