Cara mengintegrasikan tombol media hardware, menyesuaikan notifikasi media, dan lainnya.
Untuk memberi tahu pengguna konten yang sedang diputar di browser mereka dan mengontrolnya tanpa kembali ke halaman yang meluncurkannya, Media Session API telah diperkenalkan. Ini memungkinkan pengembang web untuk menyesuaikan pengalaman ini melalui metadata di notifikasi media khusus, peristiwa media seperti putar, jeda, mencari, melacak perubahan, dan peristiwa konferensi video seperti membisukan/membunyikan mikrofon, mengaktifkan/menonaktifkan kamera, dan menutup telepon. Penyesuaian tersebut adalah tersedia dalam beberapa konteks termasuk hub media desktop, notifikasi media di perangkat seluler, dan bahkan di perangkat wearable. Saya akan menjelaskan penyesuaian tersebut di artikel ini.
![Screenshot konteks Sesi Media.](https://web.developers.google.cn/static/articles/media-session/image/screenshots-media-sessio-f4629fe9ea633.jpg?authuser=0000&hl=id)
Tentang Media Session API
Media session API memberikan beberapa manfaat dan kemampuan:
- Tombol media hardware didukung.
- Notifikasi media disesuaikan di 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 hal tersebut.
Contoh 1: Jika pengguna menekan "trek berikutnya" tombol media pada {i>keyboard<i} mereka, developer web dapat menangani tindakan pengguna ini baik saat browser digunakan di latar depan atau latar belakang.
Contoh 2: Jika pengguna mendengarkan podcast di web saat menggunakan perangkat saat layar terkunci, pengguna masih dapat menekan tombol "Cari mundur" ikon dari kunci mengontrol media layar sehingga developer web dapat memundurkan waktu pemutaran detik.
Contoh 3: Jika pengguna memiliki tab yang memutar audio, mereka dapat berhenti dengan mudah pemutaran dari hub media di desktop sehingga pengembang web memiliki kesempatan untuk membersihkan statusnya.
Contoh 4: Jika pengguna sedang melakukan panggilan video, mereka dapat menekan tombol "tombol" mikrofon" di jendela Picture-in-Picture untuk menghentikan situs web agar yang menerima data mikrofon.
Ini semua dilakukan melalui dua antarmuka yang berbeda: Antarmuka MediaSession
dan antarmuka MediaMetadata
. Yang pertama memungkinkan
pengguna mengontrol apa pun
sedang diputar. Yang kedua adalah cara Anda memberi tahu MediaSession
apa yang perlu dikontrol.
Untuk mengilustrasikan, gambar di bawah menampilkan bagaimana antarmuka ini berhubungan dengan kontrol media, dalam hal ini adalah notifikasi media di seluler.
![Ilustrasi antarmuka Sesi Media.](https://web.developers.google.cn/static/articles/media-session/image/media-session-interfaces-c7bc0962a921c.jpg?authuser=0000&hl=id)
Beri tahu pengguna media apa yang sedang diputar
Saat situs web memutar audio atau video, pengguna secara otomatis mendapatkan media notifikasi di baki notifikasi di ponsel, atau hub media di {i>desktop<i}. Browser melakukan yang terbaik untuk menampilkan informasi yang sesuai dengan menggunakan judul dokumen dan gambar ikon terbesar yang dapat ditemukannya. Dengan Sesi Media memungkinkan penyesuaian notifikasi media dengan beberapa metadata seperti judul, nama artis, nama album, dan poster seperti yang ditampilkan di bawah.
Chrome meminta "lengkap" fokus audio. Untuk menampilkan notifikasi media hanya saat durasi media adalah minimal 5 detik. Hal ini memastikan bahwa suara insidental seperti "ding" tidak akan 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.
}
Setelah pemutaran berakhir, Anda tidak perlu "melepaskan" sesi media sebagai
notifikasi akan hilang secara otomatis. Perlu diingat bahwa
navigator.mediaSession.metadata
akan digunakan saat pemutaran berikutnya dimulai
meskipun begitu. Inilah mengapa penting untuk memperbaruinya
ketika sumber pemutaran media
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
. Sebagai perangkat kelas bawah, yaitu256x256
. - Atribut
title
elemen HTML media digunakan dalam "Now Playing" Widget macOS. - Jika resource media disematkan (misalnya dalam iframe), Media Session API informasi harus ditetapkan dari konteks yang disematkan. 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 segmen satu per satu, seperti judul bagian, stempel waktunya, dan gambar screenshot ke metadata media. Hal ini memungkinkan pengguna untuk menavigasi melalui 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' },
]
}]
});
![Informasi segmen ditampilkan di notifikasi media ChromeOS.](https://web.developers.google.cn/static/articles/media-session/image/screenshot-notification-chapter.jpg?authuser=0000&hl=id)
Izinkan pengguna mengontrol media yang sedang diputar
Tindakan sesi media adalah tindakan (misalnya, "putar" atau "jeda") yang dapat
digunakan oleh pengguna ketika mereka berinteraksi
dengan pemutaran media saat ini. Tindakannya adalah
dianalogikan dan berfungsi
hampir sama dengan kejadian. Seperti halnya peristiwa, tindakan
dengan mengatur pengendali pada objek yang sesuai, yaitu instance
MediaSession
, dalam hal ini. Beberapa tindakan dipicu saat pengguna menekan
dari headset, perangkat jarak jauh lain, {i>keyboard<i}, atau berinteraksi dengan
notifikasi media.
![Screenshot notifikasi media di Windows 10.](https://web.developers.google.cn/static/articles/media-session/image/screenshot-a-media-notif-0b640cbe50bb1.jpg?authuser=0000&hl=id)
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 menyetelnya 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 melalui pemutaran media. Ini mirip dengan pola pemroses peristiwa kecuali bahwa menangani suatu peristiwa berarti bahwa browser berhenti melakukan perilaku {i>default<i} apa pun dan menggunakannya sebagai menunjukkan bahwa situs web mendukung aksi media. Oleh karena itu, kontrol tindakan media tidak akan ditampilkan kecuali jika pengendali tindakan yang tepat telah ditetapkan.
![Screenshot widget Now Playing di macOS Big Sur.](https://web.developers.google.cn/static/articles/media-session/image/screenshot-the-playing-178373d8aea09.jpg?authuser=0000&hl=id)
Memutar / menjeda
Tindakan "play"
menunjukkan bahwa pengguna ingin melanjutkan pemutaran media
sedangkan "pause"
menunjukkan keinginan untuk menghentikannya untuk sementara.
Opsi "putar/jeda" selalu ditampilkan dalam notifikasi media dan peristiwa media ditangani secara otomatis oleh browser. Untuk mengganti perilaku, menangani "play" dan "jeda" tindakan media seperti yang ditunjukkan di bawah ini.
Browser dapat menganggap situs tidak memutar media saat mencari atau
memuat, misalnya. Dalam hal ini, ganti perilaku ini dengan menyetel
navigator.mediaSession.playbackState
kepada "playing"
atau "paused"
untuk memastikan
UI situs tetap tersinkron 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
saat ini pemutaran media dari awal jika pemutaran media memiliki gagasan
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
membersihkan status jika diperlukan.
navigator.mediaSession.setActionHandler('stop', () => {
// Stop playback and clear state if appropriate.
});
Mundur / maju
Tindakan "seekbackward"
menunjukkan bahwa pengguna ingin memindahkan media
waktu pemutaran mundur dengan periode yang singkat, sementara "seekforward"
menunjukkan keinginan
untuk memajukan waktu pemutaran media beberapa saat. 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 diberikan (misalnya undefined
), maka
Anda harus menggunakan waktu yang
masuk akal (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 pemutaran media
waktu ke waktu tertentu.
Nilai seekTime
yang diberikan di pengendali tindakan adalah waktu dalam detik untuk
memindahkan waktu pemutaran media.
Boolean fastSeek
yang disediakan di pengendali tindakan bernilai benar (true) jika tindakan tersebut
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 semudah seperti menyetel status posisi pada waktu yang tepat seperti ditunjukkan di bawah ini. Tujuan status posisi adalah kombinasi dari kecepatan pemutaran media, durasi, dan waktu saat ini.
![Screenshot kontrol media layar kunci di ChromeOS.](https://web.developers.google.cn/static/articles/media-session/image/screenshot-lock-screen-m-e71582de5ca3d.jpg?authuser=0000&hl=id)
Durasi harus diberikan dan bersifat positif. Posisinya harus positif dan kurang dari durasi. Laju 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
Ketika 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 video tindakan konferensi di bawah ini. Sebagai contoh, lihat contoh Konferensi Video.
![Screenshot kontrol konferensi video di jendela Picture-in-Picture.](https://web.developers.google.cn/static/articles/media-session/image/screenshot-video-confere-7e82acef00cdb.jpg?authuser=0000&hl=id)
Aktifkan/nonaktifkan mikrofon
Tindakan "togglemicrophone"
menunjukkan bahwa pengguna ingin membisukan atau membunyikan audio
mikrofon. Metode setMicrophoneActive(isActive)
memberi tahu browser
apakah situs web saat ini
mempertimbangkan mikrofon aktif.
let isMicrophoneActive = false;
navigator.mediaSession.setActionHandler('togglemicrophone', () => {
if (isMicrophoneActive) {
// Mute the microphone.
} else {
// Unmute the microphone.
}
isMicrophoneActive = !isMicrophoneActive;
navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});
Kamera depan/belakang
Tindakan "togglecamera"
menunjukkan bahwa pengguna ingin mengaktifkan
mengaktifkan atau menonaktifkan kamera. Metode setCameraActive(isActive)
menunjukkan apakah
{i>browser<i} menganggap situs web sebagai 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
Ketika pengguna menempatkan presentasi {i>slide<i} mereka ke dalam jendela {i>Picture-in-Picture<i}, browser dapat menampilkan kontrol untuk menavigasi slide. Saat pengguna mengekliknya, situs web akan menanganinya melalui Media Session API. Untuk misalnya, lihat Contoh Presentasi Slide.
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 {i>slide<i}.
navigator.mediaSession.setActionHandler('nextslide', () => {
// Show next slide.
});
Dukungan Browser
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