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

François Beaufort
François Beaufort

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

या

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

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

यहां नीचे दिए गए कुछ JavaScript कोड दिए गए हैं, जो आपको दिख रही "नहीं मिली (प्रॉमिस में)" गड़बड़ी को फिर से दिखाते हैं:

यह न करें
<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() कॉल करने से प्रॉमिस दिखता है. यह ऐसा फ़ंक्शन है जो किसी एक नतीजे को एसिंक्रोनस तरीके से दिखाता है. अगर वीडियो चलता है, तो प्रॉमिस पूरा होता है और 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 की गड़बड़ी