← Все статьи

Туториалы

Добавьте кнопку «картинка в картинке» к любому видео

«Картинка в картинке» позволяет видео плавать над всеми другими окнами, пока вы работаете. Браузеры поддерживают это нативно, но множество сайтов вырезают кнопку из своего плеера. Правило 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);

Советы для надёжного поведения

Возьмите готовую версию из наших готовых примеров или скачайте JustZix, чтобы добавить её самостоятельно. Чтобы вообще не дать видео автовоспроизводиться, прочтите остановите автовоспроизведение видео и аудио.

Оцени эту статью

Оценок пока нет — оцени первым.

Попробуй сам

Установи JustZix и вставь любой сниппет из этой статьи. Две минуты от нуля до работающего правила на всех твоих устройствах.

Получить JustZix

Возможности · Как это работает · Примеры · Применение