🙌

【TTS】SpeechSynthesisUtterance APIの使い方

に公開

Webブラウザ上で文字を声に変えて読み上げたいときに使えるのがSpeechSynthesisUtteranceです。日本語や韓国語など、さまざまな言語の発音も設定でき、文章を順番に読み上げることも可能です。
現在進行中のアプリケーションにこれらの機能を実装しようと思います。


基本文法

  1. オブジェクト生成
    const synth = window.speechSynthesis;

  2. テキスト設定
    const utter = new SpeechSynthesisUtterance('こんにちは');

  3. 言語設定
    utter.lang = "ja-JP";

  4. 速度や音の高さ調整(選択)
    utter.rate = 1;
    utter.pitch = 1;

  5. speak()で音声再生
    synth.speak(utter);

example
const text = "こんにちは"; // text変数を定義
const utter = new SpeechSynthesisUtterance(text); // synthを定義
utter.lang = "言語コード";           // 例: "ja-JP", "ko-KR", "en-US"
utter.pitch = 1;                     // 音の高さ、0 ~ 2
utter.rate = 1;                      // 話す速度、0.1 ~ 10
utter.volume = 1;                    // 音量、0 ~ 1
speechSynthesis.speak(utter);        // synthを使用

イベントの使用

SpeechSynthesisUtterance は以下のイベントが利用可能です:

イベント 説明
onstart 読み上げ開始時
onend 読み上げ終了時
onerror 読み上げ中にエラーが発生した場合
onpause 読み上げが一時停止された場合
onresume 読み上げが再開された場合
onmark / onboundary テキストマーカーや単語の境界イベント
  • 順番に読み上げたい場合は onend を使って次の文章を再生します
  • 例:utter.onend = () => speakTextsSequentially(...)

知っておくと良いポイント・注意点

  1. ブラウザ対応

    • ほとんどの最新ブラウザでサポートされていますが、IEや一部のモバイルブラウザでは制限があります
    • モバイルでは iOS Safari で ユーザー操作イベント(クリックなど) が必要
  2. 同時再生は不可

    • speechSynthesis.speak を複数回呼ぶと重複再生される場合があるため、順次再生には onend やキュー方式が必要
  3. 言語サポート

    • ブラウザによってサポートされる音声や言語が異なります
    • speechSynthesis.getVoices() で使用可能な音声リストを確認可能
  4. テキストの長さ

    • 長すぎるテキストは途中で切れたり、ブラウザが処理しきれない場合があるため、文章単位で分割して再生するのがおすすめ
  5. ユーザー体験

    • モバイルでは音量、音声変更、重複クリック防止、TTS の一時停止・停止機能を考慮すると良い

順次再生例:

配列とonendで日本語 → 韓国語など順番に再生可能

example
 type SpeakItem = { word: string; lang: string };

const card: SpeakItem[] = [
  { word: "안녕하세요", lang: "ko-KR" },
  { word: "こんにちは", lang: "ja-JP" },
];

const speakTextsSequentially = (items: SpeakItem[]) => {
  if (items.length === 0) return;

  const utter = new SpeechSynthesisUtterance(items[0].word);
  utter.lang = items[0].lang;

  utter.onend = () => speakTextsSequentially(items.slice(1));
  speechSynthesis.speak(utter);
};


speakTextsSequentially(card);

今度、実際に開発ログに書いてみます!

Discussion