Как воспроизвести видео со звуком по событию, инициированному пользователем, до того, как элемент видео добавлен в DOM? iOS Safari / Chrome / Webkit - PullRequest
2 голосов
/ 05 июня 2019

У меня есть приложение Ember.js с двумя элементами в DOM: 1) Окно просмотра (показывает большое изображение или видео) 2) сетка миниатюр (представляющих видео или изображения).

Когда пользовательнажимает на соответствующий эскиз для видео, видео должно загрузиться в окно просмотра и начать воспроизведение со звуком на мобильном / IOS / Android.Я тестирую специально для iOS Safari.

Мне известны политики webkit для событий, инициируемых пользователем, требующие отключения видео, если пользователь явно не нажимает на вещи (что является действиемЯ делаю это здесь), но у меня возникают проблемы с пониманием конкретных деталей реализации.

Примечание о требовании жеста пользователя: когда мы говорим, что действие должно было произойти «в результате жеста пользователя”, Мы имеем в виду, что JavaScript, который привел к вызову video.play (), например, должен был напрямую получаться из обработчика события касания, щелчка, двойного щелчка или нажатия клавиши.Таким образом, button.addEventListener ('click', () => {video.play ();}) удовлетворяет требованию жеста пользователя.video.addEventListener ('canplaythrough', () => {video.play ();}) не будет.

Я считаю, что проблема для меня заключается в том, что элемент видео не добавляется в домен.до следующего цикла рендеринга.Даже если пользователь запускает событие, нажимая на миниатюру для воспроизведения видео, webkit не распознает его как событие, инициированное пользователем, и не блокирует воспроизведение видео, потому что оно имеет звук.

Щелчок пользователя:

    updateCurrentItem(item) {
      set(this, "currentItem", item);

      this.videoManager.playWhenLoaded.perform(item);
    }

videoManager.playWhenLoaded - задача параллельного исполнения.Когда видео загружается в dom, оно регистрируется в сервисе videoManager.

  playWhenLoaded: task(function*(item) {
    let id = item.id;
    while (this.videos.findBy("modelId", id) === undefined) {
      yield timeout(200);
    }

    let video = this.videos.findBy("modelId", id);
    video.player.muted = false;
    video.player.play();
  })

Не могли бы вы объяснить, почему это не работает?и какие стратегии я мог бы попытаться заставить это работать для моего варианта использования?У меня есть событие, инициированное пользователем, запускающее воспроизведение, так как заставить его работать?

Мозговой штурм, мне, вероятно, нужно что-то вроде этого:

    updateCurrentItem(item) {
      set(this, "currentItem", item);

      let player = this.videoManager.getVideoPlayer.perform(item);
      //wait for the result somehow?

      player.muted = false;
      player.play();
    }

В котором play () имеет видпрямой результат события click.Но могу ли я заблокировать выполнение функции, чтобы дождаться получения плеера?насколько я знаю, это просто заблокировало бы runloop, и видео никогда не вставлялось бы в dom.

...