← Todos los artículos

Tutoriales

Añade un botón de imagen en imagen a cualquier vídeo

La imagen en imagen permite que un vídeo flote por encima de todas las demás ventanas mientras trabajas. Los navegadores la admiten de forma nativa, pero muchos sitios quitan el botón de su reproductor. Una regla de JustZix lo vuelve a poner en cada vídeo.

La API en una línea

Cualquier elemento <video> con los metadatos cargados puede moverse a una ventana flotante con video.requestPictureInPicture(). Devuelve una promesa, y el navegador exige que se active mediante un gesto del usuario como un clic.

someVideo.requestPictureInPicture().catch(function (err) {
  console.warn('PiP rechazado:', err.message);
});

Ese es el motor entero. El resto de este artículo lo envuelve en un botón en el que puedes hacer clic en cualquier página.

Un botón PiP flotante

Esta regla inyecta un solo botón. Al hacer clic en él, encuentra el mayor vídeo en reproducción y lo saca. Elegir el vídeo más grande evita activarlo en clips diminutos de fondo o de anuncios.

(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 = 'Sin PiP';
      setTimeout(function () { btn.textContent = 'PiP'; }, 1500);
    });
  });
})();

El mismo botón alterna: si un vídeo ya está en PiP llama a exitPictureInPicture(). La comprobación readyState > 0 salta los vídeos que aún no han cargado metadatos, ya que la API los rechaza.

Doble clic en cualquier vídeo para sacarlo

Si prefieres no tener un botón en pantalla, asocia la acción directamente a los vídeos. Esta regla hace que un doble clic en el propio vídeo alterne el 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);

Como el escuchador usa captura, se ejecuta antes que el propio gestor de doble clic del sitio, y preventDefault() impide que el reproductor alterne la pantalla completa al mismo tiempo.

Reaccionar a los eventos de PiP

Puedes mantener tu interfaz sincronizada escuchando enterpictureinpicture y leavepictureinpicture en un vídeo:

document.addEventListener('enterpictureinpicture', function (e) {
  console.log('flotando:', e.target.currentSrc);
}, true);

Consejos para un comportamiento fiable

Consigue una versión empaquetada en nuestros ejemplos listos para usar o descarga JustZix para añadirlo tú mismo. Para impedir que los vídeos se reproduzcan automáticamente en primer lugar, lee detener la reproducción automática de vídeo y audio.

Valora este artículo

Sin valoraciones — sé el primero.

Pruébalo tú mismo

Instala JustZix y pega cualquier snippet de este artículo. Dos minutos de cero a una regla funcionando en todos tus dispositivos.

Obtener JustZix

Funciones · Cómo funciona · Ejemplos · Casos de uso