Donanım medya tuşlarıyla entegrasyon, medya bildirimlerini özelleştirme ve daha pek çok konuda daha fazla yöntem.
Kullanıcıların tarayıcılarında o anda neyin oynatıldığını bilmelerini sağlamak ve tarayıcıyı başlatan sayfaya dönmeden kontrol etmelerini sağlamak için Media Session API'si kullanıma sunuldu. Web geliştiricilerinin bu deneyimi; özel medya bildirimlerindeki meta veriler, oynatma, duraklatma, arama, değiştirme gibi medya etkinlikleri ve mikrofonun sesini kapatma/açma, kamerayı açma/kapatma ve telefonu kapatma gibi video konferans etkinlikleri aracılığıyla özelleştirmelerine olanak tanır. Bu özelleştirmeler; masaüstü medya merkezleri, mobil cihazlardaki ve hatta giyilebilir cihazlardaki medya bildirimleri dahil olmak üzere çeşitli bağlamlarda kullanılabilir. Söz konusu özelleştirmeleri bu makalede açıklayacağım.
![Medya Oturumu bağlamlarının ekran görüntüleri.](https://web.dev/static/articles/media-session/image/screenshots-media-sessio-f4629fe9ea633.jpg?authuser=5&hl=tr)
Media Session API'si hakkında
Medya oturumu API'sı çeşitli avantajlar ve olanaklar sunar:
- Donanım medya anahtarları desteklenir.
- Medya bildirimleri mobilde, masaüstünde ve eşlenmiş giyilebilir cihazda özelleştirilir.
- Medya merkezi masaüstünde kullanılabilir.
- Kilit ekranı medya denetimleri, ChromeOS ve mobil cihazlarda kullanılabilir.
- Pencere İçinde Pencere pencere kontrolleri; ses oynatma, video konferans ve sunum slaytları için kullanılabilir.
- Mobil cihazlarda Asistan entegrasyonu kullanılabilir.
Bu noktaların bazıları birkaç örnekle gösterilmiştir.
1. Örnek: Kullanıcılar klavyelerinin "sonraki parça" medya tuşuna basarsa web geliştiricileri, tarayıcının ön planda veya arka planda olmasına bakılmaksızın bu kullanıcı işlemini gerçekleştirebilir.
2. Örnek: Kullanıcılar cihaz ekranları kilitliyken web'de bir podcast dinlerlerse de kilit ekranı medya denetimlerindeki "geriye git" simgesine basarak web geliştiricilerinin oynatma süresini birkaç saniye geriye taşıyabilirler.
3. Örnek: Kullanıcıların ses çalan sekmeleri varsa masaüstündeki medya merkezinden oynatmayı kolayca durdurabilirler. Böylece web geliştiricilerinin durumlarını temizleme şansı olur.
4. Örnek: Kullanıcılar bir video görüşmesindeyse, web sitesinin mikrofon verilerini almasını durdurmak için Pencere İçinde Pencere penceresinde "mikrofonu aç/kapat" denetimine basabilir.
Bu işlemlerin tümü iki farklı arayüz üzerinden yapılır: MediaSession
arayüzü ve MediaMetadata
arayüzü. Birincisi, kullanıcıların oynatılan içeriği
kontrol etmelerine olanak tanır. İkincisi, MediaSession
hizmetine nelerin kontrol edilmesi gerektiğini nasıl bildirdiğinizdir.
Örnek olarak, aşağıdaki resimde bu arayüzlerin belirli medya kontrolleriyle (bu örnekte, mobil ortamdaki bir medya bildirimi) ilişkisi gösterilmektedir.
![Medya Oturumu arayüzlerinin resmi.](https://web.dev/static/articles/media-session/image/media-session-interfaces-c7bc0962a921c.jpg?authuser=5&hl=tr)
Kullanıcılara oynatılan içeriği bildirin
Bir web sitesinde ses veya video oynatıldığında, kullanıcılar mobil cihazlardaki bildirim tepsisinde veya masaüstünde medya merkezinde otomatik olarak medya bildirimleri alır. Tarayıcı, dokümanın başlığını ve bulunabileceği en büyük simge resmini kullanarak uygun bilgileri göstermek için elinden geleni yapar. Medya Oturumu API'sı ile medya bildirimini aşağıda gösterildiği gibi başlık, sanatçı adı, albüm adı ve poster gibi bazı zengin medya meta verileriyle özelleştirebilirsiniz.
Chrome, yalnızca medya süresi en az 5 saniye olduğunda medya bildirimlerini göstermek için "tam" ses odağını ister. Bu sayede, çınlama gibi arızi seslerin bildirimlerin gösterilmemesi sağlanır.
// After media (video or audio) starts playing
await document.querySelector("video").play();
if ("mediaSession" in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
artist: 'Rick Astley',
album: 'Whenever You Need Somebody',
artwork: [
{ src: 'https://via.placeholder.com/96', sizes: '96x96', type: 'image/png' },
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
{ src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
{ src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
});
// TODO: Update playback state.
}
Oynatma sona erdiğinde, bildirim otomatik olarak kaybolacağı için medya oturumunu "bırakmanıza" gerek yoktur. Yine de bir sonraki oynatma başladığında navigator.mediaSession.metadata
öğesinin kullanılacağını unutmayın. Bu nedenle, medya bildiriminde alakalı bilgilerin gösterildiğinden emin olmak için medya oynatma kaynağı değiştiğinde bu ayarı güncellemek önemlidir.
Medya meta verileri ile ilgili göz önünde bulundurulması gereken birkaç nokta vardır.
- Bildirim posteri dizisi, blob URL'lerini ve veri URL'lerini destekler.
- Hiç poster tanımlanmamışsa ve istediğiniz boyutta bir simge resmi (
<link rel=icon>
ile belirtilir) varsa medya bildirimleri bunu kullanır. - Android için Chrome'da bildirim çiziminin hedef boyutu:
512x512
. Düşük teknolojili cihazlar için bu fiyat256x256
. - Media HTML öğesinin
title
özelliği, macOS "Şimdi oynatılıyor" widget'ında kullanılır. - Medya kaynağı yerleştirilmişse (örneğin bir iframe içine) Media Session API bilgileri yerleştirilmiş bağlamdan ayarlanmalıdır. Aşağıdaki snippet'i inceleyin.
<iframe id="iframe">
<video>...</video>
</iframe>
<script>
iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
...
});
</script>
Medya meta verilerine bölümün başlığı, zaman damgası ve ekran görüntüsü resmi gibi bölüm bilgilerini tek tek ekleyebilirsiniz. Bu, kullanıcıların medya içeriğinde gezinmesine olanak tanır.
navigator.mediaSession.metadata = new MediaMetadata({
// title, artist, album, artwork, ...
chapterInfo: [{
title: 'Chapter 1',
startTime: 0,
artwork: [
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
}, {
title: 'Chapter 2',
startTime: 42,
artwork: [
{ src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
{ src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
]
}]
});
![ChromeOS medya bildiriminde gösterilen bölüm bilgileri.](https://web.dev/static/articles/media-session/image/screenshot-notification-chapter.jpg?authuser=5&hl=tr)
Kullanıcıların oynatılan içeriği kontrol etmesine izin verin
Medya oturumu işlemi, bir web sitesinin mevcut medya oynatmayla etkileşimde
bulunduğunda kullanıcılar için gerçekleştirebileceği bir işlemdir (örneğin "oynat" veya "duraklat"). Eylemler olaylara benzer ve onlarla hemen hemen aynı şekilde işler. Etkinliklerde olduğu gibi, işlemler de uygun bir nesne (bu örnekte MediaSession
örneği) üzerinde işleyiciler ayarlanarak uygulanır. Kullanıcılar mikrofonlu kulaklık, başka bir uzak cihaz veya klavyedeki düğmelere bastığında ya da bir medya bildirimiyle etkileşimde bulunduğunda bazı işlemler tetiklenir.
![Windows 10'daki bir medya bildiriminin ekran görüntüsü.](https://web.dev/static/articles/media-session/image/screenshot-a-media-notif-0b640cbe50bb1.jpg?authuser=5&hl=tr)
Bazı medya oturumu işlemleri desteklenmediğinden, bunları ayarlarken bir try…catch
engellemesi kullanmanız önerilir.
const actionHandlers = [
['play', () => { /* ... */ }],
['pause', () => { /* ... */ }],
['previoustrack', () => { /* ... */ }],
['nexttrack', () => { /* ... */ }],
['stop', () => { /* ... */ }],
['seekbackward', (details) => { /* ... */ }],
['seekforward', (details) => { /* ... */ }],
['seekto', (details) => { /* ... */ }],
/* Video conferencing actions */
['togglemicrophone', () => { /* ... */ }],
['togglecamera', () => { /* ... */ }],
['hangup', () => { /* ... */ }],
/* Presenting slides actions */
['previousslide', () => { /* ... */ }],
['nextslide', () => { /* ... */ }],
];
for (const [action, handler] of actionHandlers) {
try {
navigator.mediaSession.setActionHandler(action, handler);
} catch (error) {
console.log(`The media session action "${action}" is not supported yet.`);
}
}
Medya oturumu işlem işleyicisini kaldırmak, null
olarak ayarlamak kadar kolaydır.
try {
// Unset the "nexttrack" action handler at the end of a playlist.
navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
console.log(`The media session action "nexttrack" is not supported yet.`);
}
Ayarlandıktan sonra medya oturumu işlem işleyicileri, medya oynatmaları boyunca devam eder. Bu, etkinlik işleyici kalıbına benzerdir. Tek fark, bir etkinliğin işlenmesinin, tarayıcının herhangi bir varsayılan davranışı yapmayı bırakması ve bunu, web sitesinin medya işlemini desteklediğine dair bir sinyal olarak kullanması anlamına gelir. Bu nedenle, uygun işlem işleyici ayarlanmadığı sürece medya işlemi kontrolleri gösterilmez.
![macOS Big Sur'daki Ne Çalıyor? widget'ının ekran görüntüsü.](https://web.dev/static/articles/media-session/image/screenshot-the-playing-178373d8aea09.jpg?authuser=5&hl=tr)
Oynatma / duraklatma
"play"
işlemi kullanıcının medya oynatmayı devam ettirmek istediğini belirtirken "pause"
işlemi geçici olarak durdurmak istediğini belirtir.
"Oynat/duraklat" simgesi her zaman medya bildiriminde gösterilir ve ilgili medya etkinlikleri, tarayıcı tarafından otomatik olarak işlenir. Varsayılan davranışlarını geçersiz kılmak için "oynat" ve "duraklat" medya işlemlerini aşağıda gösterildiği gibi gerçekleştirin.
Örneğin, tarayıcı, arama yaparken veya yüklerken bir web sitesinin medya oynatmadığını düşünebilir. Bu durumda, web sitesi kullanıcı arayüzünün medya bildirimi kontrolleriyle senkronize kalmasını sağlamak için navigator.mediaSession.playbackState
değerini "playing"
veya "paused"
olarak ayarlayarak bu davranışı geçersiz kılın.
const video = document.querySelector('video');
navigator.mediaSession.setActionHandler('play', async () => {
// Resume playback
await video.play();
});
navigator.mediaSession.setActionHandler('pause', () => {
// Pause active playback
video.pause();
});
video.addEventListener('play', () => {
navigator.mediaSession.playbackState = 'playing';
});
video.addEventListener('pause', () => {
navigator.mediaSession.playbackState = 'paused';
});
Önceki parça
"previoustrack"
işlemi, medya oynatmanın başlangıç kavramı varsa kullanıcının geçerli medya oynatmayı baştan başlatmak veya medya oynatmada oynatma listesi fikri varsa oynatma listesindeki bir önceki öğeye geçmek istediğini belirtir.
navigator.mediaSession.setActionHandler('previoustrack', () => {
// Play previous track.
});
Sonraki parça
"nexttrack"
işlemi, medya oynatmada bir oynatma listesi fikri varsa kullanıcının medya oynatmayı oynatma listesindeki bir sonraki öğeye taşımak istediğini belirtir.
navigator.mediaSession.setActionHandler('nexttrack', () => {
// Play next track.
});
Durdur
"stop"
işlemi, kullanıcının medya oynatmayı durdurmak ve uygunsa durumu temizlemek istediğini belirtir.
navigator.mediaSession.setActionHandler('stop', () => {
// Stop playback and clear state if appropriate.
});
Geri / ileri sar
"seekbackward"
işlemi, kullanıcının medya oynatma süresini kısa bir süreliğine geriye taşımak istediğini gösterir. "seekforward"
ise medya oynatma süresini kısa bir süre ileriye taşımak istediğini gösterir. Kısa dönem her iki durumda da birkaç saniye anlamına gelir.
İşlem işleyicide sağlanan seekOffset
değeri, medya oynatma süresinin saniye cinsinden aktarılacağı süredir. Belirtilmemişse (örneğin, undefined
) makul bir süre kullanmalısınız (örneğin 10-30 saniye).
const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
const skipTime = details.seekOffset || defaultSkipTime;
video.currentTime = Math.max(video.currentTime - skipTime, 0);
// TODO: Update playback state.
});
navigator.mediaSession.setActionHandler('seekforward', (details) => {
const skipTime = details.seekOffset || defaultSkipTime;
video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
// TODO: Update playback state.
});
Belirli bir zamana git
"seekto"
işlemi, kullanıcının medya oynatma süresini belirli bir zamana taşımak istediğini belirtir.
İşlem işleyicide sağlanan seekTime
değeri, medya oynatma süresinin saniye cinsinden taşınacağı süredir.
İşlem, bir dizinin parçası olarak birden çok kez çağrılıyorsa ve bu, söz konusu sıradaki son çağrı değilse işlem işleyicide sağlanan fastSeek
boole'si doğrudur.
const video = document.querySelector('video');
navigator.mediaSession.setActionHandler('seekto', (details) => {
if (details.fastSeek && 'fastSeek' in video) {
// Only use fast seek if supported.
video.fastSeek(details.seekTime);
return;
}
video.currentTime = details.seekTime;
// TODO: Update playback state.
});
Oynatma konumunu ayarla
Bir bildirimde medya oynatma konumunu doğru şekilde görüntülemek, aşağıda gösterildiği gibi konum durumunu uygun bir zamanda ayarlamak kadar basittir. Konum durumu; medya oynatma hızı, süre ve geçerli sürenin birleşimidir.
![ChromeOS'teki kilit ekranı medya denetimlerinin ekran görüntüsü.](https://web.dev/static/articles/media-session/image/screenshot-lock-screen-m-e71582de5ca3d.jpg?authuser=5&hl=tr)
Süre sağlanmalı ve pozitif olmalıdır. Konum pozitif ve süreden küçük olmalıdır. Oynatma hızı 0'dan büyük olmalıdır.
const video = document.querySelector('video');
function updatePositionState() {
if ('setPositionState' in navigator.mediaSession) {
navigator.mediaSession.setPositionState({
duration: video.duration,
playbackRate: video.playbackRate,
position: video.currentTime,
});
}
}
// When video starts playing, update duration.
await video.play();
updatePositionState();
// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
/* ... */
updatePositionState();
});
// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
/* ... */
updatePositionState();
});
// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
/* ... */
updatePositionState();
});
// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
updatePositionState();
});
Konum durumunu sıfırlamak, null
olarak ayarlamak kadar kolaydır.
// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);
Video konferans işlemleri
Kullanıcı, video görüşmesini Pencere İçinde Pencere penceresine yerleştirdiğinde tarayıcı, mikrofon, kamera ve görüşmeyi sonlandırma denetimlerini görüntüleyebilir. Kullanıcı bu tıklamaları tıkladığında web sitesi bunları aşağıdaki video konferans işlemleri aracılığıyla işler. Örnek için Video Konferans örneğini inceleyin.
![Pencere İçinde Pencere penceresindeki video konferans denetimlerinin ekran görüntüsü.](https://web.dev/static/articles/media-session/image/screenshot-video-confere-7e82acef00cdb.jpg?authuser=5&hl=tr)
Mikrofonu aç/kapat
"togglemicrophone"
işlemi, kullanıcının mikrofonun sesini kapatmak veya açmak istediğini gösterir. setMicrophoneActive(isActive)
yöntemi, tarayıcıya, web sitesinin mikrofonun etkin olduğunu
düşünüp algılamadığını bildirir.
let isMicrophoneActive = false;
navigator.mediaSession.setActionHandler('togglemicrophone', () => {
if (isMicrophoneActive) {
// Mute the microphone.
} else {
// Unmute the microphone.
}
isMicrophoneActive = !isMicrophoneActive;
navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});
Kameralar arasında geçiş yap
"togglecamera"
işlemi, kullanıcının etkin kamerayı açmak veya kapatmak istediğini belirtir. setCameraActive(isActive)
yöntemi, tarayıcının web sitesini etkin olarak kabul edip etmediğini belirtir.
let isCameraActive = false;
navigator.mediaSession.setActionHandler('togglecamera', () => {
if (isCameraActive) {
// Disable the camera.
} else {
// Enable the camera.
}
isCameraActive = !isCameraActive;
navigator.mediaSession.setCameraActive(isCameraActive);
});
Görüşmeyi bitir
"hangup"
işlemi, kullanıcının bir aramayı sonlandırmak istediğini gösterir.
navigator.mediaSession.setActionHandler('hangup', () => {
// End the call.
});
Slaytlarla sunulan işlemler
Kullanıcı, slayt sunularını Pencere İçinde Pencere penceresine yerleştirdiğinde, tarayıcı, slaytlar arasında gezinmeye ilişkin denetimleri görüntüleyebilir. Kullanıcılar bu tıklamaları tıkladığında web sitesi bunları Media Session API üzerinden işler. Örnek için Slaytlar'ı gösterme örneğini inceleyin.
Önceki slayt
"previousslide"
işlemi, kullanıcının slaytları sunarken bir önceki slayta dönmek istediğini gösterir.
navigator.mediaSession.setActionHandler('previousslide', () => {
// Show previous slide.
});
Tarayıcı Desteği
- 111
- 111
- x
- x
Sonraki slayt
"nextslide"
işlemi, kullanıcının slaytları sunarken sonraki slayta geçmek istediğini gösterir.
navigator.mediaSession.setActionHandler('nextslide', () => {
// Show next slide.
});
Tarayıcı Desteği
- 111
- 111
- x
- x
Numuneler
Blender Foundation ve Jan Morgenstern'ın çalışmalarının yer aldığı bazı Medya Oturumu örneklerine göz atın.
Kaynaklar
- Medya Oturumu Özellikleri: wicg.github.io/mediasession
- Teknik Özelliklerle İlgili Sorunlar: github.com/WICG/mediasession/issues
- Chrome Hataları: crbug.com