音声合成エンジン VOICEROID+ で作成した朗読音声とテキストを同期して再生する EPUB3 の試作品を作った - EPUB3、Media Overlays、VOICEROID+ -

by

EPUB3 には動画・音声とテキストを同期させる仕様「EPUB Media Overlays 3.0(以後、Media Overlays)」があります。
この Media Overlays を利用して見て読むだけでなく聴いて読む EPUB3 を作って見ました。
第36回 Sugamo.css のフォローアップ記事でもあります。
なお再生する環境は iOS5 以上の iPhone4/iPad、リーディングシステムは iBooks1.5 以上を想定しています。

取り急ぎ完成した EPUB3 を見たい方はこちら

記事の目次

制作手順

1)準備

何はともあれ EPUB3 のファイルが必要です。適当に作って準備しましょう。
今回は作りおきのファイルを利用しました。

サンプル1:ASCANDALINBOHEMIA.epub

2)再生箇所の指定

音声と内容を同期させるため、HTML 文書内のそのテキストを読み上げている音声と同じ範囲を id 属性で指定します。

加工前

<p class="noindent">「まだデータがない。データなしに理論を立てるのは、致命的な誤りだ。無意識のうちに、事実と符合するべく推理するのではなく、推理に符合するべく事実を歪曲することになる。しかしここに紙がある。演繹してごらん。」</p>

加工後

<p id="chp01-p025" class="noindent">
<span id="chp01-p025-01">「まだデータがない。データなしに理論を立てるのは、致命的な誤りだ。</span>
<span id="chp01-p025-02">無意識のうちに、事実と符合するべく推理するのではなく、推理に符合するべく事実を歪曲することになる。</span>
<span id="chp01-p025-03">しかしここに紙がある。演繹してごらん。」</span>
</p>

指定できる範囲は任意ですが、音声を再生している箇所をハイライトなどの視覚効果を加えることができるので(後述)、あまり広範囲を指定すると指定した範囲内のどこを再生しているのかわかりにくくなると思います。
今回の再生範囲の区切りは特に短いものを除いては基本的にセンテンスとしました。

3)合成音声の制作

次に音声ファイルを作成します。音声データは人が朗読するものを録音して利用するのが一般的なのかは知りませんが、今回は AH-Software が発売している音声合成エンジン『VOICEROID+ 結月ゆかり(http://www.ah-soft.com/voiceroid/yukari/)』を使用しました。

他にも多く音声合成エンジンがありますが、『VOICEROID+ 結月ゆかり』を選んだ理由としては以下の点です。

  1. 機能と価格のバランスが良かった。
  2. 落ち着きがあり優しい声がベースになっているのでので、朗読に適していた。

VOICEROID+ の使い方は割愛しますが、簡単に説明すると

  1. テキストを貼り付ける
  2. 再生する
  3. イントネーションや読み方がおかしかったら修正して2に戻る

の繰り返しです。

固有名詞や一般的ではない文字はイントネーションがおかしくなる傾向がありましたが、だいたい修正なしで読みあげてくれたと思います。

写真:VOICEROID+ 結月ゆかりのメイン画面
基本的な画面。テキストフィールドに読ませたいテキストを入れて再生させると音声で読み上げます。
写真:フレーズ調整画面
フレーズ調整画面。イントネーションや読み方がおかしい時に修正する。調整したフレーズや単語を登録できるので、だんだんと読み上げ精度が上がるようです。
写真:音響効果画面
ピッチや話す速度も調整できる。今回作成した音声データは会話部分は1.1倍、他は1倍にしました。

保存すると音声データは .wav で、読ませたテキストは .txt で保存されます。
今回は 1) で定義した再生範囲毎に1つの音声ファイルを作成しました。音声ファイルはwavだとファイルサイズが大きかったので、音質とファイルサイズを検討して M4A に変換しました。WAV から M4A への変換は XLD(http://tmkk.pv.land.to/xld/)を使用しました。どの音声フォーマットを使う方のが良いのかわかりません。ここは更に調べる必要があります。

4)SMIL の記述

音声データとテキストを同期させるために SIML を利用します。1つの HTML 毎に1つの SMIL を用意します。

SMIL の中身は次の通り。

<?xml version="1.0" encoding="UTF-8"?>
<smil xmlns="http://www.w3.org/ns/SMIL" version="3.0" xmlns:epub="http://www.idpf.org/2007/ops">
<body>
...
</body>
</smil>

body 要素内に音声データと HTML 文書内の再生範囲を par 要素で紐付けます。

