Добавьте кнопку «картинка в картинке» к любому видео
«Картинка в картинке» позволяет видео плавать над всеми другими окнами, пока вы работаете. Браузеры поддерживают это нативно, но множество сайтов вырезают кнопку из своего плеера. Правило JustZix возвращает её на каждое видео.
API в одну строку
Любой элемент <video> с загруженными метаданными можно переместить в плавающее окно с помощью video.requestPictureInPicture(). Он возвращает промис, и браузер требует, чтобы его запустил пользовательский жест, например клик.
someVideo.requestPictureInPicture().catch(function (err) {
console.warn('PiP отклонён:', err.message);
});
Это весь движок. Остальная часть этой статьи оборачивает его в кнопку, которую вы можете кликнуть на любой странице.
Плавающая кнопка PiP
Это правило вставляет одну кнопку. Клик по ней находит самое крупное играющее видео и выносит его. Выбор самого крупного видео избегает срабатывания на крошечных фоновых или рекламных клипах.
(function () {
if (!document.pictureInPictureEnabled) { return; }
var btn = document.createElement('button');
btn.textContent = 'PiP';
btn.style.cssText = 'position:fixed;bottom:16px;right:16px;z-index:2147483647;'
+ 'background:#2563eb;color:#fff;border:0;border-radius:8px;'
+ 'padding:8px 14px;font:600 13px sans-serif;cursor:pointer;'
+ 'box-shadow:0 2px 8px rgba(0,0,0,.3)';
document.body.appendChild(btn);
function biggestVideo() {
var best = null, bestArea = 0;
document.querySelectorAll('video').forEach(function (v) {
var r = v.getBoundingClientRect();
var area = r.width * r.height;
if (area > bestArea && v.readyState > 0) {
best = v; bestArea = area;
}
});
return best;
}
btn.addEventListener('click', function () {
if (document.pictureInPictureElement) {
document.exitPictureInPicture();
return;
}
var v = biggestVideo();
if (!v) { return; }
v.requestPictureInPicture().catch(function (err) {
btn.textContent = 'Нет PiP';
setTimeout(function () { btn.textContent = 'PiP'; }, 1500);
});
});
})();
Та же кнопка переключает: если видео уже в PiP, она вызывает exitPictureInPicture(). Проверка readyState > 0 пропускает видео, ещё не загрузившие метаданные, поскольку API их отклоняет.
Двойной клик по любому видео, чтобы вынести его
Если вы предпочитаете без экранной кнопки, привяжите действие прямо к видео. Это правило делает так, что двойной клик по самому видео переключает PiP.
document.addEventListener('dblclick', function (e) {
var v = e.target;
if (!v || v.tagName !== 'VIDEO') { return; }
if (!document.pictureInPictureEnabled) { return; }
e.preventDefault();
if (document.pictureInPictureElement === v) {
document.exitPictureInPicture();
} else {
v.requestPictureInPicture().catch(function () {});
}
}, true);
Поскольку слушатель использует захват, он срабатывает раньше собственного обработчика двойного клика сайта, а preventDefault() не даёт плееру одновременно переключить полноэкранный режим.
Реакция на события PiP
Вы можете держать свой интерфейс синхронизированным, слушая enterpictureinpicture и leavepictureinpicture на видео:
document.addEventListener('enterpictureinpicture', function (e) {
console.log('плавает:', e.target.currentSrc);
}, true);
Советы для надёжного поведения
- PiP нужен защищённый контекст. Он работает на страницах
httpsи отклоняется на обычномhttp. - Если сайт задаёт
disablePictureInPictureна элементе, сначала очистите его черезvideo.disablePictureInPicture = false. - Некоторые одностраничные сайты подменяют видеоэлемент при навигации, так что держите правило кнопки активным на весь сайт, а не для отдельной страницы.
Возьмите готовую версию из наших готовых примеров или скачайте JustZix, чтобы добавить её самостоятельно. Чтобы вообще не дать видео автовоспроизводиться, прочтите остановите автовоспроизведение видео и аудио.
Оцени эту статью
Оценок пока нет — оцени первым.