无接触交互革命:用语音控制Web通知的完整指南
你是否曾在烹饪时因满手油污无法点击通知?在健身时因汗水浸湿屏幕难以操作提醒?本文将展示如何通过push.js与Web Speech API(语音识别应用程序接口)的组合,打造真正解放双手的通知交互体验。读完本文你将掌握:语音指令控制通知的完整实现方案、跨浏览器兼容性处理技巧,以及三个实用场景的代码模板。
技术原理与架构设计
push.js作为全球最通用的桌面通知框架,其核心优势在于跨平台适配能力。通过src/push/Push.js的模块化设计,我们可以看到它支持五种通知代理:
this._agents = {
desktop: new DesktopAgent(win),
chrome: new MobileChromeAgent(win),
firefox: new MobileFirefoxAgent(win),
ms: new MSAgent(win),
webkit: new WebKitAgent(win)
};
Web Speech API则提供两类核心功能:SpeechRecognition(语音识别)将音频转换为文本,SpeechSynthesis(语音合成)将文本转换为语音。两者结合push.js的通知系统,形成"语音输入→指令解析→通知控制→语音反馈"的完整闭环。
环境准备与基础配置
项目初始化
首先通过GitCode克隆项目仓库:
git clone https://gitcode.com/gh_mirrors/pu/push.js
cd push.js
npm install
核心依赖引入
在HTML文件中同时引入push.js和语音控制模块:
<!-- 引入push.js核心库 -->
<script src="dist/push.min.js"></script>
<!-- 引入语音控制扩展 -->
<script src="src/extensions/speech-control.js"></script>
实现步骤与代码示例
1. 权限申请流程
通知与语音识别均需用户授权,最佳实践是合并权限请求流程:
// 统一权限申请函数
async function requestAllPermissions() {
try {
// 请求通知权限
const pushPermission = await Push.Permission.request();
// 请求麦克风权限
const speechPermission = await navigator.mediaDevices.getUserMedia({ audio: true });
return {
push: pushPermission,
speech: !!speechPermission
};
} catch (error) {
console.error("权限申请失败:", error);
return { push: false, speech: false };
}
}
2. 语音指令识别器实现
创建语音指令解析模块,支持"显示通知"、"关闭通知"、"清除全部"等指令:
class SpeechCommandRecognizer {
constructor() {
this.recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
this.recognition.continuous = true;
this.recognition.interimResults = false;
this.recognition.lang = 'zh-CN';
this.commands = new Map();
this._initCommands();
}
_initCommands() {
// 基础指令映射
this.commands.set(/显示通知 (.+)/i, (text) => {
const content = text.match(/显示通知 (.+)/i)[1];
Push.create("语音指令通知", {
body: content,
icon: "images/notification-icon.png",
timeout: 8000
});
});
this.commands.set(/关闭通知/i, () => {
if (Push.count() > 0) {
// 关闭最新通知
const latestId = Math.max(...Object.keys(Push._notifications));
Push._closeNotification(latestId);
}
});
this.commands.set(/清除全部通知/i, () => {
Push.clear();
this.speak("已清除所有通知");
});
}
start() {
this.recognition.start();
this.recognition.onresult = (event) => {
const transcript = event.results[0][0].transcript;
this._processTranscript(transcript);
};
}
_processTranscript(transcript) {
for (const [pattern, handler] of this.commands) {
if (pattern.test(transcript)) {
handler(transcript);
break;
}
}
}
speak(text) {
const utterance = new SpeechSynthesisUtterance(text);
window.speechSynthesis.speak(utterance);
}
}
3. 与push.js集成
通过push.js的extend方法注册语音控制插件:
// 注册语音控制插件
Push.extend({
plugin: SpeechCommandRecognizer,
config: {
speech: {
autoStart: true,
sensitivity: 0.8
}
}
});
// 初始化语音识别
const speechController = new SpeechCommandRecognizer();
speechController.start();
场景化应用案例
案例1:智能助手通知中心
在客服系统中,当新消息到来时:
- 系统通过push.js发送通知
- 用户说"阅读最新消息"
- 系统调用语音合成朗读消息内容
- 用户说"标记为已读"完成操作
核心代码片段:
// 消息通知与语音控制集成
function showNewMessageNotification(message) {
Push.create("新消息通知", {
body: message.content,
icon: message.senderAvatar,
onClick: () => {
window.focus();
openMessage(message.id);
this.close();
},
onShow: () => {
speechController.speak(`收到来自${message.sender}的新消息`);
}
});
// 添加消息专属语音指令
speechController.commands.set(
new RegExp(`阅读来自${message.sender}的消息`, 'i'),
() => speechController.speak(message.content)
);
}
案例2:厨房烹饪计时器
// 语音控制的烹饪计时器
function startCookingTimer(minutes, dishName) {
const endTime = Date.now() + minutes * 60 * 1000;
Push.create("烹饪计时器", {
body: `正在烹饪${dishName},剩余${minutes}分钟`,
timeout: false, // 不自动关闭
icon: "images/cooking-icon.png"
});
// 每分钟更新一次通知
const interval = setInterval(() => {
const remaining = Math.round((endTime - Date.now()) / 60000);
if (remaining <= 0) {
clearInterval(interval);
Push.clear();
Push.create("烹饪完成", {
body: `${dishName}已烹饪完成!`,
icon: "images/finished-icon.png"
});
speechController.speak(`${dishName}烹饪完成,请取出`);
} else {
Push.update({
body: `正在烹饪${dishName},剩余${remaining}分钟`
});
}
}, 60000);
// 添加语音查询指令
speechController.commands.set(
/还剩多久/i,
() => speechController.speak(`${dishName}还剩${Math.round((endTime - Date.now())/60000)}分钟`)
);
}
兼容性处理与优化
浏览器支持情况
| 功能 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| push.js通知 | ✅ 完全支持 | ✅ 完全支持 | ✅ 13+支持 | ✅ 完全支持 |
| 语音识别 | ✅ 支持 | ⚠️ 实验性支持 | ✅ 14.1+支持 | ✅ 支持 |
| 语音合成 | ✅ 完全支持 | ✅ 完全支持 | ✅ 14.5+支持 | ✅ 完全支持 |
降级处理策略
当浏览器不支持语音识别时,提供备用交互方式:
// 兼容性检测与降级处理
function initSpeechFallback() {
if (!('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)) {
Push.create("功能提示", {
body: "您的浏览器不支持语音控制,将使用键盘快捷键替代",
icon: "images/info-icon.png",
onClick: () => openShortcutHelp()
});
// 注册键盘快捷键
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'n') {
// Ctrl+N 创建新通知
createQuickNotification();
} else if (e.ctrlKey && e.key === 'c') {
// Ctrl+C 清除通知
Push.clear();
}
});
}
}
性能优化与安全考量
识别效率优化
- 实现指令关键词过滤,减少不必要的识别处理:
// 关键词预过滤机制
this.recognition.onresult = (event) => {
const transcript = event.results[0][0].transcript.toLowerCase();
// 检查是否包含指令关键词
const hasCommandKeyword = ['通知', '显示', '关闭', '清除', '阅读'].some(word =>
transcript.includes(word)
);
if (hasCommandKeyword) {
this._processTranscript(transcript);
}
};
- 使用本地语音模型减少网络延迟(实验性):
// 加载本地语音模型(需TensorFlow.js支持)
async function loadLocalSpeechModel() {
const model = await tf.loadLayersModel('models/speech-command/model.json');
// 模型初始化逻辑...
}
安全与隐私保护
- 实现语音活动检测,避免持续录音:
// 语音活动检测
this.recognition.onend = () => {
if (this.isActive) {
// 无活动时延迟重启,减少录音时间
setTimeout(() => this.recognition.start(), 500);
}
};
- 提供明确的录音状态指示:
// 录音状态UI指示
function updateRecordingIndicator(isRecording) {
const indicator = document.getElementById('recording-indicator');
indicator.style.display = 'block';
indicator.style.backgroundColor = isRecording ? '#ff4444' : '#33b5e5';
indicator.title = isRecording ? '正在聆听...' : '已暂停';
}
总结与扩展方向
通过push.js与Web Speech API的结合,我们成功打破了传统通知系统的交互限制。这种无接触交互模式特别适合以下场景:医疗环境中的无菌操作、厨房/实验室等双手忙碌的场景、以及行动不便人士的辅助工具。
未来扩展方向包括:
- 多语言指令支持(通过src/push/Messages.js的国际化框架)
- 个性化语音模型训练
- 与智能家居系统联动控制
完整代码示例可在项目的examples/speech-control/目录中找到,包含购物清单、会议提醒和媒体控制三个完整场景的实现。
附录:API速查表
| 方法 | 描述 | 参数 |
|---|---|---|
| Push.create(title, options) | 创建新通知 | title:字符串, options:对象 |
| Push.clear() | 清除所有通知 | 无 |
| SpeechCommandRecognizer.start() | 启动语音识别 | 无 |
| SpeechCommandRecognizer.addCommand(pattern, handler) | 添加自定义指令 | pattern:正则表达式, handler:函数 |
| speechSynthesis.speak(utterance) | 语音合成 | utterance:SpeechSynthesisUtterance对象 |
更多API细节请参考项目README.md和官方文档。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