<?xml version="1.0" encoding="UTF-8"?>
<smil xmlns="http://www.w3.org/ns/SMIL" version="3.0" xmlns:epub="http://www.idpf.org/2007/ops">
<body>
...
<par id="chp01-p025-01">
<text src="../doc/chapter01.xhtml#chp01-p025-01"/>
<audio src="../audio/chapter01/chp01-p025-01.m4a" clipBegin="0:00:00.000" clipEnd="00:00:06.608"/>
</par>
<par id="chp01-p025-02">
<text src="../doc/chapter01.xhtml#chp01-p025-02"/>
<audio src="../audio/chapter01/chp01-p025-02.m4a" clipBegin="0:00:00.000" clipEnd="00:00:08.719"/>
</par>
<par id="chp01-p025-03">
<text src="../doc/chapter01.xhtml#chp01-p025-03"/>
<audio src="../audio/chapter01/chp01-p025-03.m4a" clipBegin="0:00:00.000" clipEnd="00:00:04.520"/>
</par>
...
</body>
</smil>

1つの再生箇所につき1つの par 要素で定義します。par 要素の中には、text 要素で HTML 文書内の再生範囲(id 属性を付与した箇所)を指定し、audio 要素で再生する音声ファイルを指定します。

text 要素は src 属性で再生箇所を指定します。再生箇所が chapter01.xhtml 内の id=”chp01-p025-01″ であった場合は次のようになります。

<par>
<text src="../doc/chapter01.xhtml#chp01-p025-01"/>
</par>

audio 要素も text 要素と同じく再生する音声ファイルを src 属性で指定します。

<par>
<audio src="../audio/chapter01/chp01-p025-01.m4a" clipBegin="0:00:00.000" clipEnd="00:00:06.608"/>
</par>

加えて clipBegin で音声ファイルの再生開始時間、clipEnd で再生終了時間を指定します。今回は1つの再生箇所につき1つの音声ファイルを用意したので、clipBegin は常に音声ファイルの最初から、clipEnd は音声ファイルの再生時間になります。
clipBegin と clipEnd の値は Appendix B. Examples of Clock Values – EPUB Media Overlays 3.0(http://idpf.org/epub/30/spec/epub30-mediaoverlays.html#app-clock-examples)にいくつかサンプルがあります。

今回のハマりどころの一つが clipEnd の取得でした。サウンド関連の知識がさっぱりなかったので、この値をどうやって取得するのかに頭を悩ましました。また再生箇所を細かく別けたので、それだけ音声ファイルが増え、一度に長さを取得する方法を探すのに苦労しました。
結果的に音声ファイルの再生時間の取得には黒羽製作所(http://kurohane.net/)が配布している Windows 用のソフトウェア『真空波動研Lite』を使うことで解決しました。『真空波動研Lite』は”つくりもの”の”生産物”のページからダウンロードできます。

写真:真空波動研Liteに音声ファイルをドロップ
ウィンドウに音声ファイルをドロップすると、すぐ解析が始まります。解析が終わったら全選択し、コピーします。
写真:テキストエディタにコピーした情報を張り付ける
テキストエディタなどにペーストします。音声ファイルの様々な情報が得られます。あとはこの情報をエクセルなどで加工したら SMIL ファイルは簡単に作ることができると思います。

5)OPF ファイルの編集

次に、作成した音声ファイルや SMIL ファイルなどを OPF ファイルに追記します。

音声ファイルを item 要素に登録

manifest 要素下の item 要素に音声ファイルを記述します。EPUB3 を作成できる人には特に注意するところはありません。

<manifest>
...
<item id="chp01-h001-01" href="audio/chapter01/chp01-h001-01.m4a" media-type="audio/mpeg"/>
...
</manifest>
SMIL ファイルを item 要素に登録

音声ファイルと同様に SMIL ファイルを item 要素として登録します。

<manifest>
...
<item id="smil-chapter01" href="smil/chapter01.smil" media-type="application/smil+xml"/>
...
</manifest>
HTML 文書を SMIL の紐付け

すでに item 要素で記述されている HTML 文書と SMIL ファイルを紐付けます。HTML 文書を登録している item 要素に media-overlay 属性を加え、media-overlay 属性の値は該当する SMIL ファイルの item 要素にある id 属性値にします。
このことから1つのHTMLファイルにつき、SMILファイルは1つとなります。
修正前

<manifest>
...
<item id="chapter01" href="doc/chapter01.xhtml" media-type="application/xhtml+xml"/>
...
</manifest>

修正後

<manifest>
...
<item id="chapter01" href="doc/chapter01.xhtml" media-type="application/xhtml+xml" media-overlay="smil-chapter01"/>
...
</manifest>
SMIL ファイルの再生時間

metadata 要素下の meta 属性で各 SMIL ファイルの合計再生時間を記述します。

<metadata ...>
...
<meta property="media:duration" refines="#smil-title">0:00:11.808</meta>
...
</metadata>

property 属性値は media:duration、refines 属性値は SMIL ファイルを記述した item 要素の id 属性値を指定します。

合計再生時間

各 SMIL ファイルの再生時間に加え、全体の再生時間を記述します。この meta 要素には refines 属性はありません。

<metadata ...>
...
<meta property="media:duration">0:01:22.572</meta>
...
</metadata>
再生箇所のスタイルシート

リーディングシステムが Media Overlays を利用する時に、音声がどの箇所と同期しているのかを判断できるように視覚効果を与えることがあります。
作成者が任意の効果を与える為に、リーディングシステムが HTML 文書内の再生箇所に付与するスタイルシートのセレクタを指定できるようになっています。

metadata 要素下の meta 要素に property=”media:active-class” を与え、任意につけた値がセレクタになります。なおセレクタはクラスセレクタになるので、CSS ファイルに記述する時は「.meta値」となります。

<meta property="media:active-class">media-overlay-active</meta>
.media-overlay-active
{
background-color:#000;
color:#fff;
}

以上で Media Overlays に対応した EPUB3 の制作方法は終了です。

サンプル2:ASCANDALINBOHEMIA-voice.epub

6)iBooks 用にカスタマイズ

iBooks で Media Overlays を利用するには iBooks の独自拡張である Fixed Laytout モードにする必要があります。Fixed Laytout の EPUB にしないと音声をコントロールするメニューが表示されません。

xml ファイルの追加

Fixed Layout モードにするため、以下の内容を記述し、com.apple.ibooks.display-options.xml としたファイルを META-INF ディレクトリ以下に保存します。

<?xml version="1.0" encoding="utf-8"?>
<display_options>
<platform name="*">
<option name="fixed-layout">true</option>
</platform>
</display_options>
meta 要素の追加

HTML 文書に meta 要素で viewport を指定します。viewport はスマートフォン向けのサイトを作ったことがある方なら見たことがあると思います。content 属性の width と height の値は数値のみが有効になるようで、device-width や device-height を使用すると表示がおかしくなったので注意が必要です。

<meta name="viewport" content="width=552px, height=920px, user-scalable=no"/>
スタイルシートの追加
body
{
width: 552px;
height: 920px;
}

写真:再生箇所に視覚効果が与えられる

以上の処理で、iBooks で Media Overlays を利用した EPUB3 が完成しました。

サンプル3:ASCANDALINBOHEMIA-ibooks.epub

7)iBooks に最適化する追加の処理

iBooks の Fixed Layout モードはリフローをせず見た目の領域以外のコンテンツを表示してくれません。上のサンプルでは第一章、第二章、第三章、奥付の下が切れてしまい非表示のままです。
もっとも音声は非表示領域も再生し続けるので、オーディオブックとしての利用価値はあります。しかし再生している箇所とテキストを同期して表示できるのMedia Overlaysの利点を生かせません。
という理由でこれまで Media Overlays を利用した iBooks 用 EPUB3 は絵本などの固定レイアウトで破綻しないものが多かったのではないかと思います。
今回はあくまでテキストが主体の文芸。そして見た目や印刷書籍の再現を重視し、文章の途中で HTML を別けるといった選択はしません。

要はボックスから溢れているコンテンツが表示できればとりあえずの解決になるので、表示して欲しいコンテンツを内包している要素を CSS の overflow を利用し、スクロールして表示できるようにします。

サンプルはどれも section 要素に本文を収めています。この section 要素に CSS で overflow:scroll; を指定し、スクロール可能にします。
もちろんこれを推奨しているわけではなく、iBooks専用に暫定処置です。今回はあくまで試作ということで、こうしたサンプルを作りました。

写真:ページ内のコンテンツは上下にスクロールし、左右の移動でページを遷移する

この処理をした結果、1ページのコンテンツは上下スクロールで読み、次のページ(次のHTML)へは前後のコンテンツへは左右方向で移動するという印刷物にはあらざる挙動をします。

