Картинка в картинке и полноэкранный режим вместе — API можно активировать только жестом пользователя

Я запускаю два видео друг над другом, как на этой картинке:

демонстрация видеопроигрывателя

Там есть кнопка «Войти в полноэкранный режим». Когда кто-то нажимает на эту кнопку, я хочу сделать две вещи.

  1. Видеопроигрыватель 2 будет установлен в режим «картинка в картинке».
  2. Видеоплеер 1 будет настроен на полноэкранный режим.

Я могу работать как в полноэкранном режиме, так и в режиме «картинка в картинке», но не могу одновременно использовать полноэкранный режим и функцию «картинка в картинке». Ошибка вылетает так:

Не удалось выполнить 'requestFullscreen' для 'Element': API может быть инициировано только жестом пользователя.
Uncaught (в обещании) TypeError: полноэкранная ошибка

Я использую jQuery, и вот мой пример кода:

$('.enter-full-screen').click(event => {
  event.stopImmediatePropagation();
  event.stopPropagation();

  let pipResponse = $('#video-player-2')[0].requestPictueInPicture();

  pipResponse.then(() => {
    $('#video-player-1')[0].requestFullscreen() // Note: I am using a browser prefixes
      .then(/* ... */)
      .catch(/* ... */);
  })
});

Обновление: 07.01.2020: Я пробовал оба запроса одновременно, но тоже не работает. Он работает только для одного, который я запрашиваю первым.

let pipResponse = $('#video-player-2')[0].requestPictueInPicture();
let fullscreenResponse = $('#video-player-1')[0].requestFullscreen();

Promise.all([pipResponse, fullscreenResponse])
    .then(/* code */)
    .catch(/* code */);

В этом случае работает только pip, а полноэкранный запрос выдает ошибку. Если я сначала запрашиваю полноэкранный режим, то работает только полноэкранный режим - pip выдает ошибку.

Я попытался использовать jQuery trigger('click') для автоматического запуска другого события клика вместе с одним. Работает только для одного (пип или полноэкранный режим), НО НЕ РАБОТАЕТ ВМЕСТЕ!

Я действительно ценю твою помощь.


person Robin    schedule 06.01.2020    source источник
comment
Странно, что вы получаете эту ошибку, учитывая, что вы вызываете функцию в обработчике кликов, вызванном пользователем. Выполняется ли код в iframe или в другом DOM, который вы загружаете отдельно?   -  person Rory McCrossan    schedule 06.01.2020
comment
Какой полифилл вы используете для этого?   -  person Rory McCrossan    schedule 06.01.2020
comment
.requestFullscreen() вызывается в обещании, поэтому я предполагаю, что браузер не отслеживает, был ли этот код изначально активирован гостевой учетной записью пользователя. Разве вы не можете одновременно запросить полноэкранный режим и картинку в картинке и отменить одно, если другое не работает?   -  person Axel Köhler    schedule 06.01.2020
comment
@RoryMcCrossan извините, это была опечатка - не полифилл, префиксы, как предлагает w3schools. w3schools.com/jsref/met_element_requestfullscreen.asp   -  person Robin    schedule 06.01.2020
comment
@AxelKöhler, я пытаюсь запросить оба одновременно - не работает. Работает только тот, который я запрашиваю первым.   -  person Robin    schedule 07.01.2020


Ответы (1)


Я не уверен, что изображение -in-picture (PiP) API является подходящим инструментом для этой работы - полноэкранный режим и поведение PiP в этом случае кажутся взаимоисключающими.

Поскольку вы уже эмулируете поведение PiP (как показано на рисунке), вы сможете использовать тот же подход при переходе в полноэкранный режим.

Вместо того, чтобы пытаться сделать отдельные видеоэлементы полноэкранными/PiP, сделайте один общий родительский элемент для обоих видео полноэкранными. Затем вы можете просто разместить маленькое видео поверх большого (как вы уже делаете), чтобы создать эффект «картинка в картинке».

<!-- 1. Give the video players a common ancestor -->
<div id="video-group">
    <div id="video-player-1">...</div>
    <div id="video-player-2">...</div>
</div>


$('.enter-full-screen').click(event => {
    event.stopImmediatePropagation();
    event.stopPropagation();

    // 2. Make the ancestor element fullscreen, not the videos themselves
    $('#video-group')[0].requestFullscreen()
        .then(/* ... */)
        .catch(/* ... */);
});

Вот быстрый и грязный пример создания «картинка в картинке» с двумя видео на YouTube:

<button type="button"
    onclick="document.querySelector('#video-group').requestFullscreen();">
    Enter fullscreen
</button>

<div id="video-group">
    <iframe style="position: absolute"
    width="100%" height="100%" 
    src="https://www.youtube.com/embed/9bZkp7q19f0" frameborder="0"
    allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

    <iframe style="position: absolute; bottom: 0; right: 0;"
    width="560" height="315"
    src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" 
    allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
person Sly_cardinal    schedule 07.01.2020
comment
Спасибо, проблема решена - теперь я могу понять, что делать в моем случае. - person Robin; 07.01.2020