Saturday, 28 March 2009

Twitter to Speech in Java

During the working day I glance at Twitter quite a lot to see what folk are saying. I'd personally rather have it talk to me instead, if something interests me then I can go looking on the website.

(Now I know mobiles do text to speech well already, this was more of a basic exercise to see how easy it would be in Java).

First of all we need some Tweets.
public class TwitterSpeech {
public TwitterSpeech(String username, String password){
Twitter twitter = new Twitter(username, password);
List messages = twitter.getFriendsTimeline();
for(Status s : messages){
System.out.println(s.getUser());
System.out.println(s.getText());
}
tv.closeVoice();
}
}


The Winterwell JTwitter API works really well for what we need and I don't see the point of overcomplicating the matter by reading JSON and Atom feeds. So, a username and password are passed to the method and the getFriendsTimeline() method pulls the last 20 Tweets in the timeline.

Now for some speech.

The FreeTTS project is on Sourceforge and provides a nice way to get text to speech in short space of time. Here there is another class that sets up the voice synth and gives a way of passing a text message to it to be processed.

public class TweetVoice{
VoiceManager voiceManager = null;
Voice helloVoice = null;

public TweetVoice(){
voiceManager = VoiceManager.getInstance();
helloVoice = voiceManager.getVoice("kevin16");
helloVoice.allocate();
}
public void closeVoice(){
helloVoice.deallocate();
}

public void speakTweet(String message){
helloVoice.speak(message);
}
}

Kevin16 is the voice set to be used, a bit robotic but fine for our needs. So now, back in our original code segment, it's just a case of plumbing in the speech synth and passing tweets to it.

public class TwitterSpeech {
public TwitterSpeech(String username, String password){
TweetVoice tv = new TweetVoice();
Twitter twitter = new Twitter(username, password);
List messages = twitter.getFriendsTimeline();
for(Status s : messages){
System.out.println(s.getUser());
System.out.println(s.getText());
tv.speakTweet(s.getUser() + " said " + s.getText());
}
tv.closeVoice();
}

public static void main(String[] args){
TwitterSpeech ts = new TwitterSpeech("myusername", "mypassword");
}
}

It's plain and it's simple but it works rather well and has scope for a few other applications. If you wrapped a Quartz Scheduler or a mechanism to retrigger a thread then you could leave it run and grab new tweets for you. This example will always grab the most recent 20 tweets for you, it would be easy to modify the code and get the most recent tweets by id or date.

No comments: