本サイトはプロモーションが含まれています

【コピペOK】JavaScriptを使ってウェブサイト上で音声読み上げする方法【Web Speech API】

導入

皆さんはウェブサイトを作っていて、「テキストを音声で読み上げてほしい」「セリフをしゃべらせたい」などと思ったことはないでしょうか。


ウェブサイト上で音声読み上げをする方法はいくつかあり、例えばGoogleのText-to-Speech APIを使った方法がありますが、これは有料です。
しかし、JavaScriptを使うことで、ブラウザ上で音声読み上げを無料ですることができます。


そこで、今回の記事では、JavaScriptを使って音声読み上げする方法・使い方を実際のコードを紹介しながら、丁寧に説明します
紹介したコードはコピペOKなので、ご自身のサイトにもぜひ利用してください。



対応ブラウザ

SpeechSynthesis APIの対応バージョン

今回はブラウザ上で標準で使えるWeb Speech APIの、SpeechSynthesisというものを使います。


これは以下の主要なブラウザに対応しています。
ただし、IE、Android WebViewは非対応です


<パソコン>

  • Google Chrome バージョン33以降
  • Microsoft Edge バージョン14以降
  • Apple Safari バージョン7以降
  • Mozilla Firefox バージョン49以降

<スマホ・タブレット>

  • Google Chrome バージョン33以降
  • Apple Safari バージョン7以降

IE以外の主要ブラウザは、遅くとも2016年から対応しているため、問題なく使用できると思います。
Androidについても、WebViewではなく、通常のブラウザ(Chrome, Firefox)を使えば良いので、問題ないと思います。


注意点として、Chromium系のブラウザ(Chrome, Edge, Operaなど)では、Windows・Ubuntuなどで15秒以上音声が再生されると、途中で止まるバグがあります
なので、15秒以上の音声再生に使用する場合は、使用を控えた方が良いと思います。

実装方法

それでは、早速実装方法について説明します。

基本的な手順

まず、基本的な手順ですが、日本語の音声を再生する場合は、以下の手順で進めます。


1.最初に新しいSpeechSynthesisUtteranceインスタンスを作成します

const uttr = new SpeechSynthesisUtterance('再生するメッセージ');

2.言語を日本語に設定します

uttr.lang = 'ja-JP';

3.音声を再生します

speechSynthesis.speak(uttr);

手順としてはこれだけです。

実際の活用例

それでは、具体的な例として、しゃべらせたいメッセージ内容をテキストボックスに入力し、再生ボタンを押すとその内容を話してくれるサイトを実装してみます。


完成形は以下のようになります。
(現在は音声が不自然ですが、この後で改良します)

では、具体的な実装方法に移ります。


まず、今回のデモ用のページを作ります。
HTMLとCSSをそれぞれ以下のようにしてください。


HTML

<h1>音声読み上げデモ</h1>
<div class="main">
<div class="direction">
<label for="message">しゃべらせたいセリフを以下に入力<br>(日本語のみ、50字以内)</label>
</div>
<div class="chat-area">
<div class="bio">
<img id="image" src="https://drive.google.com/uc?export=view&id=1FiOWtMk0oi6tsgKD_lIUNX_M_dBQ0jf1" width="50" height="50" alt="site-logo">
</div>
<div class="speech-bubbles">
<textarea id="message" rows="3" cols="30" maxlength="50"></textarea>
</div>
</div>
<div class="bottom-area">
<button id="play">再生</button>
</div>
</div>

CSS

