xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

web 语音播报 & 网页阅读器

web 语音播报 & 网页阅读器

Chrome

auto speech & voice speaking

http://3.141592653589793238462643383279502884197169399375105820974944592.com/index314159.html

demos

屏幕阅读器 / web 无障碍

http://www.shanghai.gov.cn/nw2/nw2314/nw2315/nw43978/u21aw1432462.html

https://www.pudong.gov.cn/shpd/

https://www.youlai.cn/video/article/294538.html


web speech api

https://mdn.github.io/web-speech-api/speak-easy-synthesis/


const autoReaderTTS = () => {
    const text = document.getElementById('ttsText').value;
    const msg = new SpeechSynthesisUtterance(text);
    msg.volume = 100;
    msg.rate = 1;
    msg.pitch = 1.5;
    console.log(`voice msg`, msg);
    window.speechSynthesis.speak(msg);
};



<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="author" content="xgqfrms">
  <meta name="generator" content="VS code">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width">
  <title>speech synthesiser / speech synthesizer/ 网络语音API和语音合成器</title>
  <link rel="stylesheet" href="./style.css">
  <!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
</head>

<body data-gr-c-s-loaded="true">
  <h1>speech synthesiser / speech synthesizer/ 网络语音API和语音合成器</h1>
  <p>Enter some text in the input below and press return or the "play" button to hear it. change voices using the
    dropdown menu.</p>
  <form>
    <input type="text" class="txt" value="hello world 你好👋">
    <div>
      <label for="rate">Rate</label><input type="range" min="0.5" max="2" value="1" step="0.1" id="rate">
      <div class="rate-value">1</div>
      <div class="clearfix"></div>
    </div>
    <div>
      <label for="pitch">Pitch</label><input type="range" min="0" max="2" value="1" step="0.1" id="pitch">
      <div class="pitch-value">1</div>
      <div class="clearfix"></div>
    </div>
    <select>
      <option data-lang="zh-CN" data-name="Google&nbsp;普通话(中国大陆)" selected>Google&nbsp;普通话(中国大陆)(zh-CN) -- DEFAULT</option>
      <option data-lang="en-US" data-name="Alex">Alex (en-US)</option>
      <option data-lang="it-IT" data-name="Alice">Alice (it-IT)</option>
      <option data-lang="sv-SE" data-name="Alva">Alva (sv-SE)</option>
      <option data-lang="fr-CA" data-name="Amelie">Amelie (fr-CA)</option>
      <option data-lang="de-DE" data-name="Anna">Anna (de-DE)</option>
      <option data-lang="he-IL" data-name="Carmit">Carmit (he-IL)</option>
      <option data-lang="id-ID" data-name="Damayanti">Damayanti (id-ID)</option>
      <option data-lang="en-GB" data-name="Daniel">Daniel (en-GB)</option>
      <option data-lang="es-AR" data-name="Diego">Diego (es-AR)</option>
      <option data-lang="nl-BE" data-name="Ellen">Ellen (nl-BE)</option>
      <option data-lang="en" data-name="Fiona">Fiona (en)</option>
      <option data-lang="en-US" data-name="Fred">Fred (en-US)</option>
      <option data-lang="id-ID" data-name="Google Bahasa Indonesia">Google Bahasa Indonesia (id-ID)</option>
      <option data-lang="de-DE" data-name="Google Deutsch">Google Deutsch (de-DE)</option>
      <option data-lang="es-ES" data-name="Google español">Google español (es-ES)</option>
      <option data-lang="es-US" data-name="Google español de Estados Unidos">Google español de Estados Unidos (es-US)
      </option>
      <option data-lang="fr-FR" data-name="Google français">Google français (fr-FR)</option>
      <option data-lang="it-IT" data-name="Google italiano">Google italiano (it-IT)</option>
      <option data-lang="nl-NL" data-name="Google Nederlands">Google Nederlands (nl-NL)</option>
      <option data-lang="pl-PL" data-name="Google polski">Google polski (pl-PL)</option>
      <option data-lang="pt-BR" data-name="Google português do Brasil">Google português do Brasil (pt-BR)</option>
      <option data-lang="en-GB" data-name="Google UK English Female">Google UK English Female (en-GB)</option>
      <option data-lang="en-GB" data-name="Google UK English Male">Google UK English Male (en-GB)</option>
      <option data-lang="en-US" data-name="Google US English">Google US English (en-US)</option>
      <option data-lang="ru-RU" data-name="Google русский">Google русский (ru-RU)</option>
      <option data-lang="hi-IN" data-name="Google हिन्दी">Google हिन्दी (hi-IN)</option>
      <option data-lang="zh-TW" data-name="Google 國語(臺灣)">Google 國語(臺灣) (zh-TW)</option>
      <option data-lang="ja-JP" data-name="Google 日本語">Google 日本語 (ja-JP)</option>
      <option data-lang="ko-KR" data-name="Google 한국의">Google 한국의 (ko-KR)</option>
      <option data-lang="zh-CN" data-name="Google&nbsp;普通话(中国大陆)">Google&nbsp;普通话(中国大陆) (zh-CN)</option>
      <option data-lang="zh-HK" data-name="Google&nbsp;粤語(香港)">Google&nbsp;粤語(香港) (zh-HK)</option>
      <option data-lang="ro-RO" data-name="Ioana">Ioana (ro-RO)</option>
      <option data-lang="pt-PT" data-name="Joana">Joana (pt-PT)</option>
      <option data-lang="es-ES" data-name="Jorge">Jorge (es-ES)</option>
      <option data-lang="es-MX" data-name="Juan">Juan (es-MX)</option>
      <option data-lang="th-TH" data-name="Kanya">Kanya (th-TH)</option>
      <option data-lang="en-AU" data-name="Karen">Karen (en-AU)</option>
      <option data-lang="ja-JP" data-name="Kyoko">Kyoko (ja-JP)</option>
      <option data-lang="sk-SK" data-name="Laura">Laura (sk-SK)</option>
      <option data-lang="hi-IN" data-name="Lekha">Lekha (hi-IN)</option>
      <option data-lang="it-IT" data-name="Luca">Luca (it-IT)</option>
      <option data-lang="pt-BR" data-name="Luciana">Luciana (pt-BR)</option>
      <option data-lang="ar-SA" data-name="Maged">Maged (ar-SA)</option>
      <option data-lang="hu-HU" data-name="Mariska">Mariska (hu-HU)</option>
      <option data-lang="zh-TW" data-name="Mei-Jia">Mei-Jia (zh-TW)</option>
      <option data-lang="el-GR" data-name="Melina">Melina (el-GR)</option>
      <option data-lang="ru-RU" data-name="Milena">Milena (ru-RU)</option>
      <option data-lang="en-IE" data-name="Moira">Moira (en-IE)</option>
      <option data-lang="es-ES" data-name="Monica">Monica (es-ES)</option>
      <option data-lang="nb-NO" data-name="Nora">Nora (nb-NO)</option>
      <option data-lang="es-MX" data-name="Paulina">Paulina (es-MX)</option>
      <option data-lang="en-US" data-name="Samantha">Samantha (en-US)</option>
      <option data-lang="da-DK" data-name="Sara">Sara (da-DK)</option>
      <option data-lang="fi-FI" data-name="Satu">Satu (fi-FI)</option>
      <option data-lang="zh-HK" data-name="Sin-ji">Sin-ji (zh-HK)</option>
      <option data-lang="en-ZA" data-name="Tessa">Tessa (en-ZA)</option>
      <option data-lang="fr-FR" data-name="Thomas">Thomas (fr-FR)</option>
      <option data-lang="zh-CN" data-name="Ting-Ting">Ting-Ting (zh-CN)</option>
      <option data-lang="en-IN" data-name="Veena">Veena (en-IN)</option>
      <option data-lang="en-US" data-name="Victoria">Victoria (en-US)</option>
      <option data-lang="nl-NL" data-name="Xander">Xander (nl-NL)</option>
      <option data-lang="tr-TR" data-name="Yelda">Yelda (tr-TR)</option>
      <option data-lang="ko-KR" data-name="Yuna">Yuna (ko-KR)</option>
      <option data-lang="ru-RU" data-name="Yuri">Yuri (ru-RU)</option>
      <option data-lang="pl-PL" data-name="Zosia">Zosia (pl-PL)</option>
      <option data-lang="cs-CZ" data-name="Zuzana">Zuzana (cs-CZ)</option>
    </select>
    <div class="controls">
      <button id="play" type="submit">Play</button>
    </div>
  </form>
  <script src="./script.js"></script>
  <footer>
      <p>copyright&copy; xgqfrms 2020</p>
  </footer>