でも挙動に関してはこれで問題ないと思っています。作っているのは印刷書籍を模した電子書籍ではないので。
ちなみに Firefox のアドオンにある EPUBReader(http://www.epubread.com/en/)も似たような挙動をします。

サンプル4:ASCANDALINBOHEMIA-ibooks-cmp.epub

8)さらに拡張してみる

サンプル4はユーザーがスクロールすることで、コンテンツおよび音声再生箇所を見ることはできます。しかし望む挙動は音声再生時にコンテンツが自動的にスクロールし、再生箇所が常に画面内に収まることです。
何かしらの理由によりユーザーが画面をスクロールすることができない状況を想定し、対処する必要があるかと思います。

できれば再生箇所に割り当てられるセレクタを取得し、再生箇所が画面内に表示されるよう JavaScript などで処理できればよかったのですが、自分の力量が足りないのか制御できませんでした。

そこでかなり力技ですが CSS の position を用いて、再生箇所を抜き出し画面内に表示する方法で対応しました。
写真:CSSで再生箇所がポップアップしたように表示される

サンプル5:ASCANDALINBOHEMIA-ibooks-cmp2.epub

朗読音声を作ってみて

さて制作を終えて感想と反省です。

制作の動機は VOICEROID+ 結月ゆかりの声を聴いて、これなら少しの手間で TTS のあのロボットぽい音声より遥かに人間の声のように、かつ人の声を使うよりはるかに低コストで好きな時に好きなように朗読音声を得られるということでした。
ただ朗読音声を EPUB にパッケージするとファイルごとの容量が肥大します。OS やアプリケーションに内蔵された TTS はテキストを直接読み上げるので、この容量の問題や音声を作る手間を省いてくれますが、朗読というレベルにはまだ達していないと感じています。VOICEROID による音声作りは TTS と肉声の中間に位置するのではないでしょうか。

また TTS は読み間違えや意図とした通りに読んでくれないことが多々あります。作品によっては表記とは異なる読みをさせたい場合があります。それはどう技術的に対応したらよいのでしょう?
例えば「とある科学の超電磁砲」は「とある かがく の ちょうでんじほう」とは読みません。「とある かがく の れーるがん」です(もっとも表記と読みについては、人によって考え方もあるでしょうが)。

また VOICEROID+ を使って音声を調節している時に「はて、イントネーションはこれで正しいのか」や「読みはこれで良かったっけ」、「息継ぎは表読点とは違うな」などのように発見と苦労がありました。

そもそもサウンド関係の知識はさっぱりなく、また音声合成エンジンも使ったことがなかったので、コツを掴むまで何度も音声を作り直しましたが、いったんわかってくると大きな問題は発生しませんでした。

とは言うものの今回の試作品にも微妙なイントネーションな怪しい読み方をしているところが多くありますが。

まとめ

今回の主題は iBooks で再生できる Media Overlays を利用した EPUB3 の作成ではなく、音声合成エンジンで作った朗読音声でオーディオブックの代替は可能かの実験でした。
ただ iPhone や iPad は一定数が普及しており、また iBooks はデバイスに標準的に搭載されているリーディングシステムなので、試作品の再生環境として選択しました。
EPUB3 の仕様通りに再生してくれる環境があれば「サンプル2:ASCANDALINBOHEMIA-voice.epub」で作業は完了しているはずです。iBooks の Fixed Layout モードについてはここで言及はしませんが、Fixed Layout モードは視覚表現を優先したと思われる節があります。

以前からオーディオブックに興味はあったものの知識も少なく、オーディオブックに不可欠な音声を得るのが制作において大きな壁でした。しかし初音ミクに代表される VOCALOID という人格を得た音声合成エンジンの普及と認知、技術的な向上で、人が聴いても違和感の少ない合成音声を作る環境が個人に整ってきたように思えます。
また EPUB3 が  Media Overlays を仕様として盛り込み、スマートフォンを普通の人が持つ状況を創り上げた iPhone、それに続く Android 端末の普及により、汎用的な音声”でも”本を読むことのできる機器を多くの人がそれとは気が付かない内に所持している時代もそう遠くないのではないでしょうか。

最後に「音声付きの本」は必要なの?と疑問を持つ方もいるかもしれません。文字があるなら文字を読むよと思われるかもしれません。もしかしたら「音声付きの本」は今までしなかった読み方をする為のものかもしれません。移動中や他の作業をしている時、音声であれば明かりがなくても読めます、また手を使ってページをめくる必要がないので、寝る前や寝転がっている時に聴くのも良いでしょう。

「本を読む方法に新しい選択肢が増えた」というだけでも、こうした本を作る意味は十分にあるのではないかと思っています。