javascript - 如何在 chromium 浏览器中创建文本或将文本转换为音频?

标签 javascript audio text-to-speech chromium webspeech-api

在尝试确定 How to use Web Speech API at chromium? 的解决方案时发现

var voices = window.speechSynthesis.getVoices();

voices 标识符返回一个空数组。

不确定 Chromium 浏览器缺乏支持是否与此问题有关 Not OK, Google: Chromium voice extension pulled after spying concerns

问题:

1) 是否有任何解决方法可以实现在 chromium 浏览器中从文本创建或转换音频的要求?

2) 作为开发者社区,我们如何创建一个开源的音频文件数据库来反射(reflect)常见和不常见的单词;与适当的 CORS header 一起提供?

最佳答案

已经找到了几种可能的解决方法,它们提供了从文本创建音频的能力;其中两个需要请求外部资源,另一个使用 meSpeak.js通过@masswerk。

使用 Download the Audio Pronunciation of Words from Google 中描述的方法,如果没有 writing a shell script,则无法预先确定哪些词作为文件实际存在于资源中或执行 HEAD 请求以检查是否发生网络错误。例如,“do”一词在下面使用的资源中不可用。

window.addEventListener("load", () => {

  const textarea = document.querySelector("textarea");

  const audio = document.createElement("audio");

  const mimecodec = "audio/webm; codecs=opus";

  audio.controls = "controls";

  document.body.appendChild(audio);

  audio.addEventListener("canplay", e => {
    audio.play();
  });

  let words = textarea.value.trim().match(/\w+/g);

  const url = "https://ssl.gstatic.com/dictionary/static/sounds/de/0/";

  const mediatype = ".mp3";

  Promise.all(
    words.map(word =>
      fetch(`https://query.yahooapis.com/v1/public/yql?q=select * from data.uri where url="${url}${word}${mediatype}"&format=json&callback=`)
      .then(response => response.json())
      .then(({query: {results: {url}}}) =>
        fetch(url).then(response => response.blob())
        .then(blob => blob)
      )
    )
  )
  .then(blobs => {
    // const a = document.createElement("a");
    audio.src = URL.createObjectURL(new Blob(blobs, {
                  type: mimecodec
                }));
    // a.download = words.join("-") + ".webm";
    // a.click()
  })
  .catch(err => console.log(err));
});
<textarea>what it does my ninja?</textarea>

资源位于 Wikimedia Commons Category:Public domain不需要从同一目录提供服务,请参阅 How to retrieve Wiktionary word content? , wikionary API - meaning of words .

如果资源的精确位置已知,则可以请求音频,尽管 URL 可能包含单词本身以外的前缀。

fetch("https://upload.wikimedia.org/wikipedia/commons/c/c5/En-uk-hello-1.ogg")
.then(response => response.blob())
.then(blob => new Audio(URL.createObjectURL(blob)).play());

不完全确定如何使用 Wikipedia API , How to get Wikipedia content using Wikipedia's API? , Is there a clean wikipedia API just for retrieve content summary?只获取音频文件。 JSON 响应需要解析以 .ogg 结尾的文本,然后需要对资源本身进行第二次请求。

fetch("https://en.wiktionary.org/w/api.php?action=parse&format=json&prop=text&callback=?&page=hello")
.then(response => response.text())
.then(data => {
  new Audio(location.protocol + data.match(/\/\/upload\.wikimedia\.org\/wikipedia\/commons\/[\d-/]+[\w-]+\.ogg/).pop()).play()
})
// "//upload.wikimedia.org/wikipedia/commons/5/52/En-us-hello.ogg\"

哪些日志

Fetch API cannot load https://en.wiktionary.org/w/api.php?action=parse&format=json&prop=text&callback=?&page=hello. No 'Access-Control-Allow-Origin' header is present on the requested resource

当不是来自同一来源的请求时。我们需要再次尝试使用 YQL,但不确定如何制定查询以避免错误。

第三种方法使用略有修改的 meSpeak.js 版本来生成音频,而无需发出外部请求。修改是为 .loadConfig() 方法创建一个适当的回调

fetch("https://gist.githubusercontent.com/guest271314/f48ee0658bc9b948766c67126ba9104c/raw/958dd72d317a6087df6b7297d4fee91173e0844d/mespeak.js")
  .then(response => response.text())
  .then(text => {
    const script = document.createElement("script");
    script.textContent = text;
    document.body.appendChild(script);

    return Promise.all([
      new Promise(resolve => {
        meSpeak.loadConfig("https://gist.githubusercontent.com/guest271314/8421b50dfa0e5e7e5012da132567776a/raw/501fece4fd1fbb4e73f3f0dc133b64be86dae068/mespeak_config.json", resolve)
      }),
      new Promise(resolve => {
        meSpeak.loadVoice("https://gist.githubusercontent.com/guest271314/fa0650d0e0159ac96b21beaf60766bcc/raw/82414d646a7a7ef11bb04ddffe4091f78ef121d3/en.json", resolve)
      })
    ])
  })
  .then(() => {
    // takes approximately 14 seconds to get here
    console.log(meSpeak.isConfigLoaded());
    meSpeak.speak("what it do my ninja", {
      amplitude: 100,
      pitch: 5,
      speed: 150,
      wordgap: 1,
      variant: "m7"
    });
})
.catch(err => console.log(err));

上述方法的一个警告是,在播放音频之前加载三个文件大约需要 14 秒半。但是,避免外部请求。

这对其中一个或两个都是积极的 1) 创建一个 FOSS , 开发者为常见和不常见的单词维护数据库或发音目录; 2) 进一步开发 meSpeak.js 以减少三个必要文件的加载时间;并使用基于 Promise 的方法提供有关文件加载进度和应用程序就绪情况的通知。

根据该用户的估计,如果开发人员自己创建并贡献一个在线文件数据库,并以特定单词的音频文件响应,这将是一个有用的资源。不完全确定 github是否适合存放音频文件?如果对此类项目表现出兴趣,将不得不考虑可能的选择。

关于javascript - 如何在 chromium 浏览器中创建文本或将文本转换为音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44346410/

相关文章:

python - 如何在 PYTTS (Python) 中设置属性 : age, 性别或语言

javascript - Mongodb 上的小 NLP 请求

javascript - 检查标签文本并验证与其关联的输入字段至少有 x 个字符

javascript - UL 元素宽度不随 JS 改变

audio - 更改mp3文件的采样率

delphi - 将 SAPI 文本转语音本地化为西类牙语

javascript - 使用 javascript 从查询创建文件

java - 音长不变

ios - FMOD 在 iOS 平台上比苹果的音频 API 有什么好处?

java - 无法更改 Android 默认 TextToSpeech 中的语言