Ali GÖREN

JavaScript ile Picture in Picture API Kullanımı

Selamlar. Bu yazıda size JavaScript ile Picture in Picture API Kullanımı hakkında bilgi sunmaya çalışacağım. Öncelikle ilgili bilgilere bu linkten ulaşabilirsiniz.

JavaScript ile Picture in Picture API Kullanımı

JavaScript ile Picture in Picture API Kullanımı

Öncelikle bu API ne yapıyor ona bakmalıyız. Bu API kullanıldığı websitesinde bir pencere daha oluşturulmasına imkan tanıyor. Oluşturulan bu pencere yani window top level bir pencere. Açık olan tüm pencerelerin önüne, sağ alt kısma yerleştiriliyor. Bu sayede media akışlarını yani videoları başka sekmelere geçseniz de kullanabiliyorsunuz.

Tarayıcıyı alta aldığınızda ya da bir başka sekmeye geçtiğinizde etkileşim devam ederken, üste çıkmış olan video penceresi de devam edecektir. İyi olan şu ki siz burada tasarımsal bir şey yapmak zorunda değilsiniz. Şu anda bu tarz bir polyfill var mı bilmiyorum. Açıkcası eğer bu özellik desteklenmiyor ise çalışmayacak. Dilerseniz Can I Use üzerinden kontrol edebilirsiniz.

Sevgili Firefox bey mobil sürümünde bunu desteklerken, masaüstü sürümünde buna dair bir desteğe sahip değil. Genel tarayıcı yüzdesine bakarsak şu anda çoğu tarayıcı direkt desteklemiyor. Chrome 100% bu desteği sunan tek tarayıcı. Kısacası uygulamaları bunun üzerine inşaa etmek için henüz erken.

Nasıl Yapılır?

Varsyalım ki şöyle bir video ve butona sahipsiniz;

<video class="pipSource"
  src="https://cdn.arnellebalane.com/videos/original-video.mp4"
  controls
></video>

<button>Enter Picture-in-Picture</button>

CSS ise şöyle olsun. Videoyu geniş ekran getirelim 🙂

video {
    width: 100%;
    
}

JavaScript ile bu botun ve video elementini yakalayalım.

const btn = document.querySelector("button")
const vid = document.querySelector(".pipSource")

Şimdi buton değil de scroll olunca bu işlem yapılsın gibi bir şey istiyorsanız maalesef bu mümkün değil. Bu işlem mutlaka kullanıcının hareketini gerektiriyor. Bu da click ya da touch oluyor. Onun için ben de click event'ini yakalayacağım. Bu arada click eventinden önce bu event'in kullanılabilir olup olmadığını kontrol etmeliyiz. Değilse hata almamak için butonu en başta disable edebilir ya da hide diyebiliriz;

if (!('pictureInPictureEnabled' in document)) {
  btn.hide = true;
  throw new Error('The Picture-in-Picture Web API is not available')
}
else if (!document.pictureInPictureEnabled) {
  btn.hide = true;
  throw new Error('The Picture-in-Picture Web API is disabled.')
}

Bu sayede hem butonu disable edeceğiz hem de bi error vereceğiz. Neyin yanlış gittiğini göreceğiz. Diyelim ki bu aşamalar doğru. O zaman hadi gidelim click event'i ne yapacak bakalım.

btn.addEventListener('click', async () => {
    
    if(!document.pictureInPictureElement) {
        await vid.requestPictureInPicture()
        .catch(ex => {
            console.log(ex.message)
        })
    } else {
        await document.exitPictureInPicture()
        .catch(ex => {
            console.log(ex.message)
        })
    }
    
    
})

Öncelikle pictureInPictureEnabled ve pictureInPictureElement karıştırılmamalı. İlki tarayıcı ayarı ile alakalı bir durumken, diğeri ise bu özelliğin kullanıcı tarafından JavaScript API kullanılarak daha önce aktif hale getirilip getirilmediği ile alakalı.

Bu arada eventListener'daki callback async olmak zorunda değil. Eğer yapmayacaksanız await keywordünü kaldırın. İlk if bloğundan içeri girdiğimizde video için Picture-in-Picture moduna geçmesi konusunda bir istek oluşturuyoruz. Bu promise dönüyor. Orada then kullanılabilir ya da direkt olarak catch ile hata yakalayabilirsiniz. Bu hata genellikle DOMException olarak dönecektir. Farklı hataya denk gelemedim henüz.

Eğer halihazırda zaten bu Picture-in-Picture modu aktifse else içerisine girecek bu moddan çıkış yapmak için bir istek oluşturacatır. Yine catch mekanizması da aynı. Scroll ile buton click eventini tetiklediğinizde bu catch'deki mesajlar size dönecektir.

Picture-in-Picture Mode Eventleri

Şimdi gelelim bu moda girişte ve çıkışta oluşan eventlere. Kısacası bu moda girince buton gösterilmesin, çıkılınca gösterilsin istiyorsanız şunu yapabilirsiniz.

vid.addEventListener('enterpictureinpicture', (ev) => {
    console.log(ev.pictureInPictureWindow)
    btn.hidden = true
})

vid.addEventListener('leavepictureinpicture', () => {
    btn.hidden = false
})

enter ile başlayan PIP aktifken yapılacak işlemler için, leave ile başlayansa PIP moddan çıkılınca yapılacak işlemleri tarif eder. İlk listenerda ayrıca callback'in aldığı argüman, sağ altta açılan window için bir dizi özelliği getirir. Örneğin şöyle bir yapımız olsun

vid.addEventListener('enterpictureinpicture', (ev) => {
    const pipWindow = ev.pictureInPictureWindow
    
    pipWindow.addEventListener('resize', (data) => {
        console.log('Resizing...', data)
    })
    btn.hidden = true
})

Bu kod yine ilk event'in aynısı ama ayrıca buranın içerisinde sağ altta çıkan pencereyi resize etmeye çalıştığımızda gerçekleşecek olayları da belirtebiliyoruz.

CodePen Örneği

Şu anlık bu yazıda anlatabileceğim bu kadar arkadaşlar. Bu yazıda JavaScript ile Picture in Picture API Kullanımı hakkında bilgin edindik. Umarım faydalı olur. Okuduğunuz için teşekkür ederim.

Kaynaklar:

https://wicg.github.io/picture-in-picture/

https://developers.google.com/web/updates/2018/10/watch-video-using-picture-in-picture

https://googlechrome.github.io/samples/picture-in-picture/

https://dev.to/ananyaneogi/implement-picture-in-picture-on-the-web-17g8