Funkcja obraz w obrazie (PIP) umożliwia użytkownikom oglądanie filmów w pływającym oknie. (zawsze nad innymi oknami), dzięki czemu dziecko może dokładnie śledzić, oglądać treści podczas interakcji z innymi witrynami lub aplikacjami.
Za pomocą interfejsu Picture-in-Picture Web API możesz Obraz w obrazie w elementach wideo w witrynie. Wypróbuj na oficjalną próbkę obrazu w obrazie.
Tło
We wrześniu 2016 roku w Safari dodaliśmy obsługę obrazu w obrazie za pomocą interfejsu API WebKit. w systemie macOS Sierra. Pół roku później Chrome automatycznie Funkcja obrazu w obrazie na urządzeniach mobilnych z Androidem O wykorzystującym natywnym Android API. Pół roku później ogłosiliśmy zamiar stworzenia ustandaryzować interfejs Web API, funkcję zgodną z przeglądarką Safari, która umożliwiłaby deweloperom aplikacji do tworzenia i kontrolowania wszystkich funkcji obrazu w obrazie. I o to chodzi!
Zapoznaj się z kodem
Włącz tryb obraz w obrazie
Zacznijmy od elementu wideo i sposobu interakcji użytkownika np. przycisk.
<video id="videoElement" src="https://example.com/file.mp4"></video>
<button id="pipButtonElement"></button>
Żądaj funkcji obraz w obrazie tylko w odpowiedzi na gest użytkownika i nigdy
Metoda promise zwracana przez funkcję videoElement.play()
. To dlatego, że obietnice nie są
jeszcze rozpowszechnić gesty użytkowników. Zamiast tego zadzwoń do requestPictureInPicture()
w
moduł obsługi kliknięć w systemie pipButtonElement
, jak pokazano poniżej. To Ty odpowiadasz
na to, co się stanie, gdy użytkownik kliknie go 2 razy.
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
await videoElement.requestPictureInPicture();
pipButtonElement.disabled = false;
});
Po spełnieniu obietnicy Chrome zmniejsza film do małego okna, użytkownik może się poruszać i przesuwać nad inne okna.
Gotowe. Brawo! Możesz przestać czytać i zająć się urlop. Niestety nie zawsze tak jest. Obietnica może zostać odrzucona w przypadku dowolnego z następujących powodów:
- System nie obsługuje trybu obraz w obrazie.
- Dokument nie może korzystać z funkcji obraz w obrazie z powodu ograniczeń zasadami uprawnień.
- Metadane filmu nie zostały jeszcze wczytane (
videoElement.readyState === 0
). - Plik wideo zawiera tylko dźwięk.
- W elemencie wideo znajduje się nowy atrybut
disablePictureInPicture
. - Połączenie nie zostało wykonane w ramach modułu obsługi zdarzeń gestów (np. kliknięcia przycisku). Od Chrome 74 dotyczy to tylko wtedy, gdy nie ma elementu w Tryb obraz w obrazie jest już włączony.
W sekcji Obsługa funkcji poniżej dowiesz się, jak włączyć lub wyłączyć przycisk na podstawie tych ograniczeń.
Dodajmy blok try...catch
, aby rejestrować te potencjalne błędy i pozwolić
użytkownicy wiedzą, co się dzieje.
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
try {
await videoElement.requestPictureInPicture();
} catch (error) {
// TODO: Show error message to user.
} finally {
pipButtonElement.disabled = false;
}
});
Element wideo działa tak samo niezależnie od tego, czy jest w obrazie w obrazie, czy nie: zdarzenia są wywoływane, a metody wywoływania działają. Odzwierciedla on zmiany stanu okna obrazu w obrazie (takiego jak odtwarzanie, wstrzymywanie, przewijanie itp.), a także w JavaScripcie możesz automatycznie zmienić stan.
Wyłącz obraz w obrazie
Teraz zajmijmy się włączaniem i wyłączaniem obrazu w obrazie za pomocą przełącznika. Śr
najpierw sprawdź, czy obiekt tylko do odczytu document.pictureInPictureElement
czyli elementu wideo. W przeciwnym razie wyślemy prośbę o podanie
Obraz w obrazie jak powyżej. W przeciwnym razie poprosimy Cię o opuszczenie spotkania, dzwoniąc pod numer
document.exitPictureInPicture()
, co oznacza, że film powróci za
oryginalnej karty. Pamiętaj, że ta metoda zwraca też obietnicę.
...
try {
if (videoElement !== document.pictureInPictureElement) {
await videoElement.requestPictureInPicture();
} else {
await document.exitPictureInPicture();
}
}
...
Słuchanie zdarzeń z funkcją obraz w obrazie
Systemy operacyjne zwykle ograniczają obraz w obrazie do jednego okna, Implementacja Chrome opiera się na tym wzorcu. Oznacza to, że użytkownicy mogą grać tylko jeden film w trybie obraz w obrazie jednocześnie. Użytkownicy powinni wyjść Funkcja obraz w obrazie nawet wtedy, gdy o to nie prosisz.
Nowe moduły obsługi zdarzeń enterpictureinpicture
i leavepictureinpicture
pozwalają
aby dostosować je do potrzeb użytkowników. Może to być wszystko, od przeglądania
katalog filmów, aby wyświetlić czat na żywo.
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.
});
Dostosowywanie okna obrazu w obrazie
Chrome 74 obsługuje przyciski odtwarzania/wstrzymywania, poprzedniego utworu i następnego utworu Okno obrazu w obrazie, którym możesz sterować za pomocą interfejsu Media Session API.
![Sterowanie odtwarzaniem multimediów w oknie obrazu w obrazie](https://developer.chrome.com/static/blog/watch-video-using-picture-in-picture/image/media-playback-controls-b73d819a65211.png?authuser=19&hl=pl)
Domyślnie w obrazie w obrazie jest zawsze widoczny przycisk odtwarzania/wstrzymywania
chyba że w filmie są odtwarzane obiekty MediaStream (np. getUserMedia()
,
getDisplayMedia()
, canvas.captureStream()
) lub film ma MediaSource
czas trwania ustawiony na +Infinity
(np. kanał na żywo). Aby przycisk odtwarzania/wstrzymywania
jest zawsze widoczny, ustaw moduły obsługi działań sesji multimedialnej dla obydwu parametrów „Odtwarzanie” oraz
„Wstrzymaj” zdarzeń związanych z multimediami.
// 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.
});
Wyświetlam „Poprzedni utwór” i „Następny utwór” są podobne. Ustawienie Moduły obsługi działań związanych z sesją multimediów będą wyświetlać je w obrazie w obrazie możesz wykonać te działania.
navigator.mediaSession.setActionHandler('previoustrack', function () {
// User clicked "Previous Track" button.
});
navigator.mediaSession.setActionHandler('nexttrack', function () {
// User clicked "Next Track" button.
});
Aby przekonać się, jak to działa, wypróbuj oficjalną próbkę sesji multimedialnej.
Określanie rozmiaru okna obrazu w obrazie
Jeśli chcesz dostosować jakość odtwarzania filmu przed jego rozpoczęciem i po jego zakończeniu. w przypadku funkcji obraz w obrazie należy znać rozmiar okna obrazu w obrazie powiadomienia, gdy użytkownik ręcznie zmieni rozmiar okna.
Poniższy przykład pokazuje, jak obliczyć szerokość i wysokość Okno obraz w obrazie po utworzeniu lub zmianie rozmiaru.
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.
}
Nie łącz się bezpośrednio ze zdarzeniem zmiany rozmiaru po wprowadzeniu każdej drobnej zmiany. na rozmiar okna obrazu w obrazie spowoduje uruchomienie osobnego zdarzenia, które może jeśli wykonujesz kosztowne operacje przy każdej zmianie rozmiaru. W Innymi słowy, operacja zmiany rozmiaru spowoduje ciągłe uruchamianie zdarzeń bardzo szybko. Polecam użycie popularnych technik, takich jak ograniczanie
Obsługa funkcji
Interfejs Picture-in-Picture Web API może nie być obsługiwany, więc musisz to wykryć
i wprowadzaj kolejne usprawnienia. Nawet jeśli jest obsługiwana, może
wyłączone przez użytkownika lub wyłączone przez zasadę uprawnień. Na szczęście
nową wartość logiczną document.pictureInPictureEnabled
.
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.');
}
Zastosowanie do konkretnego elementu przycisku w filmie. określić widoczność przycisku obrazu w obrazie.
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;
}
Obsługa wideo MediaStream
Film odtwarza obiekty MediaStream (np. getUserMedia()
, getDisplayMedia()
,
canvas.captureStream()
) obsługują też funkcję obraz w obrazie w Chrome 71. Ten
Oznacza to, że możesz pokazać okno z obrazem w obrazie, na którym znajduje się kamera internetowa użytkownika
strumienia wideo, strumienia wideo w sieci reklamowej, a nawet elementu canvas. Pamiętaj, że parametr
Element wideo nie musi być dołączony do DOM, aby można go było otworzyć.
Obraz w obrazie, jak pokazano poniżej.
Pokazuj kamerę internetową użytkownika w oknie obrazu w obrazie
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
Pokaż wyświetlacz w oknie obrazu w obrazie
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getDisplayMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
Pokaż element canvas w oknie obrazu w obrazie
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();
Dzięki połączeniu canvas.captureStream()
z Media Session API możesz
może utworzyć okno playlisty audio w Chrome 74. Poznaj oficjalnego
Próbka playlisty audio.
![Playlista audio w oknie obrazu w obrazie](https://developer.chrome.com/static/blog/watch-video-using-picture-in-picture/image/audio-playlist-a-picture-4c2f236920dae.jpeg?authuser=19&hl=pl)
Przykłady, wersje demonstracyjne i ćwiczenia z programowania
Wypróbuj naszą oficjalną próbkę obrazu w obrazie i wypróbuj ją. Web API.
Później będą dostępne prezentacje i ćwiczenia z programowania.
Co dalej?
Najpierw na stronie Stan implementacji dowiesz się, które fragmenty kodu Interfejs API jest obecnie zaimplementowany w Chrome i innych przeglądarkach.
Oto, czego możesz się spodziewać w najbliższej przyszłości:
- Programiści stron internetowych będą mogli dodawać niestandardowe elementy sterujące funkcji obraz w obrazie.
- Udostępnimy nowy interfejs Web API do wyświetlania dowolnych obiektów
HTMLElement
w pływającym oknie.
Obsługa przeglądarek
Interfejs Picture-in-Picture Web API jest obsługiwany w przeglądarkach Chrome, Edge, Opera i Safari. Szczegółowe informacje znajdziesz w MDN.
Zasoby
- Stan funkcji Chrome: https://www.chromestatus.com/feature/5729206566649856
- Błędy implementacji Chrome: https://crbug.com/?q=component:Blink>Media>PictureInPicture
- Specyfikacja interfejsu Picture-in-Picture Web API: https://wicg.github.io/picture-in-picture
- Problemy ze specyfikacją: https://github.com/WICG/picture-in-picture/issues
- Przykład: https://googlechrome.github.io/samples/picture-in-picture/
- Nieoficjalny kod polyfill na obraz w obrazie: https://github.com/gbentaieb/pip-polyfill/
Dziękujemy Mounir Lamouri i Jennifer Apacible za pracę obraz w obrazie i pomoc w tym artykule. Dziękuję wszystkim w procesy standaryzacyjne.