Videos mit der Funktion „Bild im Bild“ ansehen

François Beaufort
François Beaufort

Mit Bild im Bild (BiB) können Nutzer Videos in einem schwebenden Fenster ansehen. (immer über anderen Fenstern), damit sie im Auge behalten können, Videos ansehen, während du mit anderen Websites oder Anwendungen interagierst.

Mit der Bild-im-Bild-Web-API kannst du „Bild im Bild“ für Videoelemente auf Ihrer Website Probieren Sie es aus in unserem offizielles Bild im Bild.

Hintergrund

Seit September 2016 unterstützt Safari die Funktion „Bild im Bild“ über eine WebKit API. in macOS Sierra. Sechs Monate später spielte Chrome automatisch Bild-im-Bild-Video auf Mobilgeräten nach Einführung von Android O mit einem native Android API Sechs Monate später haben wir unsere Absicht bekannt gegeben, eine Web-API zu standardisieren, die mit Safari kompatibel ist und Web-APIs Entwickelnden nutzen, um das gesamte Erlebnis rund um die Funktion „Bild im Bild“ zu schaffen und zu kontrollieren. Und hier sind wir!

Code eingeben

Bild im Bild aktivieren

Beginnen wir mit einem Videoelement und einer Möglichkeit, mit der Nutzer interagieren können. wie ein Schaltflächenelement.

<video id="videoElement" src="https://example.com/file.mp4"></video>
<button id="pipButtonElement"></button>

Die Funktion „Bild im Bild“ darf nur als Reaktion auf eine Nutzergeste angefordert werden, nicht für die Funktion promise wurde von videoElement.play() zurückgegeben. Das liegt daran, dass Versprechungen noch werden Nutzergesten übertragen. Rufen Sie stattdessen requestPictureInPicture() in einem Klick-Handler für pipButtonElement, wie unten gezeigt. Es liegt in Ihrer Verantwortung. um zu erkennen, was passiert, wenn ein Nutzer zweimal klickt.

pipButtonElement.addEventListener('click', async function () {
  pipButtonElement.disabled = true;

  await videoElement.requestPictureInPicture();

  pipButtonElement.disabled = false;
});

Sobald das Versprechen aufgelöst ist, komprimiert Chrome das Video in einem kleinen Fenster, das der Nutzende sich bewegen und über anderen Fenstern positionieren kann.

Fertig! Gut gemacht! Hören Sie auf zu lesen und nehmen Sie Ihren wohlverdienten Urlaub. Leider ist das nicht immer der Fall. Das Versprechen kann aus folgenden Gründen:

  • Bild im Bild wird vom System nicht unterstützt.
  • Das Dokument darf „Bild im Bild“ aufgrund einer Einschränkung nicht verwenden Berechtigungsrichtlinie
  • Die Videometadaten wurden noch nicht geladen (videoElement.readyState === 0).
  • Videodatei hat nur Audio.
  • Das neue Attribut disablePictureInPicture ist im Videoelement vorhanden.
  • Der Aufruf wurde nicht über einen Touch-Gesten-Ereignis-Handler des Nutzers durchgeführt (z.B. ein Klick auf eine Schaltfläche). Ab Chrome 74 gilt dies nur dann, wenn in Bild im Bild schon.

Im Abschnitt Unterstützung von Funktionen unten erfahren Sie, wie Sie eine Schaltfläche basierend auf diese Einschränkungen zu erfüllen.

Wir fügen einen try...catch-Block hinzu, um diese potenziellen Fehler zu erfassen, damit die Nutzenden wissen, was los ist.

pipButtonElement.addEventListener('click', async function () {
  pipButtonElement.disabled = true;

  try {
    await videoElement.requestPictureInPicture();
  } catch (error) {
    // TODO: Show error message to user.
  } finally {
    pipButtonElement.disabled = false;
  }
});

Das Videoelement verhält sich gleich, egal, ob es sich um Bild-im-Bild- oder Nicht: Ereignisse werden ausgelöst und Aufrufmethoden funktionieren. Sie spiegelt Statusänderungen in wie z. B. Wiedergabe, Pause, Suche usw. Status programmatisch in JavaScript ändern.

Bild im Bild beenden

