Pencere İçinde Pencere (PIP), kullanıcıların kayan bir pencerede video izlemesine olanak tanır. (her zaman diğer pencerelerin üstünde görünür) olduğundan bu öğeleri takip edebilirler. diğer site veya uygulamalarla etkileşimde bulunurken içerik izleme.
Pencere İçinde Pencere Web API'si ile ağdaki Web sitenizdeki video öğeleri için Pencere İçinde Pencere. Hemen deneyin: resmi Pencere İçinde Pencere örneği.
Arka plan
Safari, Eylül 2016'da WebKit API üzerinden Pencere İçinde Pencere desteği ekledi . Altı ay sonra Chrome otomatik olarak oynatıldı Android O sürümü çıktıktan sonra yerel Android API. Altı ay sonra, kendimizi geliştirmeyi amaçladığımızı Safari'ninkiyle uyumlu bir özellik sunan ve web'e izin veren bir Web API'sini standart geliştiricilerin pencere içinde pencere özelliğiyle eksiksiz bir deneyim oluşturup kontrol etmesini sağlayabilirsiniz. İşte oldu.
Kodu öğrenin
Pencere içinde pencere moduna gir
Bir video öğesiyle ve kullanıcının etkileşime girebileceği bir yolla başlayalım bunu kullanabilirsiniz.
<video id="videoElement" src="https://example.com/file.mp4"></video>
<button id="pipButtonElement"></button>
Pencere içinde pencere özelliğini yalnızca kullanıcı hareketine yanıt olarak isteyin ve
taahhüt videoElement.play()
tarafından iade edildi. Çünkü vaatler
henüz kullanıcı hareketlerini uygulayabilir. Bunun yerine, requestPictureInPicture()
öğesini
pipButtonElement
üzerindeki tıklama işleyiciyi aşağıda gösterildiği gibi görebilirsiniz. Bu sizin sorumluluğunuzdadır
ve kullanıcı iki kez tıkladığında ne olacağını.
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
await videoElement.requestPictureInPicture();
pipButtonElement.disabled = false;
});
Vadettiğimiz söz konusu olduğunda Chrome, videoyu küçülterek kullanıcı diğer pencereler arasında gezinebilir ve bu pencerelerin üzerine gelebilir.
Hepsi bu kadar. Tebrikler! Okumayı bırakıp hak ettiğiniz şeyi alabilirsiniz Ne yazık ki bu her zaman geçerli değil. Vaat, herhangi bir durumda reddedilebilir aşağıdakilerden biri olabilir:
- Pencere içinde pencere özelliği sistem tarafından desteklenmiyor.
- Dokümanda, kısıtlayıcı nedeniyle Pencere İçinde Pencere kullanımına izin verilmiyor. izinler politikasına bakın.
- Video meta verileri henüz yüklenmedi (
videoElement.readyState === 0
). - Video dosyası yalnızca ses içeriyor.
- Yeni
disablePictureInPicture
özelliği, video öğesinde bulunur. - Arama, bir kullanıcı hareketi etkinlik işleyicisinde (ör. düğme tıklaması) yapılmadı. Chrome 74'ten itibaren bu yalnızca Pencere İçinde Pencere zaten mevcut.
Aşağıdaki Özellik desteği bölümünde, bir düğmenin bu kısıtlamalara bağlıdır.
Bu olası hataları yakalamak için bir try...catch
bloku ekleyelim ve
ne olup bittiğini anlamasını sağlar.
pipButtonElement.addEventListener('click', async function () {
pipButtonElement.disabled = true;
try {
await videoElement.requestPictureInPicture();
} catch (error) {
// TODO: Show error message to user.
} finally {
pipButtonElement.disabled = false;
}
});
Video öğesi, pencere içinde pencere veya pencere biçiminde olsun, aynı şekilde davranır. değil: Etkinlikler tetiklenir ve çağrı yöntemleri çalışır. Bölgedeki durum değişikliklerini yansıtır. Pencere İçinde Pencere (oynatma, duraklatma, sarma vb.) ve aynı zamanda JavaScript'te durumun programlı olarak değiştirilmesini sağlar.
Pencere İçinde Pencere modundan çık
Şimdi, düğmemizi Pencere İçinde Pencere moduna girmek ve pencereden çıkmak için düğmemizi yapalım. Biz
önce document.pictureInPictureElement
salt okunur nesnesinin olup olmadığını kontrol etmem gerekir
video öğemizdir. Değilse, giriş yapılması için bir istek
Yukarıdaki gibi Pencere İçinde Pencere. Aksi takdirde,
document.exitPictureInPicture()
. Bu değer, videonun şurada tekrar gösterileceği anlamına gelir:
orijinal sekme. Bu yöntemin aynı zamanda bir vaat döndürdüğünü unutmayın.
...
try {
if (videoElement !== document.pictureInPictureElement) {
await videoElement.requestPictureInPicture();
} else {
await document.exitPictureInPicture();
}
}
...
Pencere İçinde Pencere etkinliklerini dinleme
İşletim sistemleri, Pencere İçinde Pencere özelliğini genellikle tek bir pencereyle kısıtlar. Chrome'un uygulaması bu kalıbı izler. Yani kullanıcılar yalnızca oyun pencere içinde pencere eklemeniz gerekir. Kullanıcıların çıkış yapmasını beklemeniz gerekir. Siz istemeseniz bile pencere içinde pencere özelliğini kullanabilirsiniz.
Yeni enterpictureinpicture
ve leavepictureinpicture
etkinlik işleyicileri
kullanıcı deneyimi için özelleştirmemize yardımcı oluyor. Bu, bir web sitesine göz atmaktan veya
video kataloğundan canlı sohbetlere kadar her şeyi gösterir.
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.
});
Pencere içinde pencere penceresini özelleştirme
Chrome 74, Google Haritalar'da oynat/duraklat, önceki parça ve sonraki parça düğmelerini destekler Media Session API'yi kullanarak kontrol edebileceğiniz Pencere İçinde Pencere penceresi.
'nı inceleyin.Varsayılan olarak Pencere İçinde Pencere'de oynat/duraklat düğmesi her zaman gösterilir
penceresinde MediaStream nesneleri (ör. getUserMedia()
,
getDisplayMedia()
, canvas.captureStream()
) veya videoda bir MediaSource varsa
süre +Infinity
olarak ayarlanmış olmalıdır (ör. canlı feed). Oynatma/duraklatma düğmesinin
her zaman görünür olduğundan, hem "Oynat" için hem de Medya Oturumu işlem işleyicileri ayarlayın ve
"Pause" (Duraklat) gerçekleştirebilirsiniz.
// 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.
});
"Önceki Parça" gösteriliyor ve "Sonraki parça" benzerdir. Ayar Bu kullanıcılar için Medya Oturumu işlem işleyicileri Pencere İçinde Pencerede gösterilir bu işlemleri gerçekleştirebilirsiniz.
navigator.mediaSession.setActionHandler('previoustrack', function () {
// User clicked "Previous Track" button.
});
navigator.mediaSession.setActionHandler('nexttrack', function () {
// User clicked "Next Track" button.
});
Bunun nasıl çalıştığını görmek için resmi Medya Oturumu örneğini deneyin.
Pencere İçinde Pencere pencere boyutunu alma
Video girip çıktığında video kalitesini ayarlamak istiyorsanız Pencere içinde pencere boyutunu bilmeniz ve Kullanıcı pencereyi manuel olarak yeniden boyutlandırırsa bildirim alır.
Aşağıdaki örnekte, Pencere içinde pencere, oluşturulduğunda veya yeniden boyutlandırıldığında.
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.
}
Her küçük değişiklik yapıldığından doğrudan yeniden boyutlandırma etkinliğine bağlanmamanızı öneririm. farklı bir etkinlik tetikler. Bu durum, her yeniden boyutlandırmada pahalı bir işlem yapıyorsanız performans sorunları yaşanabilir. İçinde başka bir deyişle, yeniden boyutlandırma işlemi etkinlikleri tekrar tekrar tetikler. pek çok yolu vardır. Kısıtlama ve kontrol etme gibi yaygın teknikleri hata ayıklamayı deneyin.
Özellik desteği
Pencere İçinde Pencere Web API'si desteklenmiyor olabilir. Bu nedenle bu durumu tespit etmeniz gerekir.
sağlayabilirsiniz. Desteklendiğinde bile
veya bir izin politikası tarafından devre dışı bırakılmış olabilir. Neyse ki
yeni boole document.pictureInPictureEnabled
değerini kullanın.
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.');
}
Bir video için belirli bir düğme öğesine uygulandığında, pencere içinde pencere düğmenizin görünürlüğünü kontrol altında tutun.
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;
}
MediaStream video desteği
MediaStream nesneleri (ör. getUserMedia()
, getDisplayMedia()
,
canvas.captureStream()
), Chrome 71'de Pencere İçinde Pencere'yi de destekler. Bu
kullanıcının web kamerasını içeren bir Pencere İçinde Pencere penceresi gösterebileceğiniz anlamına gelir.
video akışı, görüntülü video akışı ve hatta bir tuval öğesi. Lütfen
giriş için video öğesinin DOM'ye eklenmesi gerekmez.
Aşağıda gösterildiği gibi Pencere İçinde Pencere'yi seçin.
Kullanıcının web kamerasını Pencere İçinde Pencere penceresinde göster
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getUserMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
Pencere içinde pencere penceresinde ekranı göster
const video = document.createElement('video');
video.muted = true;
video.srcObject = await navigator.mediaDevices.getDisplayMedia({video: true});
video.play();
// Later on, video.requestPictureInPicture();
Tuval öğesini Pencere İçinde Pencere penceresinde gösterme
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();
canvas.captureStream()
özelliğini Media Session API ile birleştirerek
Örneğin, Chrome 74'te bir ses oynatma listesi penceresi oluşturun. Resmi web sitesine göz atın
Ses oynatma listesi örneği.
Örnekler, demolar ve codelab'ler
Pencere içinde pencere özelliğini denemek için resmi Pencere İçinde Pencere örneğimize göz atın. Web API'si.
Ardından demolar ve codelab'ler gelir.
Sırada ne var?
Öncelikle uygulama durumu sayfasına göz atarak API şu anda Chrome ve diğer tarayıcılarda uygulanmaktadır.
Yakın gelecekte aşağıdaki değişiklikleri göreceksiniz:
- Web geliştiricileri özel pencere içinde pencere denetimleri ekleyebilir.
- Kayan pencerede rastgele
HTMLElement
nesnelerini görüntülemek için yeni bir Web API sağlanacaktır.
Tarayıcı desteği
Pencere İçinde Pencere Web API'si Chrome, Edge, Opera ve Safari'de desteklenir. Ayrıntılar için MDN bölümüne bakın.
Kaynaklar
- Chrome Özellik Durumu: https://www.chromestatus.com/feature/5729206566649856
- Chrome Uygulama Hataları: https://crbug.com/?q=component:Blink>Media>PictureInPicture
- Pencere İçinde Pencere Web API'si Spesifikasyonu: https://wicg.github.io/picture-in-picture
- Spesifikasyon sorunları: https://github.com/WICG/picture-in-picture/issues
- Örnek: https://googlechrome.github.io/samples/picture-in-picture/
- Resmi olmayan pencere içinde pencere çoklu dolgusu: https://github.com/gbentaieb/pip-polyfill/
Mounir Lamouri ve Jennifer Apacible'a Pencere İçinde Pencere ve bu makaleyle ilgili yardım. Herkese teşekkür ederim. standartlaştırma çabasına dahil edilir.