Видео не воспроизводится с первого раза при наведении

20
06 августа 2018, 04:10

Есть каталог с видео фонами, при наведении на видео оно должно проигрываться, но иногда в браузерах (в частности opera) выводиться ошибка.

Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

$('body').on("mouseover", ".services__item", function(){ 
		var videoBlock = $(this).find('.video'), 
			video = videoBlock.get(0); 
 
		if(videoBlock.length){ 
			video.play(); 
			videoBlock.css( "background-color", "black" ); 
		} 
	}); 
	$('body').on("mouseleave", ".services__item", function(){ 
		var videoBlock = $(this).find('.video'), 
			video = videoBlock.get(0); 
		if(videoBlock.length){ 
			video.pause(); 
		} 
	});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="services__item"> 
    <div class="services__media-wrp"> 
      <div class="services__media"> 
        <video class="video"loop> 
          <source src="https://upread.ru/video/art144-1.mp4" type="video/mp4" /> 
        </video> 
      </div> 
    </div> 
</div>

Как это пофиксить?

Answer 1

Решение

Попробуй проверять состояние проигрывания видео следующим образом, данная проверка подходит для любых типов медиа-файлов:

Object.defineProperty(HTMLMediaElement.prototype, "playing", {
  get: function get() {
    return !!(
      this.currentTime > 0 &&
      !this.paused &&
      !this.ended &&
      this.readyState > 2
    );
  }
});

То есть, если видео не проигрывается, то ты можешь это проверить следующим образом:

let videoBlock = $(this).find(".video");
if (!videoBlock.playing) {
  video.play();
  console.log('видео можно воспроизвести!')
}

Пример

"use strict"; 
 
Object.defineProperty(HTMLMediaElement.prototype, "playing", { 
  get: function get() { 
    return !!( 
      this.currentTime > 0 && 
      !this.paused && 
      !this.ended && 
      this.readyState > 2 
    ); 
  } 
}); 
 
$("body").on("mouseover", ".services__item", function() { 
  var videoBlock = $(this).find(".video"), 
    video = videoBlock.get(0); 
 
  if (!videoBlock.playing) { 
    video.play(); 
    videoBlock.css("background-color", "black"); 
  } 
}); 
$("body").on("mouseleave", ".services__item", function() { 
  var videoBlock = $(this).find(".video"), 
    video = videoBlock.get(0); 
    video.pause(); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="services__item"> 
    <div class="services__media-wrp"> 
      <div class="services__media"> 
        <video class="video"loop> 
          <source src="https://upread.ru/video/art144-1.mp4" type="video/mp4" /> 
        </video> 
      </div> 
    </div> 
</div>

Данная проблема возникает, потому что play() и pause() в каком-то смысле соревнуются, и вам необходимо четко определять когда видео не воспроизведено.

Решение с muted

Вы так же можете использовать muted для video:

<video ... muted="muted"></video>

Но это не лучшее решение, потому что звук будет выключен, а если у вас видео или аудио со звуком, вам понадобиться совершать лишние действия для активации звука.

Answer 2

Вы ошибку читали в консоле? Там же написано, что воспроизведение не удалось, потому что пользователь НЕ взаимодействовал с документом. Это политика автовоспроизведения.

Т.е. он считает, что раз ничего не делалось (не было клика) в DOM то это автовоспроизведения.

Для примера сделайте клик в любой части DOM потом наведите на видео. Будет работать.

Как вариант, может отключить звук по умолчанию

<video class="video" loop  muted="muted">
    <source src="https://upread.ru/video/art144-1.mp4" type="video/mp4" />
</video>
READ ALSO
Задача по JQuery [закрыт]

Задача по JQuery [закрыт]

Привяжите всем инпутам событие - по потери фокуса каждый инпут выводит свое value в абзац с id="test"

24
Зависает сайт на несколько секунд при загрузке (yandex map)

Зависает сайт на несколько секунд при загрузке (yandex map)

простой лендинг на wpИспользовал только bootstrap4 и owl-carousel ссылка на сайт

20
donut chart с анимацией

donut chart с анимацией

Здравсвуйте!

19
При нажатии на div, показать другой div [закрыт]

При нажатии на div, показать другой div [закрыт]

Есть список ul с элементами вида liitem_1, li

32