Apr 15 2003

Oh my – now the TV is speaking to me ..

A few days ago (see: TiVo + Home Media Option + EMail) we went through a little exercise to have the TiVo (with Home Media Option installed) display “images” for all current emails on a POP3 server. This worked fine and was a nice little hack.

Now let’s take that concept to another level.

Besides images, the Home Media Option also allows to send MP3 files from your PC to the TiVo unit – right?

Well, I changed the script from the message referenced above to use the Microsoft Speech Object Library (version 5.0; which was installed on my Windows XP Professional system) to “render” the first few lines (PREVIEW_LINES) of each email to a temporary WAV file. After the email has been “recorded” in the WAV file I use a command-line WAV to MP3 converter to turn the file into a file the TiVo unit can understand. If we create the file successully, we moved it into an area that can be “seen” by the TiVo Media Desktop (D:\MP3\TiVo).

Besides perl (see: http://www.activestate.com/Products/ActivePerl/), you will need the Microsoft Spech Object Library on your system and you will need access to a command line MP3 encoder. I’ve picked “bladeenc” for this purpose. You will need to google it or use a different mp3 encoder. The line were the encoder is called, is marked in italic below.

And here is the script that does it all:


use strict; use Cwd; use File::Copy; use File::Path; use File::Spec; use Mail::POP3Client; use Mail::Internet; use LWP::Simple; use Win32; use Win32::OLE; use Win32::OLE::Const qq{Microsoft Speech Object Library};
use constant DESTINATION => q{D:\MP3\TiVo}; use constant PREVIEW_LINES => 30;
my @accounts = ( { DESC => q{thoellri@foobar.com}, USER => "thoellri", AUTH_MODE => "PASS", PASSWORD => "password", HOST => "pop3.foobar.com" }, { DESC => q{tobias@somewhere.com}, USER => "tobias", AUTH_MODE => "PASS", PASSWORD => "password", HOST => "mail.somewhere.com" }, );
for my $account (@accounts) { # erase existing messages rmtree([ File::Spec->catfile(DESTINATION, qq{Email}, $account->{DESC}) ], 0, 0); my $pop = new Mail::POP3Client (%$account); unless ($pop) { warn "Couldn't connect\n"; next; } my $count = $pop->Count; if ($count <0) { warn "Authorization failed"; next; } next if($count == 0); # no new messages # create new directory for messages mkpath([ File::Spec->catfile(DESTINATION, qq{Email}, $account->{DESC}) ], 0, 0711); for my $num (1..$count) { my @preview=$pop->HeadAndBody($num,100); my $mail=Mail::Internet->new(\@preview); my $mp3file=mail2mp3($mail); next unless defined($mp3file); my $out=File::Spec->catfile(DESTINATION, qq{Email}, $account->{DESC}, qq{message-}.sprintf("%02d",$num).qq{.mp3}); copy($mp3file,$out); unlink($mp3file); } $pop->Close; }
sub mail2mp3 { my($m)=@_; my $header=$m->head();
my $type=Win32::OLE->new('SAPI.SpAudioFormat'); $type->{Type}=SAFT32kHz16BitMono; my $stream=Win32::OLE->new('SAPI.SpFileStream'); $stream->{Format}=$type; $stream->Open("output$$.wav",SSFMCreateForWrite,undef); my $speech=Win32::OLE->new('SAPI.SpVoice'); $speech->{AudioOutputStream}=$stream; $speech->Speak(qq{From: }.$header->get('From'),SVSFDefault); $speech->Speak(qq{Subject: }.$header->get('Subject'),SVSFDefault); my($lines); foreach my $line (@{$m->body()}) { chomp($line); $speech->Speak($line." ",SVSFDefault); last if($lines++ >= PREVIEW_LINES); } $speech->WaitUntilDone(-1); $stream->Close(); return undef unless (-f "output$$.wav");
# here we call out to the command line mp3 encode system(qq{bladeenc -quiet -nocfg -quit output$$.wav output$$.mp3});
unlink(qq{output$$.wav}); return undef unless (-f "output$$.mp3"); return File::Spec->catfile(getcwd,qq{output$$.mp3}); }

Again, let me know if you have questions about this stuff …

2 Responses to “Oh my – now the TV is speaking to me ..”

  • a friend of jouke Says:

    You could’ve saved yourself some trouble
    if you were smart and used CPAN 😉

    use Win32::MSAgent;


  • Tobias Hoellrich Says:

    I am smart and I did use CPAN and I did look at Win32::MSAgent, but did not find an obvious way to generate a 32KHz/16Bit WAV output instead of listening to the spoken words. Instead of installing Win32::MSAgent, trying to understand the source, modifying it and then only using 5% of it’s functionality, I decided to just code the 20 lines that do what I want them to do.

    Thanks “friend of jouke” …

Leave a Reply