ブラウザのWeb Speech API SpeechSynthesisでTextToSpeechがどこまで出来るか試してみた

文字を音声に変える、TextToSpeech。

いままで留守電サービスなどでGoogle Cloud PlatformIBM WatsonなどのAIを利用してきました。

これをもっとライトに、サクッと使いたく、ブラウザについている Web Speech API だとどうなんだろぉ〜と、試してみました。

IE以外では大体使えますね。
使ってみましょう。最終的にはこんな感じになります。

動作サンプル

https://monmon.jp/SpeechSynthesis/

流れは至ってシンプル

最初にどんな音声で話させたいかをブラウザから取得し、セレクトリストなどで選択できるように書き出します。(サンプルは、jQueryを使ってますのでDOMへのアクセスは、必要にあわせて調整下さい。)

const synth = window.speechSynthesis;

function populateVoiceList() {
    const voices = synth.getVoices();
    voices.forEach(function (voice) {
        if (voice.lang.match('ja')) {
            // 日本語だけリストに書き出す(英語を英語ランゲージで喋らせるとものすごく流暢ですよ)
            $('#voice').append($('<option>').html(`${voice.name} (${voice.lang})`).val(voice.name));
        }
    });
}

populateVoiceList();

// Chromeでは読み込みタイミングが違うらしく、イベントで処理
if (synth.onvoiceschanged !== undefined) {
    synth.onvoiceschanged = populateVoiceList;
}

voice.lang.match(‘ja’)部分を調整すれば英語やらも使えます。

再生させる

$('#play-btn').on('click', function () {
    //テキスト読み込み
    const utterThis = new SpeechSynthesisUtterance($('#text').val());
    //声を選び
    utterThis.voice = synth.getVoices().filter(voice => voice.name === $('#voice').val())[0];
    //ピッチをセット
    utterThis.pitch = $('#pitch').val();
    //速度(rate)をセット
    utterThis.rate = $('#rate').val();
    //ボリュームもセット
    utterThis.volume = $('#volume').val();

    //最後に再生(キューに追加する)
    synth.speak(utterThis);
});

#play-btnをクリックするとテキストデータを読み込み、コメント通りにもろもろ設定を行い再生させます。

見えた課題

こんな感じで、簡単にブラウザに喋らせる事ができるようになりましたが、3点。課題も見えてきました。

間が作れなさそう

途中でスペースや改行を入れても無視されて、間髪あけずに読み上げられます。(句読点が入るとちょっと間が空きます。)
読み上げイベントを拾う事ができるので、ちょっとロジックを考えていく必要がありそうです。

SSML (音声合成マークアップ言語) が反応しない

英語音声であれば、規格上、SSML (音声合成マークアップ言語)にも対応している(実際はあまり使えないそうです)っぽいのです。
コレが使えれば先出の「間が作れない問題」も一発で解決なんですが、日本語が対応するのはいつの日やら。

日本語音声が超少ない

Chromeで2種とか。選択の幅がほぼ無いっす。

他にも、長文だと動作しなかったり……(えほんと?)といった問題も潜んでいるっぽのですが、こちらは未検証。これらもろもろの問題が一切関係がなければ、簡単に使える便利機能でした。

GitHubにも

上げておきます。参考までに。

https://github.com/monmonjp/speechSynthesis/blob/main/index.html