Media Session API 是一种让网页在系统级媒体通知栏显示元信息并响应播放控制的接口,支持 play、pause、seekbackward、seekforward 等预设动作,但不控制音频播放本身,需配合 HTMLMediaElement 使用。

Media Session API 是什么,它能控制哪些播放行为
Media Session API 允许网页在系统级媒体通知栏(如 Android 锁屏、Windows 任务栏缩略图、macOS 控制中心)中显示自定义元信息,并响应播放/暂停/跳转等系统级操作。它不控制音频播放本身,只接管通知栏交互逻辑;实际播放仍需用 HTMLMediaElement(如 <audio> 或 <video>)配合实现。
- 必须在用户手势(如 click、touchstart)触发后才能调用
navigator.mediaSession.setActionHandler(),否则静默失败 - 只有处于活跃标签页且媒体已开始播放(或至少调用过
play())时,系统才可能显示通知栏 - 不支持自定义按钮图标或布局,仅能设置预设动作类型(
play、pause、seekbackward等)和元数据
设置 metadata 和 action handler 的最小可行代码
核心是两步:设置媒体元数据 + 绑定动作处理器。注意顺序和时机——必须在媒体元素可播放后设置,否则部分平台(如 Chrome on Android)会忽略 metadata。
<audio id="player" src="song.mp3"></audio>
<button id="playBtn">Play</button>
<p><script>
const audio = document.getElementById('player');
const playBtn = document.getElementById('playBtn');</p><p>playBtn.addEventListener('click', async () => {
try {
await audio.play();
// ✅ 必须在 play() 成功后设置,否则 metadata 可能不显示
if ('mediaSession' in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: 'My Song',
artist: 'Me',
album: 'Demo',
artwork: [{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' }]
});</p><pre class='brush:php;toolbar:false;'> navigator.mediaSession.setActionHandler('play', () => audio.play());
navigator.mediaSession.setActionHandler('pause', () => audio.pause());
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
audio.currentTime = Math.max(0, audio.currentTime - (details.seekOffset || 10));
});
navigator.mediaSession.setActionHandler('seekforward', (details) => {
audio.currentTime = Math.min(audio.duration, audio.currentTime + (details.seekOffset || 10));
});
}} catch (err) { console.warn('Play failed:', err.message); } }); </script>
-
artwork数组必须包含至少一个有效图片 URL,否则某些系统(如 iOS)直接隐藏整个通知栏 -
seekbackward/seekforward的details.seekOffset来自系统默认快进/快退时长(通常为 10 秒),但用户长按按钮时可能传入不同值,需兼容处理 - 不要重复调用
setActionHandler,多次设置会覆盖前一次,无报错提示
常见失效原因:为什么点了播放没反应,或通知栏根本不出现
这不是代码写错了,而是被浏览器策略或平台限制拦截了:
-
navigator.mediaSession在非安全上下文(即 HTTP 页面)中为undefined,必须用 HTTPS - 媒体元素未设置
controls属性或未触发过用户手势,Chrome 会拒绝激活 media session - 音频未设置
muted且自动播放被阻止(尤其桌面 Chrome),导致play()拒绝执行,后续 mediaSession 设置无效 - Android Chrome 要求页面在前台、媒体正在播放(
audio.readyState >= 2且audio.paused === false)才显示锁屏控件;切到后台几秒后自动隐藏 - iOS Safari 目前完全不支持
setActionHandler,仅显示元数据,所有按钮点击无响应(这是已知限制,不是 bug)
监听 playbackState 变化做状态同步的必要性
系统通知栏的播放/暂停状态与页面内 audio.paused 并不同步。例如用户在锁屏点暂停,audio 元素确实暂停了,但页面 JS 不知道——除非你主动监听 playbackstatechanged 事件。
立即学习“前端免费学习笔记(深入)”;
if ('mediaSession' in navigator) {
navigator.mediaSession.addEventListener('playbackstatechanged', (event) => {
console.log('Playback state changed to:', event.playbackState);
// event.playbackState 是 'playing' | 'paused' | 'none'
// 这里可更新 UI 按钮状态、同步播放器内部状态等
});
}
- 此事件仅在系统主动变更状态时触发(如锁屏点暂停),不响应 JS 调用
audio.pause() - 如果你的播放器有多个音源切换逻辑,必须在此事件中重置
mediaSession.metadata,否则通知栏仍显示旧歌曲信息 -
event.playbackState在部分旧版 Chrome 中不可靠,建议同时监听audio元素的play和pause事件做兜底
Media Session API 表面简单,但真正稳定生效依赖大量平台差异处理和时机判断;最容易被忽略的是「必须由用户手势触发播放」这一前提——所有后续设置都建立在这个基础上,漏掉就全盘失效。



















