浏览器内置文字转语音,播报功能Web Speech API - SpeechSynthesisUtterance

SpeechSynthesisUtterance: 让网页说话的艺术

在现代Web开发中,让网页具有语音功能可以极大提升用户体验,特别是对于视障用户或需要多任务处理的场景。SpeechSynthesisUtterance 是 Web Speech API 中的一个接口,它允许开发者创建一个语音合成对象,该对象可以用来控制语音输出的内容、语言、速度等属性。

什么是 SpeechSynthesisUtterance?

SpeechSynthesisUtterance 对象代表了一段将要通过浏览器的语音合成服务朗读出来的文本。每个 SpeechSynthesisUtterance 实例都可以设置不同的属性,如文本内容、声音类型、音量、语速等,以满足不同场景下的需求。

使用方法

首先,你需要检查用户的浏览器是否支持 speechSynthesis 接口。大多数现代浏览器(如 Chrome, Firefox, Edge, Safari)都支持此功能。

if ('speechSynthesis' in window) {
  console.log('Your browser supports speech synthesis!');
} else {
  console.log('Sorry, your browser does not support speech synthesis.');
}

接下来,你可以创建一个新的 SpeechSynthesisUtterance 对象,并设置其属性:

const utterance = new SpeechSynthesisUtterance();
utterance.text = 'Hello, world!';
utterance.lang = 'en-US'; // 设置语言为美式英语
utterance.rate = 1; // 设置语速,1为正常速度
utterance.pitch = 1; // 设置音调,1为正常音调
utterance.volume = 1; // 设置音量,1为最大音量

// 发出语音
window.speechSynthesis.speak(utterance);
使用语音包

虽然 SpeechSynthesisUtterance 提供了一些基本的属性来调整语音效果,但有时候我们可能希望使用特定的声音来增强用户体验。这可以通过选择不同的 Voice 对象实现。

function getVoices() {
  return new Promise((resolve) => {
    const voices = speechSynthesis.getVoices();
    if (voices.length !== 0) {
      resolve(voices);
    } else {
      speechSynthesis.onvoiceschanged = () => {
        resolve(speechSynthesis.getVoices());
      };
    }
  });
}

getVoices().then(voices => {
  // 选择第一个可用的语音
  const voice = voices[0];
  // 或者选择特定的语音
  const specificVoice = voices.find(v => v.name === 'Google UK English Female');
  
  utterance.voice = specificVoice;
  window.speechSynthesis.speak(utterance);
});
完整的 HTML Demo

下面是一个简单的 HTML 页面示例,展示了如何使用 SpeechSynthesisUtterance 创建一个可交互的语音合成应用。

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>语音合成示例 - 中文</title>
<style>
  label { display: block; margin-top: 10px; }
  textarea { width: 100%; height: 100px; }
</style>
</head>
<body>
<h1>语音合成示例 - 中文</h1>
<label for="textToSpeak">请输入要朗读的文本:</label>
<textarea id="textToSpeak" placeholder="请输入要朗读的文本..."></textarea>
<br>
<label for="voiceSelect">选择语音:</label>
<select id="voiceSelect">
  <option value="">请选择一个语音</option>
</select>
<br>
<label for="volumeSlider">调整音量:</label>
<input type="range" id="volumeSlider" min="0" max="1" step="0.1" value="1">
<br>
<button onclick="speak()">朗读</button>

<script>
document.addEventListener('DOMContentLoaded', () => {
  // 初始化语音选择下拉框
  getVoices().then(voices => {
    const select = document.getElementById('voiceSelect');
    voices.forEach(voice => {
      if (voice.lang === 'zh-CN') {
        const option = document.createElement('option');
        option.value = voice.name;
        option.textContent = `${voice.name} (${voice.lang})`;
        select.appendChild(option);
      }
    });
  });
});

function speak() {
  if ('speechSynthesis' in window) {
    const text = document.getElementById('textToSpeak').value;
    const selectedVoiceName = document.getElementById('voiceSelect').value;
    const volume = parseFloat(document.getElementById('volumeSlider').value);
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.lang = 'zh-CN'; // 设置语言为中文
    utterance.volume = volume; // 设置音量

    // 获取所有可用的语音
    getVoices().then(voices => {
      // 选择用户选择的中文语音
      const selectedVoice = voices.find(v => v.name === selectedVoiceName);
      if (selectedVoice) {
        utterance.voice = selectedVoice;
      } else {
        console.warn('没有找到用户选择的语音包,使用默认语音。');
      }
      window.speechSynthesis.speak(utterance);
    });
  } else {
    alert('您的浏览器不支持语音合成。');
  }
}

