Cara berintegrasi dengan tombol media hardware, menyesuaikan notifikasi media, dan lainnya.
Untuk memberi tahu pengguna tentang konten yang sedang diputar di browser mereka dan mengontrolnya tanpa kembali ke halaman yang meluncurkannya, Media Session API telah diperkenalkan. Hal ini memungkinkan developer web menyesuaikan pengalaman ini melalui metadata dalam notifikasi media kustom, peristiwa media seperti memutar, menjeda, mencari, mengubah trek, dan peristiwa konferensi video seperti membisukan/membatalan bisukan mikrofon, mengaktifkan/menonaktifkan kamera, dan menutup telepon. Penyesuaian ini tersedia dalam beberapa konteks, termasuk hub media desktop, notifikasi media di perangkat seluler, dan bahkan di perangkat wearable. Saya akan menjelaskan penyesuaian ini dalam artikel ini.
Tentang Media Session API
Media Session API memberikan beberapa manfaat dan kemampuan:
- Kunci media hardware didukung.
- Notifikasi media disesuaikan di perangkat seluler, desktop, dan perangkat wearable yang disambungkan.
- Hub media tersedia di desktop.
- Kontrol media layar kunci tersedia di ChromeOS dan perangkat seluler.
- Kontrol jendela Picture-in-Picture tersedia untuk pemutaran audio, konferensi video, dan presentasi slide.
- Integrasi Asisten di perangkat seluler tersedia.
Beberapa contoh akan menggambarkan beberapa poin ini.
Contoh 1: Jika pengguna menekan tombol media "lagu berikutnya" di keyboard, developer web dapat menangani tindakan pengguna ini, baik browser berada di latar depan maupun latar belakang.
Contoh 2: Jika pengguna mendengarkan podcast di web saat layar perangkat mereka terkunci, mereka masih dapat menekan ikon "cari mundur" dari kontrol media layar kunci sehingga developer web memindahkan waktu pemutaran mundur beberapa detik.
Contoh 3: Jika pengguna memiliki tab yang memutar audio, mereka dapat dengan mudah menghentikan pemutaran dari hub media di desktop sehingga developer web memiliki peluang untuk menghapus statusnya.
Contoh 4: Jika pengguna sedang melakukan panggilan video, mereka dapat menekan kontrol "alihkan mikrofon" di jendela Picture-in-Picture untuk menghentikan situs agar tidak menerima data mikrofon.
Semuanya dilakukan melalui dua antarmuka yang berbeda: Antarmuka MediaSession
dan antarmuka MediaMetadata
. Yang pertama memungkinkan pengguna mengontrol apa pun
yang diputar. Yang kedua adalah cara Anda memberi tahu MediaSession
apa yang perlu dikontrol.
Untuk mengilustrasikan, gambar di bawah menunjukkan hubungan antarmuka ini dengan kontrol media tertentu, dalam hal ini notifikasi media di perangkat seluler.
Memberi tahu pengguna apa yang sedang diputar
Saat situs memutar audio atau video, pengguna akan otomatis mendapatkan notifikasi media di baki notifikasi di perangkat seluler, atau hub media di desktop. Browser akan berusaha menampilkan informasi yang sesuai dengan menggunakan judul dokumen dan gambar ikon terbesar yang dapat ditemukan. Dengan Media Session API, Anda dapat menyesuaikan notifikasi media dengan beberapa metadata media yang lebih kaya seperti judul, nama artis, nama album, dan poster seperti yang ditunjukkan di bawah.
Chrome meminta fokus audio "penuh" untuk menampilkan notifikasi media hanya jika durasi media setidaknya 5 detik. Hal ini memastikan bahwa suara insidental seperti bunyi bip tidak menampilkan notifikasi.
// 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.
}
Saat pemutaran berakhir, Anda tidak perlu "melepaskan" sesi media karena
notifikasi akan otomatis menghilang. Perlu diingat bahwa
navigator.mediaSession.metadata
akan digunakan saat pemutaran berikutnya dimulai. Itulah sebabnya Anda harus memperbaruinya saat sumber pemutaran media
berubah untuk memastikan informasi yang relevan ditampilkan di notifikasi media.
Ada beberapa hal yang perlu diperhatikan tentang metadata media.
- Array poster notifikasi mendukung URL blob dan URL data.
- Jika tidak ada poster yang ditentukan dan ada gambar ikon (ditentukan menggunakan
<link rel=icon>
) dengan ukuran yang diinginkan, notifikasi media akan menggunakannya. - Ukuran target poster notifikasi di Chrome untuk Android adalah
512x512
. Untuk perangkat kelas bawah, nilainya adalah256x256
. - Atribut
title
dari elemen HTML media digunakan di widget macOS "Sedang diputar". - Jika resource media disematkan (misalnya dalam iframe), informasi Media Session API harus ditetapkan dari konteks tersemat. Lihat cuplikan di bawah.
<iframe id="iframe">
<video>...</video>
</iframe>
<script>
iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
title: 'Never Gonna Give You Up',
...
});
</script>
Anda juga dapat menambahkan informasi setiap bab, seperti judul bagian, stempel waktunya, dan gambar screenshot ke metadata media. Hal ini memungkinkan pengguna menjelajahi konten media.
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' },
]
}]
});
Mengizinkan pengguna mengontrol konten yang sedang diputar
Tindakan sesi media adalah tindakan (misalnya, "putar" atau "jeda") yang dapat ditangani situs
untuk pengguna saat mereka berinteraksi dengan pemutaran media saat ini. Tindakan
analog dengan dan berfungsi hampir sama dengan peristiwa. Seperti peristiwa, tindakan
diimplementasikan dengan menetapkan pengendali pada objek yang sesuai, yaitu instance
MediaSession
, dalam hal ini. Beberapa tindakan dipicu saat pengguna menekan
tombol dari headset, perangkat jarak jauh lainnya, keyboard, atau berinteraksi dengan
notifikasi media.
Karena beberapa tindakan sesi media mungkin tidak didukung, sebaiknya
gunakan blok try…catch
saat menyetelnya.
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.`);
}
}
Membatalkan penetapan pengendali tindakan sesi media semudah menetapkannya ke null
.
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.`);
}
Setelah ditetapkan, pengendali tindakan sesi media akan tetap ada selama pemutaran media. Ini mirip dengan pola pemroses peristiwa, kecuali bahwa menangani peristiwa berarti browser berhenti melakukan perilaku default apa pun dan menggunakannya sebagai sinyal bahwa situs mendukung tindakan media. Oleh karena itu, kontrol tindakan media tidak akan ditampilkan kecuali jika pengendali tindakan yang sesuai ditetapkan.
Memutar / menjeda
Tindakan "play"
menunjukkan bahwa pengguna ingin melanjutkan pemutaran media
sedangkan "pause"
menunjukkan keinginan untuk menghentikannya untuk sementara.
Ikon "putar/jeda" selalu ditampilkan dalam notifikasi media dan peristiwa media terkait ditangani secara otomatis oleh browser. Untuk mengganti perilaku defaultnya, tangani tindakan media "putar" dan "jeda" seperti yang ditunjukkan di bawah.
Browser mungkin menganggap situs tidak memutar media saat mencari atau
memuat, misalnya. Dalam hal ini, ganti perilaku ini dengan menetapkan
navigator.mediaSession.playbackState
ke "playing"
atau "paused"
untuk memastikan
UI situs tetap sinkron dengan kontrol notifikasi media.
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';
});
Lagu sebelumnya
Tindakan "previoustrack"
menunjukkan bahwa pengguna ingin memulai
pemutaran media saat ini dari awal jika pemutaran media memiliki konsep
awal, atau berpindah ke item sebelumnya dalam playlist jika pemutaran media
memiliki konsep playlist.
navigator.mediaSession.setActionHandler('previoustrack', () => {
// Play previous track.
});
Lagu berikutnya
Tindakan "nexttrack"
menunjukkan bahwa pengguna ingin memindahkan pemutaran media ke
item berikutnya dalam playlist jika pemutaran media memiliki konsep playlist.
navigator.mediaSession.setActionHandler('nexttrack', () => {
// Play next track.
});
Hentikan
Tindakan "stop"
menunjukkan bahwa pengguna ingin menghentikan pemutaran media dan
menghapus statusnya jika sesuai.
navigator.mediaSession.setActionHandler('stop', () => {
// Stop playback and clear state if appropriate.
});
Mundur/maju
Tindakan "seekbackward"
menunjukkan bahwa pengguna ingin memindahkan waktu pemutaran
media mundur dalam jangka waktu singkat, sedangkan "seekforward"
menunjukkan keinginan
untuk memajukan waktu pemutaran media dalam jangka waktu singkat. Dalam kedua kasus tersebut, periode singkat berarti beberapa detik.
Nilai seekOffset
yang diberikan di pengendali tindakan adalah waktu dalam detik untuk
memindahkan waktu pemutaran media. Jika tidak disediakan (misalnya undefined
), Anda harus menggunakan waktu yang wajar (misalnya 10-30 detik).
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.
});
Mencari ke waktu tertentu
Tindakan "seekto"
menunjukkan bahwa pengguna ingin memindahkan waktu pemutaran
media ke waktu tertentu.
Nilai seekTime
yang diberikan dalam pengendali tindakan adalah waktu dalam detik untuk
memindahkan waktu pemutaran media.
Boolean fastSeek
yang disediakan di pengendali tindakan bernilai benar jika tindakan
dipanggil beberapa kali sebagai bagian dari urutan dan ini bukan panggilan terakhir
dalam urutan tersebut.
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.
});
Menetapkan posisi pemutaran
Menampilkan posisi pemutaran media secara akurat dalam notifikasi sama mudahnya dengan menyetel status posisi pada waktu yang tepat seperti yang ditunjukkan di bawah. Status posisi adalah kombinasi kecepatan pemutaran media, durasi, dan waktu saat ini.
Durasi harus diberikan dan positif. Posisi harus positif dan kurang dari durasi. Kecepatan pemutaran harus lebih besar dari 0.
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();
});
Mereset status posisi semudah menyetelnya ke null
.
// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);
Tindakan konferensi video
Saat pengguna menempatkan panggilan video mereka ke jendela Picture-in-Picture, browser dapat menampilkan kontrol untuk mikrofon dan kamera, serta untuk menutup telepon. Saat pengguna mengkliknya, situs akan menanganinya melalui tindakan konferensi video di bawah. Sebagai contoh, lihat contoh Konferensi Video.
Aktifkan/nonaktifkan mikrofon
Tindakan "togglemicrophone"
menunjukkan bahwa pengguna ingin membisukan atau membunyikan
mikrofon. Metode setMicrophoneActive(isActive)
memberi tahu browser
apakah situs saat ini menganggap mikrofon aktif.
let isMicrophoneActive = false;
navigator.mediaSession.setActionHandler('togglemicrophone', () => {
if (isMicrophoneActive) {
// Mute the microphone.
} else {
// Unmute the microphone.
}
isMicrophoneActive = !isMicrophoneActive;
navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});
Aktifkan/nonaktifkan kamera
Tindakan "togglecamera"
menunjukkan bahwa pengguna ingin mengaktifkan atau menonaktifkan kamera aktif. Metode setCameraActive(isActive)
menunjukkan apakah browser menganggap situs aktif.
let isCameraActive = false;
navigator.mediaSession.setActionHandler('togglecamera', () => {
if (isCameraActive) {
// Disable the camera.
} else {
// Enable the camera.
}
isCameraActive = !isCameraActive;
navigator.mediaSession.setCameraActive(isCameraActive);
});
Menolak panggilan
Tindakan "hangup"
menunjukkan bahwa pengguna ingin mengakhiri panggilan.
navigator.mediaSession.setActionHandler('hangup', () => {
// End the call.
});
Tindakan mempresentasikan slide
Saat pengguna menempatkan presentasi slide ke jendela Picture-in-Picture, browser dapat menampilkan kontrol untuk menavigasi slide. Saat pengguna mengkliknya, situs akan menanganinya melalui Media Session API. Sebagai contoh, lihat Contoh Slide Presentasi.
Slide sebelumnya
Tindakan "previousslide"
menunjukkan bahwa pengguna ingin kembali ke
slide sebelumnya saat mempresentasikan slide.
navigator.mediaSession.setActionHandler('previousslide', () => {
// Show previous slide.
});
Dukungan Browser
Slide berikutnya
Tindakan "nextslide"
menunjukkan bahwa pengguna ingin membuka slide berikutnya
saat mempresentasikan slide.
navigator.mediaSession.setActionHandler('nextslide', () => {
// Show next slide.
});
Dukungan Browser
- x
- x
Contoh
Lihat beberapa contoh Sesi Media yang menampilkan Blender Foundation dan karya Jan Morgenstern.
Resource
- Spesifikasi Sesi Media: wicg.github.io/mediasession
- Masalah Spesifikasi: github.com/WICG/mediasession/issues
- Bug Chrome: crbug.com