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:
#!c:\perl\bin\perl.exe
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 …
April 16th, 2003 at 11:17 am
You could’ve saved yourself some trouble
if you were smart and used CPAN
use Win32::MSAgent;
http://search.cpan.org/author/JOUKE/Win32-MSAgent/
April 16th, 2003 at 12:40 pm
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” …