#!/usr/bin/perl use strict; use warnings; use DBM::Deep; use Net::TiVo; my $mak = '...'; my $tivo = Net::TiVo->new( host => '10.0.1.9', mac => $mak, ); my $ua = make_ua(); chdir( "...." ); my $db = DBM::Deep->new( '....' ); for my $folder ( $tivo->folders ) { print "Folder: ", $folder->as_string, "\n"; foreach my $show ( $folder->shows ) { next unless $show->name =~ /..../i; if( exists $db->{ $show->program_id } ) { print "Skipping '" , $show->episode, "'\n"; next; } print show_summary( $show ); fetch_show( $ua, $show ); $db->{ $show->program_id }++; } } sub make_ua { require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->credentials( '10.0.1.9:443', "TiVo DVR", "tivo", $mak ); $ua->credentials( '10.0.1.9:80', "TiVo DVR", "tivo", $mak ); $ua->cookie_jar( {} ); return $ua; } sub fetch_show { my( $ua, $show ) = @_; my $url = $show->url . "&Format=video/x-tivo-mpeg"; my $file = $show->episode . ".TiVo"; print STDERR "My file is $file\n"; my $start = time; my $response = $ua->get( $url, #":content_cb" => sub { my($d, $r, $p ) = @_; print Dumper( $d, $r->as_string) }, ":content_file" => $file, ); my $end = time; next unless -e $file; my $diff = $end - $start; print STDERR "Download time was $diff seconds: ", $show->size / $diff, " bytes/s\n"; unless( -s $file != $show->size ) { print STDERR "$file does not have the right size"; unlink $file; return; } tivo_decode( $file ); } sub show_summary { my $show = shift; my $string; $string = "\t" . $show->name . "\n"; $string .= "\t" . $show->url . "\n"; $string .= "\tprogram: " . $show->program_id . "\n"; $string .= "\tepisode: " . $show->episode . "\n"; $string .= "\tseries: ". $show->series_id . "\n"; $string .= "\tsize: ". $show->size . "\n"; $string .= "\n"; return $string; } sub tivo_decode { my $file = shift; ( my $output = $file ) =~ s/\.TiVo$/.mpeg/; unless( my $pid = fork ) { #child print "Exec-ing tivodecode\n"; exec qq|/usr/local/bin/tivodecode -m $mak -o "$output" "$file"|; die "Could not exec tivodecode!"; } else { #parent return; } }