« Twitterクライアントをつくる7 | トップページ | スゴロクっぽいゲームをつくる1 »

2011年5月22日 (日)

Twitterクライアントをつくる8

またまたTTSを探していたところ、まあ今更なネタなのかもしれませんがGoogleで音声合成を提供していました。非公式ながら情報がいくつか出回っていたので参考にして、ついーとをGoogleのTTSで読み上げるようにしてみます。

2011/05現在ではGoogle翻訳でTTSの機能を利用することができますがAPIは公開されておりません。ですので今回使用する方法では今後動作するかどうか不明です。

取り敢えずコレを利用したgemが無いかどうか検索してみるとspeakというのがありました。早速インストールしてみようと思いましたが、オーディオファイルの再生にGstreamerというライブラリを使用しているようです。

GstreamerはGNOMEプロジェクトのライブラリなのですが、mingwでコンパイルするのがかなり厄介というか、mkmfを使用するgemでヘッダ等が検知されないようで、あるはずのファイルが無いと判定されて先に進めないというよく分からない状況になってしまったのでこちらは諦めて、ソースコードだけ参考にしてオーディオファイルの再生は別の方法を考えることにしました。

Googleの非公式APIでは音声ファイルをmp3で返すのでffmpegでwavフォーマットに変換してWxRubyのSoundで再生するようにしてみようかな、と一旦組んでみたがffmpegでwhichコマンド実行時にコケたり、Soundが再生中かどうか評価するメソッドがなかったりで諦める。whichコマンドがコケる辺りがmkmfの問題と絡んでいそうであるが原因追及が長引いたのでやめてGstreamerは今回はパス。

クロスプラットフォームで使えそうかなと思っていたのだが、その思惑は外れてしまった。

gemを調べてみると意外とオーディオ周りのモノが無い。標準的なクロスプラットフォームのマルチメディアなライブラリがない。でも、こんなイベントやっているぐらいだから、そのうち標準的な組み込みライブラリができるに違いない。そうだろMatz。

おっと、馴々しいな。話題を戻そう。
ゲームをつくろうと思っていたし、ゲーム関連ならこういった機能も当然提供されているはずなので調べてみるとありました。今回はGosutというライブラリを使ってみます。

gem install gosu -r

オーディオ関連のメソッドがシンプルすぎてチュートリアルもほとんど無いのですが、勘でサクっと動いたのでコレを使用して再生することにします。

今回追加分の流れとしては、

  1. ついーとを取得
  2. GoogleのTTSでmp3に変換
  3. mp3を再生
  4. 再生が終わったら、残りのツイートがあれば最初に戻る

リロードの際にキューにツイートを貯めて、スレッドで順次読み上げていくことにしました。

  1.     # Speech tweet
  2.     thd = Thread.start do
  3.       while (tweet = tweet_queue.pop )
  4.         @speech.say(tweet)
  5.         while (@speech.is_say?)
  6.           sleep(1)
  7.         end
  8.       end
  9.     end if @tts_func

speakや他の情報を参考に、再生部分は新しいClassを作成してみた。

  1. # coding: utf-8
  2. begin
  3.   require 'rubygems'
  4. rescue LoadError
  5. end
  6. require 'open-uri'
  7. require 'gosu'
  8. require 'singleton'
  9.  
  10. class WTC_speech
  11.   include Singleton
  12.  
  13.   MP3TEMPFILE = 'temp.mp3'
  14.  
  15.   def initialize
  16.     @sound = nil
  17.   end
  18.  
  19.   def get_instance(audiofile = MP3TEMPFILE)
  20.     @sound = Gosu::Song.new(audiofile)
  21.   end
  22.  
  23.   def say(text)
  24.     to_mp3(text)
  25.     get_instance(MP3TEMPFILE)
  26.     speech(MP3TEMPFILE)
  27.   end
  28.  
  29.   def to_mp3(text)
  30.     locale = URI.encode_www_form_component('ja')
  31.     str = URI.encode_www_form_component(text)
  32.     uri = "http://translate.google.com/translate_tts?tl=#{locale}&q=#{str}&ie=utf-8"
  33.     # puts uri
  34.  
  35.     begin
  36.       open(uri) do |stream|
  37.         open(MP3TEMPFILE, "wb") do |f|
  38.           tmp = stream.read
  39.           # p tmp
  40.           f.write(tmp)
  41.         end
  42.       end
  43.     rescue => e
  44.       puts 'to_mp3 method err: ', e, e.backtrace
  45.       puts uri
  46.       exit
  47.     end
  48.   end
  49.  
  50.   def speech(audiofile = MP3TEMPFILE)
  51.     begin
  52.       get_instance(audiofile)
  53.       @sound.play
  54.       # puts ret, audiofile
  55.     rescue => e
  56.       puts 'speech method err: ', e, e.backtrace
  57.       puts audiofile
  58.       exit
  59.     end
  60.   end
  61.  
  62.   def is_say?
  63.     is_speech?
  64.   end
  65.  
  66.   def is_speech?
  67.     @sound.playing? if not @sound.nil?
  68.   end
  69.  
  70.   def stop
  71.     @sound.stop if not @sound.nil?
  72.   end
  73. end
  74.  

@speechに新しく作成したClassのインスタンスを入れる。いつ使えなくなるのか分からない非公式な方法なので適当です。これで日本語ツイートを読み上げてくれる。意外と英単語もちゃんと読み上げてくれる。

嗚呼、TTSもクラウド化するか。
どうやらespeakを使っているようだけど日本語部分は別かもしれない。確かに幾つかのTTSはWeb上でデモが使えるから難しくないのかもしれない。
寧ろ、モバイルデバイスでは地図と組み合わせてナビゲーションとかいろいろなサービス展開が考えられるので当然の流れかもしれない。まあAndroidが同じ仕組を使うのかは分からないが。
うむ、デスクトップのアプリなんか作っている場合ではないのか?

|

« Twitterクライアントをつくる7 | トップページ | スゴロクっぽいゲームをつくる1 »

Twitterクライアントをつくる」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1201593/40080519

この記事へのトラックバック一覧です: Twitterクライアントをつくる8:

« Twitterクライアントをつくる7 | トップページ | スゴロクっぽいゲームをつくる1 »