function getVoices() {
  return new Promise((resolve) => {
    const voices = speechSynthesis.getVoices();
    if (voices.length !== 0) {
      resolve(voices);
    } else {
      speechSynthesis.onvoiceschanged = () => {
        resolve(speechSynthesis.getVoices());
      };
    }
  });
}
</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/893149.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

穷举vs暴搜vs深搜vs回溯vs剪枝(一)

文章目录 全排列子集找出所有子集的异或总和再求和全排列 II电话号码的字母组合 全排列 题目&#xff1a;全排列 思路 通过深度优先搜索的方式&#xff0c;不断枚举每个数在当前位置的可能性&#xff0c;然后回溯到上一个状态&#xff0c;直到枚举完所有可能性得到正确的结果 r…

SDK5(note上)

以下代码实现菜单窗口和快捷键的ctrlo打开的操作 #include <windows.h> #include<tchar.h> #include <stdio.h> #include <strsafe.h> #include <string> #define IDM_OPEN 102 /*鼠标消息 * 键盘消息 * Onkeydown * Onkeyup * //键盘扫描码 * …

力扣hot100--二叉树

目录 二叉树 1. 94. 二叉树的中序遍历 2. 98. 验证二叉搜索树 3. 101. 对称二叉树 4.102. 二叉树的层序遍历 5. 104. 二叉树的最大深度 6. 105. 从前序与中序遍历序列构造二叉树 7. 114. 二叉树展开为链表 8. 226. 翻转二叉树 9. 236. 二叉树的最近公共祖先 二叉树 …

操作符详解(C 语言)

目录 一、操作符的分类二、算数操作符1. 除法操作符2. 取余操作符 三、位移操作符1. 进制2. 原码、反码和补码3. 左移操作符&#xff08;<<&#xff09;和右移操作符&#xff08;>>&#xff09; 四、位操作符1. 按位与 &2. 按位或 |3. 按位异或 ^4. 按位取反 ~…

大衍数列——考研408考试科目之数据算法——未来之窗学习通

一、大衍数列 中国古代文献中&#xff0c;曾记载过“大衍数列”, 主要用于解释中国传统文化中的太极衍生原理。 它的前几项是&#xff1a;0、2、4、8、12、18、24、32、40、50 … 其规律是&#xff1a;对偶数项&#xff0c;是序号平方再除2&#xff0c;奇数项&#xff0c;是…

有源滤波器(三)

这个连接方法很可以&#xff0c;正好解决了最近没有转接器的问题&#xff1a;

javaweb-xml映射文件编写sql语句

可以使用注解的方式&#xff0c;也可以使用xml映射的方式&#xff0c;一般简单sql语句使用注解&#xff0c;复杂的使用xml映射。

【PhpSpreadsheet】ThinkPHP5+PhpSpreadsheet实现批量导出数据

目录 前言 一、安装 二、API使用 三、完整实例 四、效果图 前言 为什么使用PhpSpreadsheet&#xff1f; 由于PHPExcel不再维护&#xff0c;所以建议使用PhpSpreadsheet来导出exlcel&#xff0c;但是PhpSpreadsheet由于是个新的类库&#xff0c;所以只支持PHP7.1及以上的版…

【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款购物类智能体的开发,来体验一下我的智能体『科技君Tom』

目录 1.1、智能体运行效果1.2、创作灵感来源智能体平台拥有个人化且人性化的大致框架&#xff0c;可以让小白也能搭建出一个智能体其次是拥有丰富的插件&#xff0c;可以更加快速的得到自己想要的效果~ 1.3、如何制作智能体常见问题与解决方案关于人设与回复逻辑插件使用模型的…

【黑马redis高级篇】持久化

