【问题标题】:How to create or convert text to audio at chromium browser?如何在 chromium 浏览器上创建文本或将文本转换为音频?
【发布时间】:2017-06-03 16:55:32
【问题描述】:

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

var voices = window.speechSynthesis.getVoices();

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

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

问题:

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

2) 作为开发者社区,我们如何创建一个包含常用词和不常用词的音频文件的开源数据库;提供适当的CORS 标头?

【问题讨论】:

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


    【解决方案1】:

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

    使用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 APIHow 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 是否适合托管音频文件?如果表现出对此类项目的兴趣,将不得不考虑可能的选择。

    【讨论】:

      猜你喜欢
      • 2012-09-20
      • 2010-12-09
      • 2018-12-19
      • 2020-05-10
      • 2011-09-25
      • 2014-09-02
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      相关资源
      最近更新 更多