TwitterをSoftalkのゆっくりボイスでしゃべらせる

Softalkのゆっくりボイス 作ってみた
スポンサーリンク
Softalkのゆっくりボイス

(完成動画。時々でてる音は録画用に使ったMacの音です、紛らわしくてごめん。)

2chのスレやしたらば、カキコなどの掲示板をSoftalkで読ませるフロントエンドはあるんだけど、Twitterのタイムラインを読ませるっていうのは見つからなかったので作ってみた。

TwitterのAPIを読むだけなので、スクラッチで書いてもそんなに難しいものではないんだけど、勉強がてらPythonのpython-twitterというライブラリを使ってみる。

追記:新しくエントリーを書きました

TwitterをSoftalkのゆっくりボイスでしゃべらせる 2 | クレコ

python-twitterの導入

実はこれがくそめんどいw

python-twitterまとめ ~導入まで – テックノート@ama-ch
を参考にして導入する。

simplejsonは、WindowsでCのコンパイラ環境が必要になったりする。詳しくないので、書いてある通りに実行していった。

Python 2.6ではhashlibなんちゃらの警告がでます

別にそのままつかっても問題ないけど毎回警告がでるので直し方。

@aoshimanさんに教えていただいた解決法、
2009-02-18 – nakkuの日記 [python]python2.6にtwitterのモジュールを入れる
にpatchがあるので、twitter.pyを書き換えればいい。

具体的には、simplejsonモジュールを使っているところをjsonモジュール、md5モジュールを使っているところをhashlibモジュールを使うようにそれぞれ書き換える。

TwitterのTLをSoftalkでしゃべらせるPythonスクリプト

import twitter, os, nkf, re, time

# config
userName = "username"
passWord = "password"
softalkPath = "C:\hogehoge\softalk.exe"
softalkSpeed = "120"
lastSinceTime = 0
lastGetTime = 0

# convert string
def convertString(string):
    # remove HTML entity
    string = re.sub('&.+;', ' ', string)
    # remove quote
    string = re.sub('"', ' ', string)
    string = re.sub("'", ' ', string)

    # remove my username
    string = re.sub('^@' + userName + ' ', '', string)

    # convert unicode to sjis using nkf module
    string = nkf.nkf("-sX", string.encode("utf8"))

    return string

# get twitter timeline
def getTimeline():
    global lastSinceTime

    api = twitter.Api(userName, passWord)
    statuses = api.GetFriendsTimeline(userName)
    #statuses = api.GetUserTimeline(userName)
    #statuses = api.GetReplies()

    for i in statuses[::-1]:
        if i.created_at_in_seconds > lastSinceTime:
            print "%s : %s" % (convertString(i.user.name), convertString(i.text))
            os.system('"' + softalkPath + '" /V:60 /S:'+softalkSpeed+' /T:1 /W:' + convertString(i.user.name))

            # when find my name and change voice
            if re.search(userName, i.text):
                os.system('"' + softalkPath + '" /V:60 /S:'+softalkSpeed+' /T:0 /W:' + convertString(i.text))
            else:
                os.system('"' + softalkPath + '" /V:60 /S:'+softalkSpeed+' /T:3 /W:' + convertString(i.text))
            lastSinceTime = i.created_at_in_seconds

while True:
    # time span of get timeline
    if time.time() > lastGetTime + 60:
        lastGetTime = time.time()
        getTimeline()
    else:
        time.sleep(5)

twitterモジュール

api = twitter.Api(userName, passWord)

statuses = api.GetFriendsTimeline(userName)

で、認証してタイムライン(ここではFriendTimeline)を取ってくる。

んで、そのリストは時系列昇順にしゃべらせるために、スライスを使って逆順にし、forで回してやる。

osモジュール

os.system(‘”‘ + softalkPath + ‘” /V:60 /S:’+softalkSpeed+’ /T:1 /W:’ + convertString(i.user.name))

外部コマンドでSoftalkを実行する。softalkPathにsoftalk.exeの位置を設定して、あとはパラメータ。つぶやきの中に自分のユーザー名があったら音声を変えたり。

/V:ボリューム、/S:スピード、/T:音声パターン、/W:しゃべらせたいテキスト

Softalkのソフトについては後述。

nkfモジュール

NkfPython – Ma2

Softalkにコマンド引数として値を渡すときに、UnicodeからS-JISへ変換してやる必要があるんだけど、この変換でencode()を使うとウムラウトとかが原因でエラー。

nkfを使えばいいらしいので、nkf使って変換。

string = nkf.nkf(“-sX”, string.encode(“utf8”))

reモジュール

string = re.sub(‘&.+;’, ‘ ‘, string)

HTMLエンティティをそのまま渡すと、コマンド引数が途切れたりしたので、HTMLエンティティはばっさり消しちゃうことにした。re.sub()は正規表現で置き換え。

同様に、先頭に自分のユーザー名が来てるようなreplyメッセージでのユーザー名とか、クォート符号も消す。

他にも何かエラー引き起こす文字があったら、深く考えないで消す。とても適当でごめんなさい。

timeモジュール

実行したら無限ループに入れてやり、前回の取得時間より1分以上経っていたら取得しに行く、それ以外なら5秒スリープしてループの先頭に戻る。

利用するSoftalkのバージョン

実行してみると、Softalkが実行するときにいちいちWindowがピョコンとでてきて、終了をしてあげないと次のつぶやきをしゃべってくれない。

なんか以前と違うなぁって不思議に思っていたんだけど、

ニコニコ動画のニコ生(生で配信)用のツール

NicoRequest Ver.2.3.2 – ExceptionErrorMessage

NicoRequestのドキュメントを読んでみると、どうやらSoftalkの最新バージョンで挙動が変わったらしい。

ver0151に置き換えて実行してみたところ、ちゃんとうまくいって、一番はじめの動画のようにゆっくりボイスでしゃべってくれた。

感想

  • 声でタイムラインを読んでくれるっていうのは新鮮でおもしろいよ
  • Softalkは英語が不得意なので、無理にローマ字読みして何いってるかわからないことしばしば
  • 移動体ライブ配信の読み上げに使おうとおもったけど、よく考えると60秒更新スパンくらいが負荷で限界なので、ものすっごくタイムラグ発生するかもね
  • PythonよりもNicoRequestみたいにJavaScriptで実現したほうがいいかも
  • SoftalkとそのライブラリAques TalkはWindows版でしか無償でつかえないので、環境を選ぶ

つぶやきを送ると、ゆっくりボイスで変換してくれるBOTとか作ったら面白そう。

タイトルとURLをコピーしました