</body>
</html>


"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-03-26
 * @modified
 *
 * @description
 * @augments
 * @example
 * @link
 *
 */

const log = console.log;

const synth = window.speechSynthesis;

const inputForm = document.querySelector('form');
const inputTxt = document.querySelector('.txt');
const voiceSelect = document.querySelector('select');

const pitch = document.querySelector('#pitch');
const pitchValue = document.querySelector('.pitch-value');
const rate = document.querySelector('#rate');
const rateValue = document.querySelector('.rate-value');

let voices = [];

function populateVoiceList() {
  voices = synth.getVoices()
      .sort(function (a, b) {
      const aname = a.name.toUpperCase();
      const bname = b.name.toUpperCase();
      if ( aname < bname ) {
        return -1;
      } else if ( aname == bname ) {
        return 0;
      } else {
        return +1;
      }
  });
  const selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
  voiceSelect.innerHTML = '';
  for(let i = 0; i < voices.length ; i++) {
    const option = document.createElement('option');
    option.textContent = voices[i].name + ' (' + voices[i].lang + ')';

    if(voices[i].default) {
      option.textContent += ' -- DEFAULT';
    }

    option.setAttribute('data-lang', voices[i].lang);
    option.setAttribute('data-name', voices[i].name);
    voiceSelect.appendChild(option);
  }
  voiceSelect.selectedIndex = selectedIndex;
}

populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
  speechSynthesis.onvoiceschanged = populateVoiceList;
}

function speak(){
    if (synth.speaking) {
        console.error('speechSynthesis.speaking');
        return;
    }
    if (inputTxt.value !== '') {
    const utterThis = new SpeechSynthesisUtterance(inputTxt.value);
    utterThis.onend = function (event) {
        console.log('SpeechSynthesisUtterance.onend');
    }
    utterThis.onerror = function (event) {
        console.error('SpeechSynthesisUtterance.onerror');
    }
    const selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
    for(let i = 0; i < voices.length ; i++) {
      if(voices[i].name === selectedOption) {
        utterThis.voice = voices[i];
        break;
      }
    }
    utterThis.pitch = pitch.value;
    utterThis.rate = rate.value;
    synth.speak(utterThis);
  }
}

inputForm.onsubmit = function(event) {
  event.preventDefault();

  speak();

  inputTxt.blur();
}

pitch.onchange = function() {
  pitchValue.textContent = pitch.value;
}

rate.onchange = function() {
  rateValue.textContent = rate.value;
}

voiceSelect.onchange = function(){
  speak();
}



posted @   xgqfrms  阅读(1928)  评论(6编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2019-03-26 Fetch delete API & HTTP Methods All In One
2016-03-26 Windows 10 系统下的 shutdown 命令大全 All In One
2016-03-26 How to reset your password in Ubuntu x64!
2016-03-26 从GitHub Jobs! 看技术发展趋势! 程序员进阶必备!
点击右上角即可分享
微信分享提示