Właśnie natknąłem się na ten nieoczekiwany błąd multimediów w Narzędziach deweloperskich w Chrome? konsolę JavaScript?
lub
Jesteś we właściwym miejscu. Bez obaw. Wyjaśnię, co powoduje ten problem i jak to naprawić.
Co to powoduje
Oto fragment kodu JavaScript, który odtwarza komunikat „Nieprzechwycony (obiecany)” poniżej który widzisz:
<video id="video" preload="none" src="https://example.com/file.mp4"></video> <script> video.play(); // <-- This is asynchronous! video.pause(); </script>
Powyższy kod powoduje wyświetlenie tego komunikatu o błędzie w Narzędziach deweloperskich w Chrome:
_Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
Film nie jest wczytywany z powodu: preload="none"
, dlatego odtwarzanie nie jest możliwe
musi rozpoczynać się natychmiast po wykonaniu video.play()
.
Dodatkowo od Chrome 50 wywołanie play()
na <video>
lub <audio>
element zwraca Promise, funkcję, która zwraca pojedynczy wynik.
asynchronicznie. Jeśli odtworzenie się powiedzie, obietnica zostanie spełniona, a
Jednocześnie wywoływane jest zdarzenie playing
. Jeśli odtwarzanie się nie uda, obietnica jest
odrzucono wraz z komunikatem o błędzie z wyjaśnieniem błędu.
Oto co się teraz dzieje:
video.play()
rozpoczyna asynchroniczne wczytywanie treści wideo.- Komponent
video.pause()
przerywa wczytywanie filmu, ponieważ nie jest jeszcze gotowy. - Funkcja
video.play()
odrzuca asynchronicznie głośno.
Ponieważ w naszym kodzie nie obsługujemy obietnicy odtwarzania filmu, pojawia się komunikat o błędzie pojawi się w Narzędziach deweloperskich w Chrome.
Jak to naprawić
Znasz już główną przyczynę problemu, więc teraz sprawdźmy, jak go naprawić.
Po pierwsze nie zakładaj, że będą odtwarzane elementy multimedialne (wideo lub dźwięk). Spójrz na
obietnica zwrócona przez funkcję play
, by sprawdzić, czy została odrzucona. Jest
Warto zauważyć, że obietnica nie zostanie zrealizowana, dopóki odtwarzanie
co oznacza, że kod w elemencie then()
nie będzie wykonywany, dopóki nie
gra.
Przykład: autoodtwarzanie
<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>
Przykład: Odtwórz i Pauza
<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>
To świetny przykład w tym prostym przykładzie, ale co, jeśli użyjesz funkcji video.play()
, aby
odtworzyć film później?
Zdradę Ci sekret. Nie musisz używać video.play()
, możesz używać usługi
video.load()
. Aby to zrobić:
Przykład: Pobierz i Odtwórz
<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>
Zespół Google Play ds. obietnic
W momencie pisania tekstu HTMLMediaElement.play()
zwraca obietnicę w języku:
Chrome, Edge, Firefox, Opera i Safari.
Strefa zagrożenia
Pole <source>
w obrębie <video>
sprawia, że obietnica play()
nigdy nie odrzuca
W przypadku <video src="not-existing-video.mp4"\>
obietnica play()
odrzuca jako
ponieważ film nie istnieje. W przypadku <video><source
src="not-existing-video.mp4" type='video/mp4'></video>
obietnica play()
nigdy nie odrzuca. Dzieje się tak tylko wtedy, gdy nie ma żadnych prawidłowych źródeł.