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

news2024/11/27 2:16:35

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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初学java练习题【1】

import java.util.Scanner;public class HelloWorld{public static void main(String[] args){Scanner scannernew Scanner(System.in);//输入工资System.out.println("请输入您的工资&#xff1a;");double d1scanner.nextDouble();System.out.println("请输入…

Word 批注如何添加及删除?只需这样就行

在使用 Word 编写文档之后我们可能会将其发送给其他伙伴查看&#xff0c;当其看见文档中有错误的时候可能需要加以标记&#xff0c;这样你才能知道哪里有错误。Word 批注功能就是这样的一种工具&#xff0c;它允许用户在文档中标记特定文字或段落&#xff0c;并添加相关评论或建…

【论文阅读】Semi-Supervised Few-shot Learning via Multi-Factor Clustering

通过多因素聚类的半监督小样本学习 引用&#xff1a;Ling J, Liao L, Yang M, et al. Semi-supervised few-shot learning via multi-factor clustering[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2022: 14564-14573. 论文地址…

微软已解决Word自动删除文件问题 重启或使用命令行可修复

早前作为办公软件主力产品的 Microsoft Word 出现某个错误&#xff0c;该错误会导致用户在保存文件后或者关闭 Word 时自动删除文件&#xff0c;好在文件只是被移动到回收站中而不是永久删除。 该问题主要影响以下行为&#xff1a; 文件名中包含 # 号 文件后缀为全大写的.DOC…

应对网络安全挑战:App等保测评的重要性与策略

在全球数字化转型的大潮中&#xff0c;移动应用(App)作为连接人们日常生活与互联网世界的桥梁&#xff0c;其数量与日俱增&#xff0c;功能日趋多样化。与此同时&#xff0c;App背后潜藏的网络安全风险也随之上升&#xff0c;数据泄露、隐私侵犯、恶意软件植入等问题频发&#…

访问控制列表(课内实验)

实验2&#xff1a;访问控制列表 实验目的及要求&#xff1a; 通过实验&#xff0c;进一步的理解标准ACL与扩展ACL的工作原理及执行过程。理解通配符的概念&#xff0c;熟练掌握标准ACL与扩展ACL的配置指令&#xff0c;掌握将访问控制列表应用VTY线路上&#xff0c;并且能够判断…

C++网络编程之套接字基础

概述 在网络编程中&#xff0c;套接字&#xff08;Socket&#xff09;是一种用于进程间通信的接口。套接字是操作系统提供的一种抽象层&#xff0c;它允许不同计算机之间的进程通过网络进行通信。套接字实际上并不神秘&#xff0c;简单来说&#xff0c;套接字是连接网络中不同主…

【射频通信电子线路第七讲】射频收发信机结构及具体的实例应用

一、射频收发器 &#xff08;一&#xff09;功能与需求 &#xff08;1&#xff09;频率变换&#xff1a;调制解调、混频、不同于信息变换 电平变换&#xff1a;放大、衰减 干扰抑制&#xff1a;滤波、抵消 &#xff08;2&#xff09;发射出的信号&#xff1a;高频、一定功…

【动态规划】状态 dp

动态规划步骤&#xff1a; 状态表示。所谓状态表示就是 dp 表里的值表示什么含义&#xff0c;那么状态表示怎么找呢&#xff1f; a. 题目要求 b. 经验&#xff08;以某一个位置为结尾 / 起点&#xff09; 题目要求 c. 分析问题的过程中发现重复子问题状态转移方程。dp[ i ] 等…

<Project-8.1 pdf2tx-MM> Python Flask 用浏览器翻译PDF内容 2个翻译引擎 繁简中文结果 从P8更改

更新 Project Name&#xff1a;pdf2tx (P6) Date: 5oct.24 Function: 在浏览器中翻译PDF文件 Code:https://blog.csdn.net/davenian/article/details/142723144 升级 Project Name: pdf2tx-mm (P8) 7oct.24 加入多线程&#xff0c;分页OCR识别&#xff0c;提高性能与速度 使…

美发店管理革新:SpringBoot系统的应用

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理美发门店管理系统的相关信息成为必然。开发…

3D生成基础模型来了!只需5秒,高质量3D资产规模化生成!南洋理工等重磅开源3DTopia-XL

文章链接&#xff1a;https://arxiv.org/pdf/2409.12957 项目链接&#xff1a;https://3dtopia.github.io/3DTopia-XL/ 今天AI生成未来和大家分享的是南洋理工、北大、上海AI Lab和港中文联合发布的3D PBR资产生成最新工作3DTopia-XL。通过基于高效且表达力强的3D表示方法Pri…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor &#xff08;官方链接 https://microsoft.github.io/monaco-editor/&#xff09;是一个由微软开发的功能强大的在线代码编辑器&#xff0c;被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

【linux 多进程并发】0201 Linux进程fork内存空间,父子进程变量内存地址居然是一样的

0201 Linux进程fork方式详解 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章…

学习记录:js算法(五十七):二叉树中所有距离为 K 的结点

文章目录 二叉树中所有距离为 K 的结点思路一思路二 二叉树中所有距离为 K 的结点 给定一个二叉树&#xff08;具有根结点 root&#xff09;&#xff0c; 一个目标结点 target &#xff0c;和一个整数值 k &#xff0c;返回到目标结点 target 距离为 k 的所有结点的值的数组。&…

matlab002

新建工程test001 例如&#xff1a; 脚本&#xff08;Script&#xff09; 概念 脚本是一系列按顺序执行的 MATLAB 命令的集合。它就像是一个记录了你在命令行中输入的一系列指令的文件。用途 适用于简单的任务&#xff0c;例如数据处理、可视化等一次性的操作。例如&#xff0c…

重学SpringBoot3-集成Redis(四)之Redisson

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;四&#xff09;之Redisson 1. 添加 Redisson 依赖2. 配置 Redisson 客户端3. 使用 Redisson 实现分布式锁4. 调用分布式锁5. 为什…

Java 获取热搜并生成图片

效果图如下&#xff1a; 第一步获取热搜 public List<String> getHotNews4(Integer size) {if (size < 0 || StringUtils.isEmpty(size)) {return null;}try {//set 转listreturn new ArrayList<>(getHotNews(size));} catch (Exception e) {logger.error(&qu…

如何基于审批实现文件外发管控,阻断数据违规外流?

FTP可以说是实际中企业运用最广泛的文件传输方式&#xff0c;很多企业不仅内部传输文件使用FTP&#xff0c;在与外部合作伙伴协作时&#xff0c;也多采用FTP进行文件的外发和收取。例如半导体行业&#xff0c;默认的都是使用FTP进行文件外发&#xff0c;这时候&#xff0c;替换…

卷积神经网络细节问题及知识点

一、Batch Normalization Batch Normalization&#xff08;BN&#xff0c;批归一化&#xff09; 是深度学习中的一种技术&#xff0c;主要用于加速神经网络的训练过程&#xff0c;同时提高网络的稳定性和收敛速度。它通过对每一层的输出进行归一化&#xff0c;减少梯度消失和梯…