Media Session API 控制与用户意图
使用 Media Session 元数据、动作处理器、播放状态和可访问回退,不把系统控制当作用户意图证明。
BotBrowser Team
Media Session API 让页面描述当前媒体,并接收浏览器转发的播放、暂停、快进和切换曲目等控制。这些控制是交互信号,却不能证明用户授权了播放、看到了锁屏卡片或接受了远程交易。BotBrowser 可以在获准的合成 fixture 中重放流程并检查页面状态,但不能制造耳机按键,也不能保证操作系统显示通知。在这个 Media Session 场景中,它能验证页面自有状态,不能验证系统事件或真实收听。本指南把控制、播放状态、位置状态和回退路径绑定到一个明确的媒体任务。
W3C Media Session 规范定义元数据、动作处理器、播放状态和位置状态。MDN Media Session API 参考说明浏览器对象,Chrome 指南展示集成方式。这是接口合约,不是所有平台都会提供相同控件的保证。
要点
- 只为页面拥有且对用户可见的媒体任务启动 session。
- 将
metadata、playbackState、动作处理器和位置状态分别管理。 - 只注册播放器能完成的动作,任务结束时删除过期处理器。
- 调用
setPositionState()前验证duration、position和playbackRate。 - 记录
pause-requested或unsupported等有界结果,不记录听众的私密资料。
内容导航
定义媒体任务和元数据
先定义具体任务:播放播客、预览课程或收听批准的列表。写入元数据前应有可见标题、播放按钮和清晰的停止方式。页面加载时就显示专辑封面,可能让系统误以为用户请求了媒体。
navigator.mediaSession.metadata 是展示数据,不是身份记录。MediaMetadata 可以含有 title、artist、album、albumArtist 和 artwork;只保留识别当前条目所需的字段。不要把邮箱、令牌、签名 URL 或隐藏实验标签放进这些字段。图片 URL 也是页面数据,应使用批准资源或省略封面。
媒体元素的拥有组件应管理曲目、元数据 revision 和 playbackState。如果网络响应到达时 trackId 已变化,就丢弃响应。Web Audio 与音频流程文章讨论音频图和麦克风;Media Session 只描述播放,不会授予麦克风权限。
统一使用 idle、intent-recorded、metadata-set、playing、paused、ended、action-rejected、unsupported 和 stale。playing 只表示媒体元素报告开始播放,不表示扬声器真的出声或有人在听。
围绕意图注册动作处理器
setActionHandler() 把浏览器命令连接到页面函数。常见动作有 play、pause、seekbackward、seekforward、previoustrack 和 nexttrack。播放器没有安全实现的动作不要注册。切换付费队列必须有独立产品策略。
每个媒体任务使用新的处理器集合。曲目改变时验证 trackId;任务结束时,在支持的浏览器中用 navigator.mediaSession.setActionHandler(action, null) 删除处理器,清空元数据并将 playbackState 设为 none。旧 callback 不得操作新元素。
callback 是请求,不是授权结论。调用 media.play() 或 media.pause(),捕获拒绝,并在元素确认结果后更新可见控件。收到动作本身不能标记为 playing。Clipboard API 用户意图指南也说明了不能把浏览器转交的请求推断成用户未明确执行的动作。
const task = { fixtureId: 'media-17', trackId: 'episode-04', state: 'intent-recorded' };
const media = document.querySelector('#player');
function record(next) {
task.state = next;
document.querySelector('#status').textContent = next;
}
media.addEventListener('playing', () => {
navigator.mediaSession.playbackState = 'playing';
record('play-complete');
});
media.addEventListener('pause', () => {
navigator.mediaSession.playbackState = 'paused';
record('pause-complete');
});
media.addEventListener('error', () => record('play-rejected'));
navigator.mediaSession.metadata = new MediaMetadata({ title: 'Episode 04', artist: 'Fixture', album: 'Bounded test' });
navigator.mediaSession.setActionHandler('play', async () => {
try {
await media.play();
} catch {
record('play-rejected');
}
});
navigator.mediaSession.setActionHandler('pause', () => {
media.pause();
});
保持播放和位置状态真实
playbackState 只有 none、paused 和 playing。应由媒体元素真实事件更新;被拒绝的 play() 不能变成 playing。setPositionState({ duration, position, playbackRate }) 要求有限且大于 0 的时长、范围内的位置和有限且大于 0 的速率。没有有限时长的直播应跳过调用。
在 timeupdate、seek 完成或曲目切换时更新,不要每帧发送。positionRevision 可防止延迟响应覆盖当前曲目。下表分开浏览器观察与产品结果:
| 观察 | 页面状态 | 安全响应 |
|---|---|---|
没有 mediaSession | unsupported | 保留页面按钮。 |
play 成功 | play-complete | 设置 playbackState: 'playing'。 |
play 被拒绝 | play-rejected | 保持暂停并显示重试。 |
结束后收到 pause | stale | 不自动启动下一曲。 |
| 位置校验失败 | position-skipped | 等待下一次有效样本。 |
Web Share 权限边界文章也遵循这一原则:浏览器 callback 不能证明同意或交付。
拆除控件并保留回退
在 ended、路由变化、退出或显式停止时暂停元素、清空 metadata、将 playbackState 设为 none、移除处理器并释放引用。清理必须幂等。保留可用的播放、暂停、上一曲、下一曲和 seek 按钮,支持键盘并播报 paused、playing、ended 或 play-rejected。
不要用媒体动作绕过 autoplay、同意、付费或账户校验。如果必须点击“开始预览”,先记录 intent-recorded,再安装元数据。play() 等待期间发生导航时,把旧尝试标记为 stale,禁止迟到结果更新新路由。
记录最小 fixture
有用的记录只需 fixtureId、action、state、positionState、fallback、browserVersion 和 context。排除敏感标题、封面字节、账户、完整 URL 和完整异常。分别测试 API 缺失、play() 拒绝以及等待动作期间清理。
{
"fixtureId": "media-17",
"action": "pause",
"state": "pause-complete",
"positionState": "valid",
"fallback": "in-page-controls",
"browserVersion": "156.0",
"fixtureRevision": 3
}
读取结果但不过度推断
BotBrowser 支持在授权上下文中重放 fixture、比较可见状态并保存声明的参数;它不能制造耳机事件、按下系统媒体键、强制锁屏卡片,也不能证明用户实际听过内容。若 mediaSession 缺失,检查回退;若动作到达但页面未变化,检查媒体 promise 和 owner revision。
元数据可能出现在页面之外。敏感预览应使用批准标签,不要把标题与字体、设备或权限结果组合成个人或设备评分。
来源
- Media Session, W3C
- Media Session API, MDN
MediaSession.setActionHandler(), MDNMediaSession.setPositionState(), MDN- Media Session, Chrome
- BotBrowser 自动化一致性
实际结论
把元数据和控制绑定到页面拥有的可见任务。验证播放和位置状态,清理时移除处理器,并保留可访问按钮。只保存有界结果,不保存收听历史。BotBrowser 可以重放合成交互;用户意图、系统展示和真实收听仍不属于该 fixture 的证明范围。
本文属于指南: Web 平台能力面:一致性复核地图