前回、通信カラオケ用の検索システムを作るために、VHDディスクから拾った楽曲リストの曲名と歌手名にひらがなの読みを追加する作業について紹介しました。今回は、そうやって作った楽曲リストをデータベースに登録して、実際に動作する通信カラオケシステムを作ってみます。
楽曲リストの校正
前回紹介したように、まずはkakasiを使って楽曲リストの曲名と歌手名にひらがなの読みを付けてみました。
kakasiは、SKKプロジェクトが蓄積した辞書ファイル(ひらがなと漢字の対応リスト)を元に、漢字からひらがなの読みを引けるデータベースをあらかじめ用意しておき、与えられた漢字かな混り文をこのデータベースと照合して、マッチする単語があればその読みを返す、という単純な仕組みになっています。
この変換方法はシンプルではあるものの、データベースに登録されている単語の有無によって読みが左右されるという問題があります。たとえば「中島みゆき」という歌手名をkakasiでひらがなに変換すると、「なかしまみゆき」になってしまいます。
この誤変換はkakasiが使っているデータベースに「中島」を「なかじま」と読ませる読みが登録されていないことが原因です。「中島」が無いため、「中島」が「中」と「島」に分解され、「なか」「しま」という読みが返されるため、「なかしまみゆき」になってしまいます。
この問題は、kakasiが利用するデータベースに「中島:なかじま」という読みを登録してやれば解決するものの、データベースに新しい読みを追加するためには、元となった辞書ファイルに必要な読みを追加した上でmkkanwadictコマンドを使ってkakasi用のデータベースを再生成する必要があって、ちょっと面倒です。
そのため人名やグループ名のような固有名詞にはkakasiを使わず、自前で読みを振るような機能を追加してみました。
"ANN"や"ASKA"といった英語表記の歌手名にはそれぞれひらがなの読みを対応させると共に、誤変換が目についた「梶芽衣子」や「千昌夫」といった人名にもそれぞれ適切な読みを対応させています。
やっていることは簡単で、まずは上記のようなset_namedict()関数を用意して、namedict{}に表記と読みの対応リストを登録していきます。
そして、前回紹介したスクリプトで歌手名にふりがなを付ける際、namedict{}にある名前にはkakasiからではなく、対応リストから得られる読みを使うようにしました。
なお、曲目リストに記録した歌手名のアルファベット表記には大文字と小文字の表記揺れがあったので、揺れを吸収するために歌手名はいったん大文字に統一して(50行め)、その上でname_dict{}を引くようにしています。
目につくアルファベット表記や誤変換をnamedict{}に登録してはスクリプトを再実行する、という作業を繰り返して、機械的にひらがなの読みを付けた楽曲リストは完成しました。
歌手名は複数回出てくる可能性があるのでスクリプトレベルで対応した方がいいものの、タイトルの当て字読みやアルファベット表記はたいてい1回限りしか出てこないので、namedict{}に登録して直すよりも出力結果を直接修正する方が楽でしょう。そう考えて、楽曲リストをさらに手動で直していくことにしました。
「ああ、この頃はバンドブームだったなぁ…」「この頃は小室哲也の絶頂期だっけ…」などと追憶にふけりつつ、「めいもなきし(うた)」を「なもなきうた」に直したり、"Forever"に「ふぉーればー」と読みを付けたりする退屈な作業を進めました。
データベースの構築
ひらがな読みを付けた楽曲リストの修正を一通り終えてから、このリストをSQLite3のデータベースに登録するためのPythonスクリプトを書きました。
このスクリプトでは、1行に7つのテキスト形式のコラムを持つSQLite3形式のデータベース("karaoke-titles.sql")を作り、そこにひらがなの読みをつけた楽曲リスト("karaoke-yomi.dat")のデータを流し込んでいます。これくらいの処理ならスクリプトを書くまでもないかな、とも思いましたが、データに修正が必要な場合は楽曲リストに戻って修正し、データベースも再生成することになるので、スクリプト化しておく方が作業をくりかえすには楽でしょう。
スクリプトを使って作成したデータベースを確認するために、シェルからsqlite3コマンドを使って操作してみます。なお、SQLite3の扱うテキストデータはUTF-8形式なので、端末ソフトの文字コードもUTF-8に変更しています。
ざっと見、データベースは正しく作成できているようなので、Web経由でこのデータベースを利用するためのコードを書く段階に移りました。
検索システムの構築
今回考えているお家通信カラオケシステムは、このデータベースを使ってタイトルや歌手名からその曲のID(=ファイル名)を調べ、HTML5の<video>タグを使ってその動画ファイルを再生させる、という単純な仕様です。前々回、<video>タグを使ってブラウザ経由で動画ファイルを再生する部分は考えたので、残りは検索キーワードを入力する画面と検索結果を表示する画面です。
前回紹介したセガカラの検索画面にならって、検索キーワードを入力する画面は、フリーワード入力、あるいは五十音表から歌手名やタイトルの1文字目を入力する、という構成にしてみました。
見ての通りのシンプルな画面構成で、PHPのコードにして140行弱、多少考えたのは五十音表を組むあたりで、PHPの2次元配列にいれた五十音を、<table>の中に入れ子状にして、清音と濁音を横に並べる、という形にしてみました。参考までにコードの前半部分を紹介しておきます。
このページではタイトルの読みから引くか歌手名の読みから引くかをkindという引数に、検索すべきキーワードをkeyという引数に収めて、search.phpを呼び出します。search.php の処理は50行弱なので全文を紹介しておきましょう。
10行目からのDBconnect()関数でSQLite3データベースに接続し、21行目からのquery_db()関数で
のようなSQL文を作ってデータベースを検索し、その結果を$result[]という配列に入れて返します。$result[]には見つかった曲のID(=ファイル名)とタイトル等の情報が入っているので、44行目からのループでそれらを表示します。
それぞれの検索結果には、動画ファイルを再生するためのリンクを張っており、再生したいタイトルをクリックすればブラウザから目的の楽曲が再生されます。
ちなみに動画ファイルを再生するplay.phpは20行ほどのコードです。
当初は、結構な規模が必要かな、と思っていたものの、最近のPHPやHTML5を使うと、「お家通信カラオケシステム」に必要な最低限の機能は、200行ちょっとのコードで実現できるようです。とりあえず動くシステムはできたので、今後は機能の追加や動画ファイルの変換作業を進めていくことになるでしょう。
今回、コードやデータを玩(もてあそ)んでいてあらためて感じたのは、漢字やひらがな、カタカナに加えて、アルファベットまで貪欲に飲み込む、日本語の表記システムの柔軟さです。
"Forever"を「フォーエバー」と表記するか、英語のまま表記するか、あるいは「永遠」や「永久」という漢語を使うか、そこに「とわ」や「とこしえ」という和訓を付けるか、それぞれの表記によって喚起されるイメージは異なるでしょう。「世界最短の文学」と呼ばれる俳句や短歌は、このような日本語の柔軟性を最大限に活用した芸術です。
いっぽう、このような表記の柔軟性はコンピュータで処理する際には足枷ともなります。今回は「キーワードにひらがなで読みを振る」という力技で切り抜けたものの、データの規模が増えると、そのような処理では追い付かなくなるでしょう。日本語の持つ柔軟性やイメージ喚起力を保ちつつ、コンピュータで効率よく扱うにはどうすればいいか、そこには文字コードや正書法を越えた課題があるように思います。