Вы только что наткнулись на эту неожиданную медиа-ошибку в консоли JavaScript DevTools Chrome?
или
Тогда вы находитесь в правильном месте. Не бойтесь. Я объясню , что является причиной этого и как это исправить .
Что является причиной этого
Ниже приведен код JavaScript, который воспроизводит ошибку «Uncaught (in Promise)», которую вы видите:
<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 , вызов play() элемента <video> или <audio> возвращает Promise — функцию, которая асинхронно возвращает один результат. Если воспроизведение прошло успешно, обещание выполняется и одновременно запускается событие playing . Если воспроизведение завершается неудачей, обещание отклоняется вместе с сообщением об ошибке, объясняющим сбой.
Теперь вот что происходит:
-
video.play()начинает асинхронную загрузку видеоконтента. -
video.pause()прерывает загрузку видео, поскольку оно еще не готово. -
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>Играйте, обещайте поддержку
На момент написания HTMLMediaElement.play() возвращает обещание в Chrome , Edge, Firefox, Opera и Safari .
Опасная зона
<source> внутри <video> заставляет обещание play() никогда не отклоняться
Для <video src="not-existing-video.mp4"\> обещание play() отклоняется, как и ожидалось, поскольку видео не существует. Для <video><source src="not-existing-video.mp4" type='video/mp4'></video> обещание play() никогда не отклоняется. Это происходит только в том случае, если нет достоверных источников.