You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否桥接Media Session API与Web Speech API实现硬件按键控制语音播放?

实现硬件按键控制Web Speech API语音合成(结合Media Session API)

可行性说明

完全可以打通这两个API,实现硬件播放/暂停按键控制语音合成的启停与续播。Media Session API的核心是允许自定义播放控制行为,不需要依赖<audio>或<video>元素——只要为play和pause动作绑定对应回调函数,在函数里控制speechSynthesis的播放状态即可。

需要注意:speechSynthesis本身没有原生的暂停方法,只能通过cancel()终止当前合成。因此要实现续播,需要自行维护播放进度(比如拆分文本片段、记录当前播放位置),暂停后从断点重新开始合成。

最简可行演示代码

以下是完整可运行示例,包含核心逻辑:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Speech + Media Session Demo</title>
</head>
<body>
    <button id="controlBtn">开始播放</button>

    <script>
        // 全局状态:跟踪播放进度与合成实例
        let textSegments = [];
        let currentSegmentIndex = 0;
        let isPlaying = false;

        // 初始化Media Session
        if ('mediaSession' in navigator) {
            navigator.mediaSession.metadata = new MediaMetadata({
                title: '语音合成演示',
                artist: 'Web Speech API',
            });

            // 绑定播放动作回调
            navigator.mediaSession.setActionHandler('play', () => {
                if (!isPlaying) resumeSpeech();
            });

            // 绑定暂停动作回调
            navigator.mediaSession.setActionHandler('pause', () => {
                if (isPlaying) pauseSpeech();
            });
        }

        // 启动语音合成:拆分文本为句子片段
        function startSpeech(text = '这是一段测试文本。你可以使用硬件播放暂停键控制我的播放。') {
            textSegments = text.split('。').filter(seg => seg.trim());
            currentSegmentIndex = 0;
            isPlaying = true;
            updateMediaSessionState();
            playNextSegment();
        }

        // 播放下一个文本片段
        function playNextSegment() {
            if (currentSegmentIndex >= textSegments.length) {
                isPlaying = false;
                updateMediaSessionState();
                document.getElementById('controlBtn').textContent = '开始播放';
                return;
            }

            const segment = textSegments[currentSegmentIndex];
            const utterance = new SpeechSynthesisUtterance(segment);
            
            // 当前片段播放完成后自动播放下一段
            utterance.onend = () => {
                currentSegmentIndex++;
                playNextSegment();
            };

            speechSynthesis.speak(utterance);
        }

        // 暂停语音合成
        function pauseSpeech() {
            isPlaying = false;
            updateMediaSessionState();
            speechSynthesis.cancel();
            document.getElementById('controlBtn').textContent = '继续播放';
        }

        // 续播语音合成
        function resumeSpeech() {
            isPlaying = true;
            updateMediaSessionState();
            playNextSegment();
            document.getElementById('controlBtn').textContent = '暂停播放';
        }

        // 更新Media Session播放状态
        function updateMediaSessionState() {
            if ('mediaSession' in navigator) {
                navigator.mediaSession.playbackState = isPlaying ? 'playing' : 'paused';
            }
        }

        // 绑定按钮控制逻辑
        document.getElementById('controlBtn').addEventListener('click', () => {
            if (isPlaying) {
                pauseSpeech();
            } else {
                if (currentSegmentIndex === 0) {
                    startSpeech();
                } else {
                    resumeSpeech();
                }
            }
        });
    </script>
</body>
</html>

关键逻辑说明

  1. Media Session配置:设置媒体元数据(标题、艺术家),并为play/pause动作绑定回调,直接关联语音合成的启停逻辑。
  2. 文本拆分与进度跟踪:将长文本拆分为句子片段,通过currentSegmentIndex记录当前播放位置,实现断点续播。
  3. 状态同步:每次播放/暂停时更新mediaSession.playbackState,确保系统媒体控件显示正确的播放状态。

测试注意事项

  • 桌面端Chrome:页面需要处于激活状态(有焦点)才能响应键盘媒体键。
  • 安卓端Chrome:网站需通过HTTPS访问(本地开发用localhost不受限制),蓝牙耳机需支持媒体控制功能。
  • 若语音合成无声音,检查Chrome的语音设置(确保已安装对应语言的语音包)。

内容的提问来源于stack exchange,提问作者Matt V.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:43:22