【JavaScript】Web Speech APIの音声合成(SpeechSynthesis)

Webブラウザ上でテキストを音声に変換して読み上げる「Web Speech API」の音声合成(SpeechSynthesis)機能について解説します。

サンプル




Web Speech API

Web Speech APIは、ウェブブラウザに音声認識(人の話す声を聞き取る)と音声合成(テキストを声で読み上げる)の機能を追加するための標準的な技術(API)です。
このAPIを使うことで、特別なプラグインやソフトウェアをインストールすることなく、JavaScriptを使ってウェブページ上で音声関連の機能を実装できます。

音声合成(SpeechSynthesis)でできること

SpeechSynthesisを使うと、ウェブページ上のテキストを、コンピュータの音声で読み上げさせることができます。具体的には、以下のようなことに活用できます。

  • アクセシビリティ向上:視覚に障碍のある方や、文字を読むのが難しい方のために、ウェブページのコンテンツを読み上げる。
  • ニュース記事やブログの読み上げ:長い文章を読む代わりに、音声で聞くことができるようにする。
  • 言語学習:正しい発音を聞いて学習する。
  • フォーム入力内容の確認:入力した情報を音声で確認する。
  • 通知:ユーザーに重要な情報を音声で伝える。
  • 簡単なボイスアシスタント:ウェブページ上で簡単な応答を音声で行う。

アイデア次第で、様々な面白い機能が実現できそうですね!

早速使ってみよう!基本的な使い方

では、実際にSpeechSynthesisを使ってみましょう。とてもシンプルです!

まず、簡単なHTMLファイルを用意します。テキストエディタ(メモ帳などでもOK)を開き、以下の内容をコピーして speech-synthesis-test.html のような名前で保存してください。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SpeechSynthesis テスト</title>
</head>
<body>

<h1>Web Speech API 音声合成テスト</h1>

<p>下のボタンを押すと、テキストが読み上げられます。</p>

<button id="speakButton">読み上げ開始</button>

<script>
  // ボタン要素を取得
  const speakButton = document.getElementById('speakButton');

  // 読み上げたいテキスト
  const textToSpeak = 'こんにちは!これはWeb Speech APIの音声合成テストです。';

  // ボタンがクリックされたときの処理
  speakButton.addEventListener('click', () => {
    // ブラウザがSpeechSynthesisに対応しているかチェック
    if ('speechSynthesis' in window) {
      // 読み上げる内容(発話)を作成
      const utterance = new SpeechSynthesisUtterance(textToSpeak);

      // 発話を実行
      window.speechSynthesis.speak(utterance);

      console.log('読み上げを開始しました。');
    } else {
      alert('お使いのブラウザは音声合成に対応していません。');
    }
  });
</script>

</body>
</html>

保存した speech-synthesis-test.html ファイルを、お使いのWebブラウザ(Google Chrome, Firefox, Safari, Edgeなど)で開いてみてください。

「読み上げ開始」ボタンをクリックすると、「こんにちは!これはWeb Speech APIの音声合成テストです。」と音声が聞こえてくるはずです!

コードの解説

  • document.getElementById('speakButton'):HTML内の id="speakButton" が付いたボタン要素を取得します。
  • const textToSpeak = '...':読み上げさせたいテキストを定義します。
  • speakButton.addEventListener('click', () => { ... });:ボタンがクリックされたときに、{} 内の処理を実行するように設定します。
  • if ('speechSynthesis' in window):現在開いているブラウザが speechSynthesis 機能を持っているかを確認します。
  • const utterance = new SpeechSynthesisUtterance(textToSpeak);:SpeechSynthesisUtterance というオブジェクトを作成します。これが「発話」の単位となり、読み上げるテキストや言語、声の種類などを設定できます。ここではまず、読み上げるテキスト textToSpeak を渡しています。
  • window.speechSynthesis.speak(utterance);:作成した「発話」(utterance) を、ブラウザの音声合成エンジン(window.speechSynthesis)に渡して、実際に読み上げを開始させます。

