← Tous les articles

Tutoriels

Ajoutez un bouton image dans l'image à n'importe quelle vidéo

L'image dans l'image laisse une vidéo flotter au-dessus de toutes les autres fenêtres pendant que vous travaillez. Les navigateurs la prennent en charge nativement, mais beaucoup de sites retirent le bouton de leur lecteur. Une règle JustZix le remet sur chaque vidéo.

L'API en une ligne

Tout élément <video> dont les métadonnées sont chargées peut être déplacé dans une fenêtre flottante avec video.requestPictureInPicture(). Cela renvoie une promesse, et le navigateur exige qu'elle soit déclenchée par un geste utilisateur tel qu'un clic.

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

C'est tout le moteur. Le reste de cet article l'enveloppe dans un bouton sur lequel vous pouvez cliquer sur n'importe quelle page.

Un bouton PiP flottant

Cette règle injecte un seul bouton. Cliquer dessus trouve la plus grande vidéo en lecture et la fait sortir. Choisir la plus grande vidéo évite de se déclencher sur de minuscules clips d'arrière-plan ou publicitaires.

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

Le même bouton bascule : si une vidéo est déjà en PiP, il appelle exitPictureInPicture(). La vérification readyState > 0 ignore les vidéos qui n'ont pas encore chargé leurs métadonnées, puisque l'API les rejette.

Double-cliquez n'importe quelle vidéo pour la faire sortir

Si vous préférez pas de bouton à l'écran, liez l'action directement aux vidéos. Cette règle fait qu'un double-clic sur la vidéo elle-même bascule le 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);

Comme l'écouteur utilise la capture, il s'exécute avant le gestionnaire de double-clic propre au site, et preventDefault() empêche le lecteur de basculer en plein écran en même temps.

Réagir aux événements PiP

Vous pouvez garder votre interface synchronisée en écoutant enterpictureinpicture et leavepictureinpicture sur une vidéo :

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

Astuces pour un comportement fiable

Récupérez une version packagée dans nos exemples prêts à l'emploi ou téléchargez JustZix pour l'ajouter vous-même. Pour empêcher les vidéos de se lancer automatiquement dès le départ, lisez arrêter la lecture automatique vidéo et audio.

Notez cet article

Aucune note — soyez le premier.

Essayez vous-même

Installez JustZix et collez n'importe quel snippet de cet article. Deux minutes de zéro à une règle fonctionnelle sur tous vos appareils.

Obtenir JustZix

Fonctionnalités · Comment ça marche · Exemples · Cas d'usage