Jetzt ändern wir die Funktion zum Ein- und Ausschalten von Bild im Bild. Mi. müssen zuerst prüfen, ob das schreibgeschützte Objekt document.pictureInPictureElement ist unser Videoelement. Ist dies nicht der Fall, senden wir Ihnen eine Teilnahmeanfrage, Bild im Bild wie oben. Andernfalls bitten wir Sie, uns per Anruf document.exitPictureInPicture(), was bedeutet, dass das Video wieder in zum ursprünglichen Tab. Beachte, dass diese Methode auch ein Promise zurückgibt.

    ...
    try {
      if (videoElement !== document.pictureInPictureElement) {
        await videoElement.requestPictureInPicture();
      } else {
        await document.exitPictureInPicture();
      }
    }
    ...

Auf Bild-im-Bild-Ereignisse warten

Betriebssysteme beschränken die Bild-im-Bild-Funktion in der Regel auf ein Fenster, sodass Die Implementierung von Chrome folgt diesem Muster. Das bedeutet, dass Nutzer immer nur ein Bild-im-Bild-Video. Sie sollten davon ausgehen, dass die Nutzenden Bild im Bild, auch wenn du nicht danach gefragt hast.

Mit den neuen Event-Handlern enterpictureinpicture und leavepictureinpicture die Nutzererfahrung individuell zu gestalten. Das kann alles sein, vom Durchstöbern einer Videokataloge erstellen, einen Livestream-Chat veröffentlichen.

videoElement.addEventListener('enterpictureinpicture', function (event) {
  // Video entered Picture-in-Picture.
});

videoElement.addEventListener('leavepictureinpicture', function (event) {
  // Video left Picture-in-Picture.
  // User may have played a Picture-in-Picture video from a different page.
});

Bild-im-Bild-Fenster anpassen

Chrome 74 unterstützt die Schaltflächen für Wiedergabe/Pause, den vorherigen und den nächsten Titel in den Bild-im-Bild-Fenster, das Sie mit der Media Session API steuern können.

Steuerelemente für die Medienwiedergabe in einem Bild-im-Bild-Fenster
Abbildung 1. Steuerelemente für die Medienwiedergabe in einem Bild-im-Bild-Fenster

Standardmäßig wird im Bild-im-Bild-Modus immer eine Schaltfläche für Wiedergabe/Pause angezeigt. wenn das Video MediaStream-Objekte wiedergibt (z.B. getUserMedia(), getDisplayMedia(), canvas.captureStream()) oder das Video hat eine MediaSource Dauer auf +Infinity festgelegt (z.B. Livefeed). Um sicherzugehen, dass eine Schaltfläche für Wiedergabe/Pause immer sichtbar ist, legen Sie einige Handler für Media Session-Aktionen für "Wiedergabe" fest. und „Pausieren“ Medienereignisse wie unten beschrieben.

// Show a play/pause button in the Picture-in-Picture window
navigator.mediaSession.setActionHandler('play', function () {
  // User clicked "Play" button.
});
navigator.mediaSession.setActionHandler('pause', function () {
  // User clicked "Pause" button.
});

"Vorheriger Titel" wird angezeigt und „Nächster Titel“ Fenstersteuerung ähnlich. Einstellung Media Session-Aktions-Handler für diese Elemente zeigen sie im Bild-im-Bild-Modus an. und können diese Aktionen ausführen.

navigator.mediaSession.setActionHandler('previoustrack', function () {
  // User clicked "Previous Track" button.
});

navigator.mediaSession.setActionHandler('nexttrack', function () {
  // User clicked "Next Track" button.
});

Das offizielle Media Session-Beispiel können Sie sich in Aktion ansehen.

Fenstergröße für „Bild im Bild“ abrufen

Wenn du die Videoqualität beim Ein- und Ausblenden des Videos anpassen möchtest: „Bild im Bild“ verwenden, müssen Sie die Größe des Bild-im-Bild-Fensters kennen wird benachrichtigt, wenn ein Nutzer die Größe des Fensters manuell ändert.

Im Beispiel unten sehen Sie, wie Sie die Breite und Höhe des Bild-im-Bild-Fenster, wenn es erstellt oder seine Größe geändert wird.

let pipWindow;

videoElement.addEventListener('enterpictureinpicture', function (event) {
  pipWindow = event.pictureInPictureWindow;
  console.log(`> Window size is ${pipWindow.width}x${pipWindow.height}`);
  pipWindow.addEventListener('resize', onPipWindowResize);
});

videoElement.addEventListener('leavepictureinpicture', function (event) {
  pipWindow.removeEventListener('resize', onPipWindowResize);
});

