ゆっくりハイクラジオ
「ゆっくり」で有名なAquesTalkのRubyバインディングが出たというので早速遊んでみました。
AquesTalk/Ruby - Ruby bindings for AquesTalk.
AquesTalkはWindows用ソフトなので今回はWindowsのRuby環境構築から始めました。
WindowsにRubyをインストール
(手順1)One-click Rubyをインストール
以上。
これでRuby1.8.6もirbもrubygemsも一発で入ります。世の中は怖いぐらい便利なものがあるんですね。
ちなみにRailsを一発で入れるInstant Railsは学校のパソコンで利用したことがあります。これもオススメ。
テキストエディタはサクラエディタをインストールしました。Fedoraではemacs使ってます。
AquesTalk Rubyのインストール
AquesTalk/Ruby - Ruby bindings for AquesTalk.
にあるとおり、rubygemsでaqtkパッケージをインストールすれば大丈夫です。これでAquesTalkのdllもインストールされます。
ちょっと喋らせるだけなら
require 'rubygems'
require 'aqtk'
AquesTalk::Da.play_sync('ゆっくりしていってね!!', 100)
でオッケーです。100という第2引数は喋る速度を表しています。
漢字→かな変換のKAKASIも組み込まれているので、ちょっとした漢字も読めます。
再生実行には同期再生と非同期再生があり、上の例は同期再生で、再生終了を待たずに返ってくる非同期再生の方法はAquesTalk/Ruby - Ruby bindings for AquesTalk.に例があります。
ゆっくりハイクラジオ
さて、ソースコード。前に組んだハイクのタイムラインを読むコードを流用してちゃっちゃ(のはずだった)とゆっくりしてみました。機能は3分おきにはてなハイクAPIから取得したパブリックタイムラインのデータを利用して、一番はてなスターの多い投稿の内容をDJゆっくりが読んでくれます。それだけです。
$KCODE = 's' require 'rubygems' require 'aqtk' require 'open-uri' require 'rexml/document' require 'kconv' # はてなハイクAPI参照 PUBLIC_TIMELINE_URI = "http://h.hatena.ne.jp/api/statuses/public_timeline.xml" INTERVAL = 60*3 # 秒 # # YukkuriHR # class YukkuriHR def run_yukkuri_process # INTERVAL毎にゆっくりする loop do begin yukkuri( "私は最終人道兵器ゆっくりDJちゃん、お便りを紹介するよー。" ) parse_timeline_xml yukkuri( make_sentence ) yukkuri( "でわでわ、次もゆっくりしていってね!!" ) rescue => error puts error yukkuri( "エラーですが、あわてるな、孔明の罠だ。" ) end sleep( INTERVAL ) end end # タイムラインのXMLデータを取得、解析 def parse_timeline_xml @data_set = Hash.new # 最終的に読ませるデータが格納される max_stars = -1 # はてなスター数の最高値 timeline_xml = REXML::Document.new( open( PUBLIC_TIMELINE_URI ) ) timeline_xml.elements.each("*/status") do |status| # 現在の星の最高値よりも、現在読み込んでいる投稿の方が星が多いなら各ノードのデータを取り込む。 # url等は削除し、ある程度多い文字数の内容でないと次点を読みにいく。 if ( status.elements["favorited"].text.to_i > max_stars ) keyword = status.elements["keyword"].text content = status.elements["text"].text.split(/=/)[-1] # textの中身が「キーワード名=本文」という形式への対処 content.sub!( /http:\/\/.+/, "" ) # 画像などは改行されるので、http://から改行までを置き換える。超適当。 if ( keyword.split(//s).length >= 1 && content.split(//s).length > 4 ) # キーワードは1文字以上、投稿内容は4文字以上 @data_set[:keyword] = keyword.tosjis @data_set[:content] = content.tosjis @data_set[:name] = status.elements["user/name"].text max_stars = status.elements["favorited"].text.to_i end end end end # お喋りの内容 def make_sentence sentence = "はてな県はてな市のid" + @data_set[:name] + "さんから" sentence << @data_set[:keyword] + "についてのお便りです。" sentence << @data_set[:content] + "だってさ" return sentence end # ゆっくりする def yukkuri( sentence ) AquesTalk::Da.play_sync( sentence, 100 ) end end # # Main # start_comment = <<EOF ピーピーガーガーピーピーガーガー ゆっくりハイクラジオが起動しました。 EOF AquesTalk::Da.play_sync( start_comment, 100) yhr = YukkuriHR.new yhr.run_yukkuri_process
終了はCtrl+Cでプロセス終了シグナルを送ってください。スレッドでコマンド処理をしたかったのだけど、Win32版Rubyは標準入力を受け取るgets等で他のスレッドも止めてしまうみたいですね(なんで動かないの、あれ〜?とプログラムを組んだ倍の時間を費やしてしまいました)。Ruby1.9以降では大丈夫っぽいです(http://arton.no-ip.info/data/Sapporo2008/ASR.pdf)。
課題点
- 1件だけとかケチくさいことは言わず、APIから受け取ったデータを全部表示すればいーじゃん(DJゆっくりが喋らない間が寂しい)。
- やっぱりこういう「人格」を立てるなら、定型文はかっこ悪いってカミナギの中の人も言ってた。
- 超適当と書いてあるところが気がかり。
aqtk使いたいが為に書いただけなので、不安定にも程がありますが、手直しは暇があったらします。メールを音声で読んでくれるのにも需要があるのだし(車内等のハンズフリー環境が必要なだけだが)、twitterやハイクにもそういった機能が流行るといいのになあ。twitterはタイムラインが早すぎて非効率的にはなるのでしょうけどね。
最近のネット界隈での人工無能やbotブームに乗っかって考えると、声を発してくれた方が人間らしさが出るし、人間は突拍子の無い予期せぬ発言を人工無能に期待していると思う。だから音声で喋った上に、読み間違いとかしてくれた方が「人工無能らしさ」が一層引き立つのではないでしょうか。音声言語処理も面白そうだなあとかそんな事をつらうつらと考えてた徹夜明けでした。