写点什么

用 80 行 JavaScript 代码构建自己的语音助手

  • 2020-07-17
  • 本文字数:3429 字

    阅读完需:约 11 分钟

用 80 行 JavaScript 代码构建自己的语音助手

在本教程中,我们将使用 80 行 JavaScript 代码在浏览器中构建一个虚拟助理(如 Siri 或 Google 助理)。你可以在这里测试这款应用程序,它将会听取用户的语音命令,然后用合成语音进行回复。

你所需要的是:


由于 Web Speech API 仍处于试验阶段,该应用程序只能在受支持的浏览器上运行:Chrome(版本 25 以上)和 Edge(版本 79 以上)。

我们需要构建哪些组件?

要构建这个 Web 应用程序,我们需要实现四个组件:


  1. 一个简单的用户界面,用来显示用户所说的内容和助理的回复。

  2. 将语音转换为文本。

  3. 处理文本并执行操作。

  4. 将文本转换为语音。

用户界面

第一步就是创建一个简单的用户界面,它包含一个按钮用来触发助理,一个用于显示用户命令和助理响应的 div、一个用于显示处理信息的 p 组件。


const startBtn = document.createElement("button");startBtn.innerHTML = "Start listening";const result = document.createElement("div");const processing = document.createElement("p");document.write("<body><h1>My Siri</h1><p>Give it a try with 'hello', 'how are you', 'what's your name', 'what time is it', 'stop', ... </p></body>");document.body.append(startBtn);document.body.append(result);document.body.append(processing);
复制代码

语音转文本

我们需要构建一个组件来捕获语音命令并将其转换为文本,以进行进一步处理。在本教程中,我们使用 Web Speech APISpeechRecognition。由于这个 API 只能在受支持的浏览器中使用,我们将显示警告信息并阻止用户在不受支持的浏览器中看到 Start 按钮。


const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;if (typeof SpeechRecognition === "undefined") {  startBtn.remove();  result.innerHTML = "<b>Browser does not support Speech API. Please download latest chrome.<b>";}
复制代码


我们需要创建一个 SpeechRecognition 的实例,可以设置一组各种属性来定制语音识别。在这个应用程序中,我们将 continuousinterimResults 设置为 true,以便实时显示语音文本。


const recognition = new SpeechRecognition();recognition.continuous = true;recognition.interimResults = true;
复制代码


我们添加一个句柄来处理来自语音 API 的 onresult 事件。在这个处理程序中,我们以文本形式显示用户的语音命令,并调用函数 process 来执行操作。这个 process 函数将在下一步实现。