たったこれだけで、基本的な音声読み上げが実現できました!

もっとカスタマイズ!声の種類や話し方を変える

デフォルトの音声だけでなく、言語、声の種類、話す速度、声の高さなどをカスタマイズできます。

SpeechSynthesisUtterance オブジェクトには、様々なプロパティが用意されています。

  • text:読み上げるテキスト
  • lang:言語コード(例:'ja-JP' 日本語、'en-US' アメリカ英語)
  • voice:使用する声(SpeechSynthesisVoice オブジェクト)
  • pitch:声の高さ(0 から 2 まで、1 が標準)
  • rate:話す速度(0.1 から 10 まで、1 が標準)
  • volume:音量(0 から 1 まで、1 が標準)

カスタマイズ例

// ボタン要素を取得
  const speakButton = document.getElementById('speakButton');

  // 読み上げたいテキスト
  const textToSpeak = 'ゆっくり、低い声で話します。';

  // ボタンがクリックされたときの処理
  speakButton.addEventListener('click', () => {
    if ('speechSynthesis' in window) {
      const utterance = new SpeechSynthesisUtterance(textToSpeak);

      // --- カスタマイズここから ---
      utterance.lang = 'ja-JP'; // 言語を日本語に設定
      utterance.pitch = 0.8;    // 声の高さを少し低く
      utterance.rate = 0.7;     // 話す速度を少し遅く
      utterance.volume = 0.9;   // 音量を少し小さく
      // --- カスタマイズここまで ---

      window.speechSynthesis.speak(utterance);
      console.log('カスタマイズされた読み上げを開始しました。');
    } else {
      alert('お使いのブラウザは音声合成に対応していません。');
    }
  });

声の種類(Voice)を変えるには?

利用できる声は、OSやブラウザによって異なります。以下のコードで、利用可能な声のリストを取得できます。

let voices = []; // 声のリストを格納する配列

function populateVoiceList() {
  voices = window.speechSynthesis.getVoices();
  console.log('利用可能な声:', voices); // コンソールに声のリストを表示

  // ここで、取得した声を使って何か処理をする
  // 例: 特定の声を探してutterance.voiceに設定するなど
  // const japaneseVoice = voices.find(voice => voice.lang === 'ja-JP');
  // if (japaneseVoice) {
  //   utterance.voice = japaneseVoice;
  // }
}

// 初回実行(ブラウザによってはすぐに取得できない場合がある)
populateVoiceList();

// 声のリストが変更されたときに再度取得する(重要!)
if (speechSynthesis.onvoiceschanged !== undefined) {
  speechSynthesis.onvoiceschanged = populateVoiceList;
}

// --- ボタンクリック時の処理内で声を設定する場合 ---
// speakButton.addEventListener('click', () => {
//   if ('speechSynthesis' in window) {
//     const utterance = new SpeechSynthesisUtterance(textToSpeak);
//     utterance.lang = 'ja-JP';
//
//     // 例えば、リストの最初の日本語の声を使う
//     const japaneseVoice = voices.find(voice => voice.lang === 'ja-JP');
//     if (japaneseVoice) {
//       utterance.voice = japaneseVoice;
//       console.log('選択された声:', japaneseVoice.name);
//     } else {
//       console.log('日本語の声が見つかりませんでした。デフォルトの声を使用します。');
//     }
//
//     window.speechSynthesis.speak(utterance);
//   }
// });

注意点:getVoices() は、すぐに利用可能な声のリストを返さないことがあります。特に初回アクセス時など。そのため、speechSynthesis.onvoiceschanged イベントを使って、声のリストが準備できたタイミングで再度 getVoices() を呼び出すのが確実です。

発話の状態を知る(イベント)