function onPipWindowResize(event) {
  console.log(
    `> Window size changed to ${pipWindow.width}x${pipWindow.height}`
  );
  // TODO: Change video quality based on Picture-in-Picture window size.
}

Ich empfehle, das Ereignis zum Ändern der Größe nicht direkt zu aktivieren, da jede kleine Änderung die Größe des Bild-im-Bild-Fensters ändert, wird ein separates Ereignis ausgelöst, das möglicherweise teurer Vorgang bei jeder Größenänderung durchführen. In Mit anderen Worten, der Vorgang zur Größenanpassung löst die Ereignisse immer wieder aus, schnell ändern. empfehle ich dir gängige Techniken wie Drosselung und Enthüllen, um dieses Problem zu beheben.

Funktionsunterstützung

Die Bild-im-Bild-Web-API wird möglicherweise nicht unterstützt. Progressive Enhancement zu ermöglichen. Auch wenn es unterstützt wird, vom Nutzer deaktiviert oder durch eine Berechtigungsrichtlinie deaktiviert haben. Glücklicherweise können Sie den neuen booleschen document.pictureInPictureEnabled, um dies zu bestimmen.

if (!('pictureInPictureEnabled' in document)) {
  console.log('The Picture-in-Picture Web API is not available.');
} else if (!document.pictureInPictureEnabled) {
  console.log('The Picture-in-Picture Web API is disabled.');
}

Wenn er auf ein bestimmtes Schaltflächenelement in einem Video angewendet wird, die Sichtbarkeit der Schaltfläche „Bild im Bild“ anpassen.

if ('pictureInPictureEnabled' in document) {
  // Set button ability depending on whether Picture-in-Picture can be used.
  setPipButton();
  videoElement.addEventListener('loadedmetadata', setPipButton);
  videoElement.addEventListener('emptied', setPipButton);
} else {
  // Hide button if Picture-in-Picture is not supported.
  pipButtonElement.hidden = true;
}

function setPipButton() {
  pipButtonElement.disabled =
    videoElement.readyState === 0 ||
    !document.pictureInPictureEnabled ||
    videoElement.disablePictureInPicture;
}

Unterstützung von MediaStream-Videos

Video zur Wiedergabe von MediaStream-Objekten (z.B. getUserMedia(), getDisplayMedia(), canvas.captureStream()) unterstützen auch Bild im Bild in Chrome 71. Dieses Du kannst ein Bild-im-Bild-Fenster anzeigen, das die Webcam des Nutzers enthält. Videostream, Display-Videostream oder sogar Canvas-Elemente. Das Feld muss nicht an das DOM angehängt werden, um Bild im Bild (siehe unten).

Webcam des Nutzers im Bild-im-Bild-Fenster anzeigen

const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
video.play();

// Later on, video.requestPictureInPicture();

Anzeige im Bild-im-Bild-Fenster anzeigen

const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getDisplayMedia({video: true});
video.play();

// Later on, video.requestPictureInPicture();

Canvas-Element im Bild-im-Bild-Fenster anzeigen

const canvas = document.createElement('canvas');
// Draw something to canvas.
canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height);

const video = document.createElement('video');
video.muted = true;
video.srcObject = canvas.captureStream();
video.play();

// Later on, video.requestPictureInPicture();

Wenn Sie canvas.captureStream() mit der Media Session API kombinieren, können Sie ein Fenster mit einer Audioplaylist in Chrome 74 erstellen. In der offiziellen Beispiel für eine Audioplaylist:

Audioplaylist in einem Bild-im-Bild-Fenster
Abbildung 2. Audioplaylist in einem Bild-im-Bild-Fenster

Beispiele, Demos und Codelabs

Sieh dir unser offizielles Bild im Bild an, um die Funktion „Bild im Bild“ auszuprobieren. Web API

Es folgen Demos und Codelabs.

Weiteres Vorgehen

Sehen Sie sich zunächst die Seite mit dem Implementierungsstatus an. Dort sehen Sie, welche Teile des APIs sind derzeit in Chrome und anderen Browsern implementiert.

Folgendes ist in Kürze zu erwarten:

Unterstützte Browser

Die Bild-im-Bild-Web-API wird in Chrome, Edge, Opera und Safari unterstützt. Weitere Informationen finden Sie unter MDN.

Ressourcen

Vielen Dank an Mounir Lamouri und Jennifer Apacible für ihre Arbeit an „Bild im Bild“ und Hilfe zu diesem Artikel. Vielen Dank an alle, an der Standardisierung beteiligt sind.