h1 {
text-align: center;
}
.main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.direction {
margin-bottom: 0.5rem;
}
.chat-area {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.speech-bubbles {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-left: 1rem;
}
.bottom-area {
display: flex;
flex-direction: column;
gap: 0.5rem;
justify-content: center;
align-items: center;
margin-top: 1rem;
}

そして、JavaScriptを使って、再生ボタンをクリックすると音声が再生されるようにします。
先ほど紹介した基本的な実装方法に従って、以下のように実装します。

const message = document.getElementById('message'); // セリフの入力エリア
const playButton = document.getElementById('play'); // 再生ボタン
// 再生ボタンをクリックしたとき、デフォルトの音声で再生
playButton.addEventListener('click', () => {
const uttr = new SpeechSynthesisUtterance(message.value);
uttr.lang = 'ja-JP';
speechSynthesis.speak(uttr);
});

このJavaScriptの内容について説明します。


まず、以下のプログラムで、セリフの入力エリアと再生ボタンのオブジェクトを取得しています。

const message = document.getElementById('message'); // セリフの入力エリア
const playButton = document.getElementById('play'); // 再生ボタン

そして、再生ボタンをクリックしたときに音声読み上げを行うため、以下のように書いています。

playButton.addEventListener('click', () => {
// この部分は再生ボタンをクリックしたときに実行される
});

最後に、先ほど紹介した基本的な実装方法に従って、セリフの入力エリアの中身message.valueを読み上げるメッセージとしてセットし、音声を読み上げる処理を追加しています。

// セリフの入力エリアの中身(message.value)を読み上げるメッセージとしてセットする
const uttr = new SpeechSynthesisUtterance(message.value);
// 日本語に設定する
uttr.lang = 'ja-JP';
// 音声を読み上げる
speechSynthesis.speak(uttr);

これで、以下のような入力した文字を読み上げるページを作ることができます。



(オプション)音声をより自然にする

これだけでも問題ないのですが、デフォルトの音声だと若干不自然です。
このため、音声を選択できるように変更します。


使用しているOS・ブラウザによって使用できる音声が異なりますが、現在使用しているOS・ブラウザで使用できる音声の一覧は、以下のように取得することができます。

const voiceList = speechSynthesis.getVoices();

例えば、Windows11、Google Chromeの場合、使用できる音声の種類は以下の23種類あります。

Microsoft Ayumi - Japanese (Japan)
Microsoft Haruka - Japanese (Japan)
Microsoft Ichiro - Japanese (Japan)
Microsoft Sayaka - Japanese (Japan)
Google Deutsch
Google US English
Google UK English Female
Google UK English Male
(以下省略)

また、getVoicesSpeechSynthesisVoiceオブジェクトの配列を返すようになっており、それぞれのオブジェクトは以下のような形式になっています。

{
default: true, // デフォルトの音声か
lang: "ja-JP", // 言語
localService: true, // OSに付属している音声か
name: "Microsoft Ayumi - Japanese (Japan)", // 音声の名称
voiceURI: "Microsoft Ayumi - Japanese (Japan)", // 音声の識別子(一意な値)
}

今回は日本語限定なので、langの値がja(日本語)から始まる音声の名称一覧から使用する音声を選択できるようにします。


まず、HTMLに以下のセレクトボックスを追加します。

<select id="voiceSelect"></select>

そして、現在のOS・ブラウザで使用できる音声一覧をJavaScriptで取得し、日本語の音声のみについて選択肢に追加していきます。

const voiceSelect = document.getElementById('voiceSelect');
// 音声一覧をセレクトボックスに追加する関数
const addVoiceList = () => {
const voiceList = speechSynthesis.getVoices();
for (let i=0; i<voiceList.length; i++) {
// 日本語の音声以外はスキップ
if (!voiceList[i].lang.startsWith('ja')) continue;
// selectタグ内の選択肢として、optionタグを新たに作成
const newOption = document.createElement('option');
// optionタグのテキストに音声の名称を設定
newOption.value = voiceList[i].voiceURI;
newOption.text = voiceList[i].name;
// デフォルトの音声の場合、選択済みにする
newOption.selected = voiceList[i].default;
// selectタグの選択肢として追加
voiceSelect.appendChild(newOption);
}
}
// 音声一覧をセレクトボックスに追加する関数を実行
addVoiceList();

この処理を行うと、selectタグ内に現在使用できる音声のoptionタグが追加されます。
例えば、Windows11、Chromeの場合、以下のようになります。

<select id="voiceSelect">
<option value="Microsoft Ayumi - Japanese (Japan)" selected>Microsoft Ayumi - Japanese (Japan)</option>
<option value="Microsoft Haruka - Japanese (Japan)">Microsoft Haruka - Japanese (Japan)</option>
<option value="Microsoft Ichiro - Japanese (Japan)">Microsoft Ichiro - Japanese (Japan)</option>
<option value="Microsoft Sayaka - Japanese (Japan)">Microsoft Sayaka - Japanese (Japan)</option>
<option value="Google 日本語">Google 日本語</option>
</select>

また、OSに付属していない音声(Googleの音声など)をインターネット経由で後からダウンロードした際に、それを選択肢に追加できるように、以下の処理を追加します。

// 後から使用できる音声の種類に変更があった場合にこの処理が行われる
speechSynthesis.onvoiceschanged = (e) => {
// 一度select内のoptionをすべて削除
while (voiceSelect.firstChild) {
voiceSelect.removeChild(voiceSelect.firstChild);
}
// 再度音声一覧を追加
addVoiceList();
}

最後にボタンを押したときの処理で、選択した音声を使用するように指定すれば完成です。

/* 選択した音声の値(voiceSelect.value)とvoiceURIが一致する音声の配列内で、
最初のもの(0番目)を選択 */
uttr.voice = speechSynthesis
.getVoices()
.filter((voice) => voice.voiceURI === voiceSelect.value)[0];

以下にあるのが完成したものです。
音声を変更すると、違う声で再生されるのがわかります。

すべて再生してみて、一番自然に感じた音声で固定しても良いと思います。
ただし、OS・ブラウザによって使用可能な音声が変わるので注意してください


いくつか試したところ、日本語では個人的に以下の音声が最も自然だと感じました。
あくまで個人の意見なので、参考程度にしてください。

OS音声の名称
WindowsMicrosoft Ichiro(男性)
Microsoft Sayaka(女性)
macOSGoogle 日本語 (Chrome)
Microsoft Nanami Online (Edge)
Kyoko (Safari / Firefox)
iOS / iPad OSKyoko
Android日本語 日本


その他のプロパティ・メソッド

その他にも、以下のプロパティ・メソッドなどがあります。
詳しくは、MDNのSpeechSynthesisのページを確認してください。

プロパティ

プロパティ名役割
paused一時停止中かどうか
pendingまだ話されていない発話内容が残っているかどうか
speaking現在発話中かどうか

メソッド

メソッド名役割
cancel発話を中止する
pause発話を一時停止にする
resume発話を再開する

まとめ

今回の記事では、JavaScriptを使ってブラウザ上で音声読み上げする方法を紹介しました。


今回の内容を使って、実際のサービス開発にも役立ててもらえると嬉しいです!