//来源[01,05]分布式缓存 除了黑马&#xff0c;还参考了别的。 目录 1.单点redis问题及解决方案2.为什么需要持久化&#xff1f;3.Redis持久化有哪些方式呢&#xff1f;为什么我们需要重点学RDB和AOF&#xff1f;4.RDB4.1 定义4.2 触发方式4.2.1手动触发save4.2.2被动触发bgsa…

文件IO(Linux文件IO,目录操作函数)

前言 本文介绍Linux系统下自带的文件IO的函数。 Linux文件IO相关函数 open函数 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode)…

2024ideaUI切换和svn与git的切换

2024的UI实在很不舒服&#xff0c;隐藏了很多按键&#xff1b; 第一步&#xff1a; 视图 -》 外观 -》 工具栏选出来&#xff1b; 结果出来&#xff1a; 运行的按键和设置的按钮 第二步 点击设置的按钮&#xff0c;选择最后一个&#xff0c;重启就行 结果 舒服&#xff01; s…

双通道音频功率放大电路D2822M兼容TDA2822,全封装输出功率0.11W,用于音频产品

在某客户的便携式音频产品中&#xff0c;客户想在确保其产品的性能的前提下&#xff0c;为产品方案寻找一颗国产备份料。客户产品之前使用的是TDA2822&#xff0c;在了解客户的电路设计以及该产品的电气特性后&#xff0c;给客户寻找了一款可兼容相同电路设计使用的国产厂牌芯谷…

2010年国赛高教杯数学建模C题输油管的布置解题全过程文档及程序

2010年国赛高教杯数学建模 C题 输油管的布置 某油田计划在铁路线一侧建造两家炼油厂&#xff0c;同时在铁路线上增建一个车站&#xff0c;用来运送成品油。由于这种模式具有一定的普遍性&#xff0c;油田设计院希望建立管线建设费用最省的一般数学模型与方法。   1. 针对两炼…

Python零基础01——Python的由来,Python的特点、优缺点有哪些?

文章目录 Python的由来Python的特点Python的优缺点什么是编译器 Python的由来 1989年圣诞节期间&#xff0c;在阿姆斯特丹为打发圣诞节的无趣&#xff0c;决定开发一款新的脚本解释语言&#xff0c;作为ABC语言的一种继承&#xff0c;然后他就这么做了&#xff0c;并实现了&am…

Python中的help()函数:追踪错误并提供解决方案

引言 在Python编程中&#xff0c;help()函数是一个非常有用的内置工具&#xff0c;它能够提供关于模块、关键字、属性和方法等的详细信息。对于初学者来说&#xff0c;help()函数可以帮助他们理解代码的工作原理&#xff0c;快速查找文档&#xff0c;以及解决编程过程中遇到的…

<Linux> 线程安全

目录 文章目录 一、Linux线程互斥 1. 进程线程间的互斥相关背景概念 2. 互斥量mutex 3. 互斥量接口 初始化互斥量 动静态分配 销毁互斥量 互斥量加锁 互斥量解锁 4. 互斥量实现原理 5. 简单封装互斥量 二、可重入与线程安全 1. 概念 1.1 可重入 1.2 线程安全 2. 常见的线程不…

LLama 3.2 1B 和 3B:体型虽小,但威力强大!

MetaAI 刚刚推出了 Llama-3.2&#xff0c;这是一套新的模型&#xff0c;其中包括两个令人印象深刻的轻量级大型语言模型 (LLM)&#xff0c;分别具有 10 亿 (1B) 和 30 亿 (3B) 个参数&#xff0c;以及更大的视觉语言模型 (VLM)&#xff0c;分别具有 11B 和 90B 个参数。 取决于…

IT监控平台可视化:多维度展示助力运维效率提升

在信息化时代&#xff0c;IT设备的稳定性与业务的连续性紧密相连&#xff0c;任何细微的故障都可能给企业带来巨大的损失。因此&#xff0c;IT运维团队面临着前所未有的挑战&#xff0c;他们需要迅速、准确地识别和解决问题&#xff0c;以确保业务的平稳运行。而IT监控平台的可…

Django学习- ORM基础操作_创建数据

ORM操作&#xff1a; 管理器对象&#xff1a; 创建数据&#xff1a; Django shell 想要操作模型对象&#xff0c;首先我们需要把它引进Django shell中 >>> from bookstore.models import Book >>> b1 Book.objects.create(titleAI, pub清华大学出版社, pr…