読み上げが始まったとき、終わったとき、エラーが起きたときなどを知りたい場合がありますよね。SpeechSynthesisUtterance オブジェクトには、そのためのイベントハンドラも用意されています。

  • onstart:発話が開始されたとき
  • onend:発話が正常に終了したとき
  • onerror:発話中にエラーが発生したとき
  • onpause:発話が一時停止されたとき(pause()メソッド使用時)
  • onresume:発話が再開されたとき(resume()メソッド使用時)
  • onboundary:単語や文の境界に達したとき(高度な使い方)

イベント利用例

speakButton.addEventListener('click', () => {
    if ('speechSynthesis' in window) {
      const utterance = new SpeechSynthesisUtterance('イベントのテストです。読み上げが終わったらメッセージが出ます。');
      utterance.lang = 'ja-JP';

      // イベントハンドラの設定
      utterance.onstart = () => {
        console.log('読み上げ開始!');
        speakButton.disabled = true; // 読み上げ中はボタンを無効化
      };

      utterance.onend = () => {
        console.log('読み上げ終了!');
        speakButton.disabled = false; // ボタンを有効化
      };

      utterance.onerror = (event) => {
        console.error('読み上げエラー:', event.error);
        speakButton.disabled = false; // エラー時もボタンを有効化
      };

      window.speechSynthesis.speak(utterance);
    }
  });

この例では、読み上げが始まったらコンソールにメッセージを出し、ボタンを一時的に押せないようにします。読み上げが終わるかエラーが発生したら、再びボタンを押せるようにしています。

他の便利なメソッド

window.speechSynthesis オブジェクトには、speak() 以外にも便利なメソッドがあります。

  • cancel():現在の読み上げ、およびキューに入っている読み上げをすべてキャンセルします。
  • pause():現在の読み上げを一時停止します。
  • resume():一時停止した読み上げを再開します。
  • speaking:現在読み上げ中かどうかを示すブール値(true / false)
  • pending:キューに待機中の発話があるかどうかを示すブール値
  • paused:現在一時停止中かどうかを示すブール値

これらを組み合わせることで、再生/一時停止/停止ボタンなどを実装できます。

注意点とブラウザの互換性

  • ブラウザサポート:Web Speech API、特にSpeechSynthesisは、主要なモダンブラウザ(Chrome, Firefox, Safari, Edge)でサポートされています。しかし、古いブラウザでは動作しない可能性があります。また、利用できる声の種類や質は、OSやブラウザによって大きく異なります。 Can I use... のようなサイトで互換性を確認すると良いでしょう。
  • 文字数制限:一度に読み上げさせられるテキストの長さに制限がある場合があります(ブラウザやOS依存)。非常に長いテキストは分割して speak() を呼び出すなどの工夫が必要になるかもしれません。
  • ユーザー操作の必要性:多くのブラウザでは、ユーザーが何らかの操作(ボタンクリックなど)をしないと、音声の再生が自動的に開始されないセキュリティ上の制限があります。ページを開いたらいきなり音声が流れる、ということは基本的にできません。
  • 非同期処理:getVoices() や発話の完了は非同期で行われます。特に getVoices() はすぐに結果が返らないことを意識してコードを書く必要があります(onvoiceschanged イベントの利用)。

まとめ

今回は、Web Speech APIの音声合成(SpeechSynthesis)機能について、基本的な使い方からカスタマイズ、イベント処理までを解説しました。

  • SpeechSynthesisUtterance で読み上げる内容や話し方を設定する。
  • window.speechSynthesis.speak() で発話を開始する。
  • lang, voice, pitch, rate, volume でカスタマイズできる。
  • getVoices() と onvoiceschanged で利用可能な声を取得できる。
  • onstart, onend, onerror などのイベントで発話の状態を検知できる。

特別なライブラリやAPIキーなしで、手軽にウェブページに音声読み上げ機能を追加できるのは魅力的ですね!ぜひ、あなたのウェブサイトやアプリケーションで活用してみてください。

この記事が、Web Speech API音声合成への第一歩となれば幸いです。