Как создать или преобразовать текст в аудио в браузере Chromium?

Пытаясь найти решение, как использовать Web Speech API в Chromium? установлено, что

var voices = window.speechSynthesis.getVoices();

возвращает пустой массив для voices идентификатор.

Не уверен, что проблема связана с отсутствием поддержки в браузере Chromium. Не в порядке, Google.

Вопросы:

1) Есть ли обходные пути, которые могут реализовать требование создания или преобразования аудио из текста в браузере Chromium?

2) Как мы, сообщество разработчиков, можем создать базу данных аудио файлов с открытым исходным кодом, отражающую как общие, так и необычные слова; подается с соответствующими CORS заголовки?

1 ответ

Было найдено несколько возможных обходных путей, позволяющих создавать аудио из текста; два из них требуют запроса внешнего ресурса, другой использует meSpeak.js от @masswerk.

Использование подхода, описанного в разделе Загрузка аудио произношения слов из Google, который не позволяет заранее определить, какие слова фактически существуют в виде файла на ресурсе, без написания сценария оболочки или выполнения HEAD запрос, чтобы проверить, если происходит ошибка сети. Например, слово "делать" недоступно на ресурсе, используемом ниже.

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 Категория: Общественное достояние не обязательно обслуживается из того же каталога, см. Как извлечь содержание слова из Викисловаря?, wikionary API - значение слов.

Если точное местоположение ресурса известно, аудио может быть запрошено, хотя 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());

Не совсем уверен, как использовать API Википедии, Как получить контент Википедии, используя API Википедии?, Есть ли чистый Википедия API только для получения краткого содержания? чтобы получить только аудио файл. 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 подходящим местом для размещения аудиофайлов? Придется рассмотреть возможные варианты, если проявится интерес к такому проекту.

Другие вопросы по тегам