function process(speech_text) {    return "....";}recognition.onresult = event => {   const last = event.results.length - 1;   const res = event.results[last];   const text = res[0].transcript;   if (res.isFinal) {      processing.innerHTML = "processing ....";      const response = process(text);      const p = document.createElement("p");      p.innerHTML = `You said: ${text} </br>Siri said: ${response}`;      processing.innerHTML = "";      result.appendChild(p);      // add text to speech later   } else {      processing.innerHTML = `listening: ${text}`;   }}
复制代码


我们还需要将 用户界面的 buttonrecognition 对象链接起来,以启动/停止语音识别。


let listening = false;toggleBtn = () => {   if (listening) {      recognition.stop();      startBtn.textContent = "Start listening";   } else {      recognition.start();      startBtn.textContent = "Stop listening";   }   listening = !listening;};startBtn.addEventListener("click", toggleBtn);
复制代码

处理文本并执行操作

在这一步中,我们将构建一个简单的会话逻辑并处理一些基本操作。助理可以回复“hello”、“what's your name?”、“how are you?”、提供当前时间的信息、“stop”听取或打开一个新的标签页来搜索它不能回答的问题。你可以通过使用一些 AI 库进一步扩展这个 process 函数,使助理更加智能。


function process(rawText) {   // remove space and lowercase text   let text = rawText.replace(/\s/g, "");   text = text.toLowerCase();   let response = null;   switch(text) {      case "hello":         response = "hi, how are you doing?"; break;      case "what'syourname":         response = "My name's Siri.";  break;      case "howareyou":         response = "I'm good."; break;      case "whattimeisit":         response = new Date().toLocaleTimeString(); break;      case "stop":         response = "Bye!!";         toggleBtn(); // stop listening   }   if (!response) {      window.open(`http://google.com/search?q=${rawText.replace("search", "")}`, "_blank");      return "I found some information for " + rawText;   }   return response;}
复制代码

文本转语音

在最后一步中,我们使用 Web Speech API 的 speechSynthesis 控制器为我们的助理提供语音。这个 API 简单明了。


speechSynthesis.speak(new SpeechSynthesisUtterance(response));
复制代码


就是这样!我们只用了 80 行代码就有了一个很酷的助理。程序的演示可以在这里找到。


// UI compconst startBtn = document.createElement("button");startBtn.innerHTML = "Start listening";const result = document.createElement("div");const processing = document.createElement("p");document.write("<body><h1>My Siri</h1><p>Give it a try with 'hello', 'how are you', 'what's your name', 'what time is it', 'stop', ... </p></body>");document.body.append(startBtn);document.body.append(result);document.body.append(processing);// speech to textconst SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;let toggleBtn = null;if (typeof SpeechRecognition === "undefined") {  startBtn.remove();  result.innerHTML = "<b>Browser does not support Speech API. Please download latest chrome.<b>";} else {  const recognition = new SpeechRecognition();  recognition.continuous = true;  recognition.interimResults = true;  recognition.onresult = event => {    const last = event.results.length - 1;    const res = event.results[last];    const text = res[0].transcript;    if (res.isFinal) {      processing.innerHTML = "processing ....";      const response = process(text);      const p = document.createElement("p");      p.innerHTML = `You said: ${text} </br>Siri said: ${response}`;      processing.innerHTML = "";      result.appendChild(p);      // text to speech      speechSynthesis.speak(new SpeechSynthesisUtterance(response));    } else {      processing.innerHTML = `listening: ${text}`;    }  }  let listening = false;  toggleBtn = () => {    if (listening) {      recognition.stop();      startBtn.textContent = "Start listening";    } else {      recognition.start();      startBtn.textContent = "Stop listening";    }    listening = !listening;  };  startBtn.addEventListener("click", toggleBtn);}// processorfunction process(rawText) {  let text = rawText.replace(/\s/g, "");  text = text.toLowerCase();  let response = null;  switch(text) {    case "hello":      response = "hi, how are you doing?"; break;    case "what'syourname":      response = "My name's Siri.";  break;    case "howareyou":      response = "I'm good."; break;    case "whattimeisit":      response = new Date().toLocaleTimeString(); break;    case "stop":      response = "Bye!!";      toggleBtn();  }  if (!response) {    window.open(`http://google.com/search?q=${rawText.replace("search", "")}`, "_blank");    return `I found some information for ${rawText}`;  }  return response;}×Drag and DropThe image will be downloaded
复制代码


作者介绍:


Tuan Nhu Dinh,Facebook 软件工程师。


原文链接:


https://medium.com/swlh/build-your-own-hi-siri-with-80-lines-of-javascript-code-653540c77502


2020-07-17 11:363920

评论 1 条评论

发布
用户头像
然而谷歌接口要翻墙
2020-07-28 13:16
回复
没有更多了
发现更多内容

阿里云机器学习PAI全新推出特征平台 (Feature Store),助力AI建模场景特征数据高效利用

阿里云大数据AI技术

再升级!PP-OCRv4多场景平均精度提升5%!

飞桨PaddlePaddle

人工智能 paddle OCR 百度飞桨

【干货】华为云图数据库GES技术演进

华为云开发者联盟

人工智能 华为云 图数据库 华为云开发者联盟 企业号 8 月 PK 榜

【实践篇】DDD脚手架及编码规范 | 京东云技术团队

京东科技开发者

DDD 软件架构 脚手架 企业号 8 月 PK 榜 DDD脚手架

设计模式-适配器模式

java易二三

Java 程序员 计算机

Jvm专讲之内存结构

java易二三

Java 编程 程序员 JVM 计算机

对线面试官 - MQ经典面试题之高可用性及幂等性

派大星

MQ Java 面试题

苹果Mac版防火墙推荐Radio Silence 激活下载+安装教程

胖墩儿不胖y

Mac软件 防火墙工具

Elasticsearch Mapping类型修改 | 京东云技术团队

京东科技开发者

数据库 elasticsearch 企业号 8 月 PK 榜 Mapping

度加剪辑App的MMKV应用优化实践

百度Geek说

性能优化 移动开发 企业号 8 月 PK 榜 IO优化

制造执行系统(MES)在家具行业中的应用

万界星空科技

开源 MES系统 智能家居

AI教学赋能计划(大模型特辑)2023秋季学期启动申请!

飞桨PaddlePaddle

人工智能 百度飞桨 高校 复合型人才 产教融合

为什么那么多人喜欢用云桌面

青椒云云电脑

桌面云 云桌面

快手Java一面11问(附参考答案)

JavaGuide

Java spring 面试 springboot Java web

SpringBoot中如何对数据访问层进行单元测试?

java易二三

Java 数据库 编程 程序员 计算机

写得了代码,焊得了板!嵌入式开发工程师必修之代码管理方案(中)

极狐GitLab

git gitlab conan Git-Repo 多仓管理

uniapp中解析markdown支持网页和小程序

南城FE

JavaScript 小程序 前端 markdown

中国图数据库,领导者!

华为云开发者联盟

人工智能 华为云 科技 华为云开发者联盟 企业号 8 月 PK 榜

微短剧赛道风口下的一站式点播解决方案

阿里云CloudImagine

云计算 视频云 微短剧

开发一款同城线下陪玩约玩APP大家怎么看?线下陪玩APP的应用场景

山东布谷科技胡月

语音聊天源码 线下约玩APP开发 线下陪玩平台 社交约玩平台开发 约玩交友APP源码

K8S集群中使用JDOS KMS服务对敏感数据安全加密 | 京东云技术团队

京东科技开发者

数据安全 数据加密 k8s集群 企业号 8 月 PK 榜 KMS

月活近千万,连续365天无故障:货拉拉怎么做稳定性指标度量?

TakinTalks稳定性社区

用 80 行 JavaScript 代码构建自己的语音助手_语言 & 开发_Tuan Nhu Dinh_InfoQ精选文章