ツイートをしゃべらせてみよう。

tags:web, twitter, speech-api
created:2011-06-12T22:00:00

Googleの非公開スピーチAPIで遊んでみた。

あらかじめ必要なもの

mplayerの実行バイナリ

注釈

ubuntuの場合、

sudo apt-get install mplayer

でインストールできまする。

サンプルコード

実行してほっておくと、わたしの新しいツイートのたびにしゃべるアプリです。 別のアカウントのツイートを監視するにはSCREEN_NAMEに指定すればいいです。

# encoding: utf-8

import sys
import os
import time
import json
import urllib
import urllib2
from subprocess import Popen, PIPE

MPLAYER_BIN = 'mplayer'
SPEECH_API = 'http://translate.google.com/translate_tts?tl=%s&q=%s'
TWITTER_API = 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=%s'
USER_AGENT = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; ja-jp) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16'
SCREEN_NAME = 'ssci'

def parse_timestamp(obj):
    st = time.strptime(obj['created_at'], '%a %b %d %H:%M:%S +0000 %Y')
    return time.mktime(st)

def speech(message, skip):
    l = 'ja' if any([ord(c)>127 for c in message]) else 'en'
    message = message.encode('utf-8')
    m = urllib.quote(message)
    print message
    if not skip:
        request = urllib2.Request(SPEECH_API % (l, m))
        request.add_header('User-Agent',USER_AGENT)
        try:
            data = urllib2.urlopen(request).read()
        except:
            print 'fetch fail!'
            return
        proc = Popen([MPLAYER_BIN, '-cache', '256', '-'],
          stdin=PIPE, stdout=PIPE, stderr=PIPE)
        proc.communicate(data)

def main():
    last_req = 0.0
    last_time = 0.0
    skip = True
    while 1:
        diff = (time.time()-last_req)
        if diff<24:
            wait = 24-diff
            print 'wait:', wait
            time.sleep(wait)
        print 'req:'
        last_req = time.time()
        url = TWITTER_API % SCREEN_NAME
        for obj in reversed(json.load(urllib2.urlopen(url))):
            tm = parse_timestamp(obj)
            if last_time>=tm:
                continue
            speech(obj['text'], skip)
            last_time = tm
            if not skip:
                time.sleep(1)
        skip = False

if __name__=='__main__':
    main()

まとめ

ついまるというおもちゃみたいなことをPythonでできないかなと思って作ってみた。

Twitterの制限で一時間に150回以上HTTPリクエスト掛けると弾かれるので、 リクエストから次のリクエストには24秒以上空くようにしてます。

GoogleのSpeech-APIでは字数制限がありそうですが詳しく調べていません。 (なので長めのツイートでは失敗する。)

こんな簡単にしゃべらせられるのはGoogleさんのおかげです。