DOMException - play() isteği kesintiye uğradı

François Beaufort
François Beaufort

Chrome Geliştirici Araçları JavaScript Konsolu'nda bu beklenmedik medya hatasıyla mı karşılaştınız?

veya

O halde doğru yerdesiniz. Korkmayın. Bu durumun nedenini ve nasıl düzeltileceğini açıklayacağız.

Bunun nedeni nedir?

Gördüğünüz "Yakalanamayan (vaat edilen)" hatasını yeniden oluşturan bazı JavaScript kodlarını burada bulabilirsiniz:

Yapılmaması gerekenler
<video id="video" preload="none" src="https://example.com/file.mp4"></video>

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

Yukarıdaki kod, Chrome Geliştirici Araçları'nda şu hata mesajıyla sonuçlanır:

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

Video, preload="none" nedeniyle yüklenmediğinden video oynatma mutlaka video.play() yürütüldükten hemen sonra başlamaz.

Dahası, Chrome 50'den beri <video> veya <audio> öğesi üzerindeki bir play() çağrısı, eşzamansız olarak tek bir sonuç döndüren Promise işlevi döndürür. Oynatma başarılı olursa Promise yerine getirilir ve playing etkinliği aynı anda tetiklenir. Oynatma başarısız olursa Promise, hatayı açıklayan bir hata mesajıyla birlikte reddedilir.

Durum şu:

  1. video.play(), video içeriğini eşzamansız olarak yüklemeye başlar.
  2. video.pause(), henüz hazır olmadığı için videonun yüklenmesini kesintiye uğratıyor.
  3. video.play() eşzamansız bir şekilde reddeder.

Kodumuzdaki video oynatma sözüyle ilgili işlem yapmadığımız için Chrome Geliştirici Araçları'nda bir hata mesajı görüntüleniyor.

Nasıl giderilir?

Artık sorunun asıl nedenini anladığımıza göre bunu düzeltmek için neler yapabileceğimize bakalım.

Öncelikle, hiçbir zaman bir medya öğesinin (video veya ses) oynatılacağını varsaymayın. Reddedilmiş olup olmadığını görmek için play işlevinin döndürdüğü Promise'e bakın. Oynatma gerçekten başlayana kadar Promise'ın yerine getirilmeyeceğini belirtmek isteriz. Diğer bir deyişle, then() içindeki kod, medya oynatılana kadar yürütülmeyecektir.

Yapılması gerekenler

Örnek: Otomatik oynatma

<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>
Yapılması gerekenler

Örnek: Oynat ve Duraklat

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

Bu basit örnek için bu harika bir şey, ancak bir videoyu daha sonra oynatmak için video.play() kullanırsanız ne olur?

Sana bir sır anlatacağım. video.play() uygulamasını kullanmak zorunda değilsiniz. video.load() kullanarak nasıl yapacağınız aşağıda açıklanmıştır:

Yapılması gerekenler

Örnek: Getir ve Oyna

<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 söz desteği

Bu yazının yazıldığı sırada HTMLMediaElement.play(), Chrome, Edge, Firefox, Opera ve Safari'de vadeyi döndürdü.

Tehlike bölgesi

<video> içindeki <source>, play() sözünün hiçbir zaman reddedilmemesini sağlıyor

<video src="not-existing-video.mp4"\> için play() sözü, video mevcut olmadığından beklendiği şekilde reddediliyor. <video><source src="not-existing-video.mp4" type='video/mp4'></video> için play() sözü hiçbir zaman reddedilmez. Bu durum, yalnızca geçerli kaynak olmadığında gerçekleşir.

Chromium Hatası