【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

用 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


公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2020-07-17 11:363311

评论 1 条评论

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

分布式存储中间件(1):10000字把Redis扒个干净,一发入魂

北游学Java

Java 数据库 redis 分布式

一种自适应混合域音频无声水印

行者AI

音频

20年研发安全积累,5大研发安全能力让软件“天生安全”

华为云开发者联盟

DevOps 安全 DevSecOps 华为云 devcloud

老爷子这代码,看跪了!

why技术

Java

机器学习训练营第一次作业

学习

8K视频指的什么?8K视频处理和工作原理分析

科技猫

技术 分辨率 视频 视频处理 8k

使用开源项目必须保留作者姓名?开源软件不能商用?我们需要先学会分辨开源许可证

郭旭东

开源 开源文化

软件 IT 专业的高校大学生创新创业问卷调查

五分钟学大数据

问卷调查

FusionInsight MRS:你的大数据“管家”

华为云开发者联盟

大数据 数据湖 云原生 华为云 FusionInsight MRS

如何用iMazing备份恢复贪婪洞窟

懒得勤快

聚力区块链 共建数字中国丨“桂链”平台正式发布并启动全面接入“星火·链网”

浪潮云

云计算

传统行业为什么需要互联网人才

陈俊

智慧公安情指勤指挥调度平台搭建,指挥中心平台搭建

新疆重点人员管控系统搭建,指挥调度系统开发

BOE(京东方)成都数字医院开诊,投资60亿打造西南智慧医疗创新典范

爱极客侠

德赛西威与华为签署全场景智慧出行生态解决方案合作协议

curl使用

Hex

工具

百度商业大规模微服务分布式监控系统——凤睛

百度Geek说

数据库 分布式 微服务 大前端 监控

北京天源迪科亮相2021年企业数字化转型峰会暨山东CIO智库年会

DT极客

BOE(京东方)亮相数字中国 “三驾马车”加速物联网战略转型

爱极客侠

Java中&、|、&&、||详解

Sakura

4月日更

低功耗深度休眠后无法唤醒、烧录程序,怎么办?(华大半导体HC32L136)

不脱发的程序猿

嵌入式软件 单片机 4月日更 华大半导体 HC32L136

全球案例 | Dropbox: 在 COVID-19 时代通过 Atlassian 为远程工作提供动力

Atlassian

敏捷 Atlassian Jira 远程工作 Dropbox

【论文分享】Presto: SQL on Everything(二)

小舰

4月日更

commons-pool2 池化技术探究

vivo互联网技术

Java common-pool2 池化技术

Linux内核源码分析:基于最新的Linux 4.0内核(学习路线总结)

Linux服务器开发

后端 Linux内核 内核源码 内核4.0 底层原理

Leveldb解读之二:Read

Jowin

leveldb

如何快速准备高质量的AI数据?

华为云开发者联盟

AI 数据 华为云 modelarts 数据标注

全球案例 | Dropbox: 在 COVID-19 时代通过 Atlassian 为远程工作提供动力

Atlassian

DevOps 敏捷 远程办公 Atlassian Jira

又有400多个组件支持鸿蒙了!

Geek_283163

华为 鸿蒙

干货拉满!阿里公开内部P9级架构师(Java)成长路线图,满满的干货

Java架构追梦

Java 阿里巴巴 架构 面试 成长路线

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