新たなプロジェクト「DOM-SPEAKER(ドムスピーカー)」を公開しました。
HTML や XML のファイルから要素を抜き出し、階層を視覚的に表示し、Web Speech API の音声合成(SpeechSynthesis)でタグ名を読み上げるボーカルシンセサイザーです。
音声の種類を変更したり、読み上げのピッチ(音程)や速さなどを変更することが可能です。
あらかじめ用意されたプリセットの HTML データに加えて、直接ローカルファイルを読み込むこともできます。また、解析した HTML データや音声の設定は localStorage
に保存できます。
なお、本アプリで使用している Speech Synthesis は現時点では試験的な機能であり、OS やブラウザによって大きく挙動が異なりますのでご了承ください。
構成と機能
見出し「構成と機能」本アプリは以下のセクションで構成されています。
1. HEADER
見出し「1. HEADER」読み込んだファイルのタイトルと URL が表示されます。
タイトルの値は読み込んだファイル内の <title>
要素が参照されますが、見つからない場合には「Untitled」が表示されます。なお、タイトルは自由に変更可能です。
URL は、まず <link rel="canonical">
が参照され、そのあとに <meta property="og:url">
が参照されます。どちらも見つからない場合には「Canonical URL not found」が表示されます。
2. DISPLAY
見出し「2. DISPLAY」ディスプレイには、読み込んだファイルの HTML や XML の要素が解析され、タグ名とともにネストに応じた深さで視覚化されます。
ここで表示されるタグ名は、通常は <body>
から下の要素です。
この各要素を押下すると、タグ名が読み上げられ再生位置に設定されます。
また、ディスプレイエリア内はキーボードでも操作することができます。
操作 | キー |
---|---|
エリア外から再生位置にフォーカス | Tab / Shift + Tab |
音声を再生 / 再生位置に設定 | Enter |
フォーカスの移動 | ↑ / → / ↓ / ← / PageUp / PageDown |
最初の要素にフォーカス | Home |
最後の要素にフォーカス | End |
自動再生 / 一時停止 | Space |
自動再生の一時停止 | Esc |
なお、Esc キーによる自動再生の一時停止については、ディスプレイエリアに限らずにページ全体で有効なキー操作です。
ディスプレイの下にはモードを変更するスイッチが 2 つ用意されています。
VERTICAL-LR
見出し「VERTICAL-LR」「VERTICAL-LR」を選択すると、ディスプレイ内の要素は垂直向きになり、スクロールは水平方向に切り替わります。
ちなみに、この見た目の切り替えは CSS の :has()
擬似クラスで実現しています。
AUTO SCROLL
見出し「AUTO SCROLL」「AUTO SCROLL」を選択すると、再生位置に応じてスクロール位置が移動します。デフォルトではオンになっていますが、自動再生中にエリア内を自由にスクロールしたいときなどにチェックを外します。
3. VOICE CONTROLS
見出し「3. VOICE CONTROLS」このエリアでは、音声データの種類や読み上げの設定を変更できます。
VOICE
見出し「VOICE」「VOICE」では、音声データ(音源)を選択できます。ここで表示されるリストには OS にインストールされている音源とブラウザ独自の音源が含まれるため閲覧環境によって異なります。
なお「Google」や「Microsoft」といった接頭辞が付いたオンライン音源がありますが、これらについては動作が安定しないことがあります。
また、OS に音声データを追加することも可能です。ただ、ダウンロードサイズが大きいデータもあるため事前にご確認ください。
Mac の場合には「鐘の音(Bells)」や「ロボット風ボイス(Zarvox)」といった、飛び道具的な音源も用意されているので、よりシンセライクな楽しみ方ができます。
PITCH
見出し「PITCH」「PITCH」では、読み上げのピッチ(音程)を変更できます。
音声データによってはピッチが変化しないものもあります。
項目 | 値 |
---|---|
範囲 | 0 から 100 |
初期値 | 50 |
変換後の値 | 0 から 2 |
「変換後の値」は JS で使用する際に変換した値の範囲を意味します。例えば「PITCH」のスライダーの値が 75
の場合には、JS で使用するときには 1.5
に変換されます。
MOD
見出し「MOD」「MOD」は、Modulation(変調)を意味し、要素の階層にあわせてピッチに変化をつけることができます。正の値を与えると、要素の階層が深くなるごとにピッチが高くなり、負の値を与えると、反対に階層が深くなるごとにピッチが低くなります。
最初に表示されるプリセット「Tuner」は、構造が階段状になっているので、この変化が確認しやすくなっています。
項目 | 値 |
---|---|
範囲 | -100 から 100 |
初期値 | -20 |
変換後の値 | -0.1 から 0.1 |
RATE
見出し「RATE」「RATE」では、読み上げの速度を変更できます。極端に速度を上げることで、アタックの短いパーカッシブな音を得ることもできます。
音声データによっては速度が変化しないものもあります。
項目 | 値 |
---|---|
範囲 | 0 から 100 |
初期値 | 25 |
変換後の値 | 0 から 4 |
ちなみに、SpeechSynthesisUtterance.rate
の範囲では 0.1
から 10
とされているのですが、4
を超えてもほとんど変化が得られないので、このような設定にしています。
BPM
見出し「BPM」「BPM」では、再生時の速度(テンポ)を変更できます。
項目 | 値 |
---|---|
範囲 | 0 から 240 |
初期値 | 60 |
指定した値はミリ秒(ms)に変換されて、setInterval()
の待ち時間として使用されます。
なお、この setInterval()
で処理を呼び出したときに、音声の再生が終わっていない場合には次のタグには移動せずにもう一周するため、タグ名の長さによって独特のリズムが生まれます。
VOLUME
見出し「VOLUME」「VOLUME」では、音量を変更できます。
項目 | 値 |
---|---|
範囲 | 0 から 100 |
初期値 | 100 |
変換後の値 | 0 から 1 |
4. BUTTONS
見出し「4. BUTTONS」ボタンエリアには「IMPORT」と「PLAY」の 2 つのボタンが配置されています。
IMPORT
見出し「IMPORT」「IMPORT」ボタンを選択すると、ローカルのファイルを読み込むことができます。
対象となるファイルの型は text/html
もしくは text/xml
なので、HTML ファイルに加えて XML ファイルや SVG ファイルも読み込むことができます。
なお、読み込むファイルのサイズが大きいと、解析や描画処理に時間を要する場合があります。
PLAY
見出し「PLAY」「PLAY」ボタンを選択すると、「BPM」で指定したテンポで自動再生が開始します。もう一度選択すると一時停止します。
キーボードの Esc キーでも一時停止します。
5. STORAGE
見出し「5. STORAGE」「STORAGE」では、解析した HTML / XML のデータや音声の設定を localStorage
に保存できます。
「SAVE」ボタンを選択するとテキストフィールドが出現し、保存するアイテム名を入力できます。初期値はタイトルが入力されています。
入力を終えるとリストに追加され、localStorage
にもデータが保存されます。
リストの中から保存したアイテム名を選択すると設定が反映され、アイテム名の隣にある削除アイコン(Delete)を選択すると、保存したアイテムが削除されます。
6. HTML PRESETS
見出し「6. HTML PRESETS」「HTML PRESETS」では、あらかじめ用意された HTML データを読み込むことができます。
「VOICE CONTROLS」の値は保持していないため、音声の設定は変更されません。
Tuner
見出し「Tuner」最初に表示されるデータで、音声の試聴やチューニング用として用意しています。
Table-Layout Era
見出し「Table-Layout Era」開発者がウェブデザイン関連のスクールに通っていたときの課題として作成したサイトのデータです。その名のとおり、テーブルレイアウトが主流の時代の HTML です。
MT-333
見出し「MT-333」開発者がその後、初めて CMS を使用して作成した個人ブログの HTML です。当時使用していた CMS が Movable Type の 3.33 だったので、このような名前を付けています。
Home
見出し「Home」このサイトのホームを動的に読み込みます。今後内容が更新されて HTML の構造が変わると、生成される内容も変化します。
カスタマイズ
見出し「カスタマイズ」読み込む HTML ファイルのコードに独自属性を付与することで、データの解析方法をカスタマイズすることができます。
data-dom-speaker="body"
この見出しのリンクファイルをインポートしたときに、通常は <body>
より下の要素が対象になりますが、任意の要素に data-dom-speaker="body"
を指定することで対象となる要素を変更できます。
また、<html data-dom-speaker="body">
のように指定することで、<head>
要素以下もすべて対象に含めることができます。
data-dom-speaker="ignore"
この見出しのリンク要素に data-dom-speaker="ignore"
を付けると、その要素自身が対象外となり、データには含まれなくなります。子孫要素には影響しません。
data-dom-speaker="ignore-all"
この見出しのリンク要素に data-dom-speaker="ignore-all"
を付けると、子孫要素も含めて対象外となり、データには含まれなくなります。
data-dom-speaker="rest"
この見出しのリンク要素に data-dom-speaker="rest"
を付けると、その要素は読み上げられなくなるので、休符として使用することができます。また、この属性を指定した要素は、ディスプレイエリアではタグ名ではなく <…>
(三点リーダ)が表示されます。
以下の例では「div」が 3 回読み上げられますが、最後の <div>
は読み上げられません。
既知の問題
見出し「既知の問題」本アプリについて、現時点では以下の問題を認識しています。
相互運用性
見出し「相互運用性」繰り返しになりますが、Speech Synthesis は実験的な機能なため、OS やブラウザによって挙動が大きく異なります。
ダウンロードされている音声データによって異なるのはもちろんですが、同じ名前の音声であっても、デバイスや OS によって読み上げ方が異なることがあります。
例えば、iPadOS と macOS で同じ「Cellos(en-US)」という音声を鳴らすと、iPadOS では「RATE」で速度を細かく調整できますが、macOS では速度が変わりません。
OS のバージョンに起因するかもしれませんが、細かくは調査できていません。
音声データの不確実性
見出し「音声データの不確実性」音声の読み上げ方については、SpeechSynthesisUtterance
で設定しています。このインタフェースには pitch
や rate
といったプロパティがあり、本アプリの「PITCH」や「RATE」の値はこれらのプロパティに反映されます。
しかし、音声データによっては pitch
や rate
に対応していないことがあり、それを調べる方法が見つからず、実際にレンジスライダーを動かしてみないと対応の可否がわかりません。
また、rate
については、音声を切り替えたときには即時反映されずに、レンジスライダーを操作すると反映されることがあります。
加えて、原因は不明ですが「Google」のプレフィックスが付いた音声データでは、rate
を変更すると音声が流れなくなってしまいます。苦肉の策ですが、これらの音源については rate
の値が変わらないように調整しています。
このように、選択した音声データによって思わぬ不具合が発生する可能性があります。
音声の同時再生はできない
見出し「音声の同時再生はできない」Speech Synthesis では複数の音声を同時に鳴らすことができません。
例えば、ウィンドウをいくつか開いてから「PLAY」ボタンを選択すると、順番に音声が再生され、いずれか 1 つの音声しか流すことができません。
Web Audio API との連携の難しさ
見出し「Web Audio API との連携の難しさ」開発当初は Web Audio API で簡単なリズムトラックを鳴らすことも試みました。
同時に音を鳴らすこと自体はできるのですが、音声の種類によって読み上げのタイミングに個性があり、テンポを同期させるのが難しかったので見送りました。
また、Web Speech API の音声を Web Audio API に接続して加工するといったことも試したかったのですが、方法を見つけることができませんでした。
おわりに
見出し「おわりに」HTML は同じ構成要素がパターン化して繰り返して出現することが多いため、音声として聞くことで、そのリズムを楽しむことができます。
対応するかは今のところ未定ですが、追加機能としては以下が考えられそうです。
- 「STORAGE」からアイテムを削除した後に元に戻せるようにする(undo)
- 「STORAGE」に登録した後にアイテム名を変更できるようにする
- 「STORAGE」に登録したアイテムの順番を並べ替えられるようにする
- 変更したデータのエクスポート機能
- 自動再生時のループのオン・オフ切り替え
- 読み込んだファイルから favicon を取得して表示
- タイトルの編集を
contenteditable
から<input>
に変更 - レンジスライダーの値を数値から直接編集できるようにする
- ブックマークレットやブラウザ拡張機能
また、HTML の構造を解析して、Web Audio API で音を鳴らす派生版のアプリも考えられますが、自由度が高いだけに完成までの道のりは長くなりそうです。
関連リンク
見出し「関連リンク」- DOM-SPEAKER | grip on minds
- SpeechSynthesis | MDN(外部リンクを開く)
- SpeechSynthesisUtterance | MDN(外部リンクを開く)
「STORAGE」の UI については、以下のドラムシンセのウェブアプリを参考にしました。