В версии 69 появилось расширение pictureInPicture, которое позволяет вывести видео поверх всех окон. Решил протестировать эту возможность и поделиться результатами.
Сразу нашел пример, но кнопка «картинка в картинке» для переключения в режим Picture-in-Picture (далее PiP) была недоступна, пошел проверять флаг chrome://flags/#enable-picture-in-picture, значение «Default», для этого флага, равносильно «Enabled», но все равно попробовал включить его вручную.
Не помогло, оказалось нужен еще один флаг chrome://flags/#enable-surfaces-for-videos, значение «Default» для него равносильно «Disabled».
Включил и заработало. Так же пишут, что необходимо включение флага #enable-experimental-web-platform-features, но у меня заработало и без него.
Пример
Сделаем простой пример, тег <video/>, кнопка для включения/выключения режима PiP, обработка доступных событий PiP.
<html>
<head>
<title>Chrome 69</title>
</head>
<body>
<video width="320" height="240" controls>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
<br/>
<button>Включить PiP</button>
<script>
const video = document.querySelector('video');
const button = document.querySelector('button');
if (!document.pictureInPictureEnabled) {
button.textContent = 'Режим PiP не поддерживается.';
button.disabled = true;
}
button.addEventListener('click', () => {
if (document.pictureInPictureElement) {
document.exitPictureInPicture()
.then(() => { /**/ })
.catch(() => { /**/ });
} else {
video.requestPictureInPicture()
.then(() => { /**/ })
.catch(() => { /**/ });
}
});
video.addEventListener('enterpictureinpicture', () => {
button.textContent = 'Выключить PiP';
});
video.addEventListener('leavepictureinpicture', () => {
button.textContent = 'Включить PiP';
});
</script>
</body>
</html>
Проверяем доступность режима:
if (document.pictureInPictureEnabled){
//Режим PiP доступен
}
Все просто, если свойство существует, оно возвращает true или false.
Делаем запрос на запуск режима:
button.addEventListener('click', () => {
video.requestPictureInPicture()
.then(() => { /**/ })
.catch(() => { /**/ });
});
Если разрешение получено выполниться then иначе catch. Запрос точно будет отклонен, если не инициирован по событию пользователя.
После запуска document.pictureInPictureElement будет возвращать наш элемент <video/>.
Для выхода из режима можно в окне PiP нажать крестик в правом верхнем углу.
Можно сделать выход програмно:
button.addEventListener('click', () => {
if (document.pictureInPictureElement) {
document.exitPictureInPicture()
.then(() => { /**/ })
.catch(() => { /**/ });
}
});
После выхода из режима document.pictureInPictureElement снова будет возвращать null.
События PiP
Доступно два события, включение режима PiP и соответственно выключение:
video.addEventListener('enterpictureinpicture', () => {
//режим включен
button.textContent = 'Отключить PiP';
});
video.addEventListener('leavepictureinpicture', () => {
//режим отключен
button.textContent = 'Включить PiP';
});
Резюме
На данный момент, этот режим работает только с тегом <video/>, но возможно будет расширен.
Окно PiP появляется в правом нижнем углу, пока что мы не можем на это повлиять.
Режим PiP, несовместим с полноэкранным режимом, либо то либо другое, что вполне логично.
Одновременно может быть только одно окно PiP.
Вкладка, на которой пользователь включил режим PiP, отмечается значком (видно на КДПВ).
Автор: brzsmg