sub config { open(FILE,"dvr.conf"); @lines = ; close(FILE); # Set some defaults $DVR{'log'} = "dvr.log"; $DVR{'schedule'} = "schedule.txt"; foreach $line (@lines){ $line =~ s/\#(.*)$//g; if($line){ ($opt,$value) = split(/\t/,$line); $value =~ s/[\n\r]//g; if($value){ $DVR{$opt} = $value; } } } } sub getSchedule { local($schedule_file,$i,$num,$j); $schedule_file = $_[0]; if(!$schedule_file){ $schedule_file = "/tmp/freevo_record.lst"; } my @progs,$prog; my $r_str1,$r_str2,@rest,$s_yr,$s_mon,$s_day,$s_time,$r_last,$r_cmd,$s_hr,$s_min,$s_sec; my $custom,$cmmd; # Get current time my ($sec,$min,$hour,$mday,$mon,$year,$wday,@yday); ($sec,$min,$hour,$mday,$mon,$year,$wday,@yday) = (localtime(time))[0,1,2,3,4,5,6,7]; my @days = ('SUNDAY','MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY','SATURDAY'); my @months = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); my $time_now,$time_start,$time_end,$diff_start,$diff_end; my $tmpfile; $mon++; # Make Jan=1, Feb=2 etc. if($year < 1900){ $year += 1900; } open(FILE,$schedule_file); @progs = ; close(FILE); # Rearrange lines so we can sort by filename @newlines = ""; foreach $prog (@progs){ if($prog !~ /^\#/ && $prog){ ($date,$timelast,$chnum,$file,$channel) = split(/\s/,$prog); push(@newlines,"$file $date $timelast $chnum $channel\n"); } } @progs = sort(@newlines); foreach $prog (@progs){ if($prog =~ /^\#/ || !$prog){ next; } ($file,$date,$timelast,$chnum,$channel) = split(/\s/,$prog); $prog = "$date $timelast $chnum $file $channel"; ($r_str1,$r_str2,@rest) = split(/\s/,$prog); ($s_yr,$s_mon,$s_day) = split(/\-/,$r_str1); ($s_time,$r_last,$r_cmd) = split(/\,/,$r_str2); ($s_hr,$s_min,$s_sec) = split(/\:/,$s_time); $time_now = &timeinseconds(0,$min,$hour,$mday,$mon,$year)+0; $cmmd = ""; $extra = 0; if($prog =~ /PERLDVR/){ $custom = 1; if($r_cmd =~ /\{EVERY([^\}]*DAY)\}/){ $cmmd = $1; $s_day = $mday; $s_mon = $mon; $s_yr = $year; $time_start = &timeinseconds(0,$s_min,$s_hr,$s_day,$s_mon,$s_yr)+0; $time_end = $time_start + $r_last; if($cmmd eq "DAY"){ if($time_end < $time_now){ $extra = 86400; } }elsif($cmmd eq "WEEKDAY"){ if($wday == 0){ $extra += 86400; } elsif($wday == 6){ $extra = 2*86400; } else{ if($time_end < $time_now){ if($wday == 5){ $extra = 3*86400; } else{ $extra = 86400; } } } }else{ # FIND OUT WHICH DAY RECORDING SHOULD START $rday = $wday; for($j = 0 ; $j < 7 ; $j++){ if($days[$j] =~ /$cmmd/){ $rday = $j; } } $rday = $rday - $wday; if($rday == 0){ if($time_end < $time_now){ $extra = 7*86400; } }elsif($rday < 0){ $extra = ($rday+7)*86400; } else{ $extra = ($rday)*86400; } } }else{ $time_start = &timeinseconds(0,$s_min,$s_hr,$s_day,$s_mon,$s_yr)+0; } }else{ $custom = 0; # Correction for Freevo time mistake $s_hr = $s_hr - 2; if($s_hr < 0){ $s_hr += 24; } $time_start = &timeinseconds(0,$s_min,$s_hr,$s_day,$s_mon,$s_yr)+0; } $time_start += $extra; $time_end = $time_start + $r_last; # Add overrun to Freevo set programmes so we don't lose the end if($prog !~ /PERLDVR/){ $time_end = $time_end + 2; } $diff_start = $time_start - $time_now; $diff_end = $time_end - $time_now; if($custom){ $record{"channel"} = $rest[0]; $record{"file"} = $rest[1]; # If we want to keep it give it a timestamp filename if($r_cmd =~ /\{KEEP\}/){ $date = &formatDate("\_",$s_yr,$s_mon,$s_day); $record{"file"} =~ s/(\.avi)$/\_$date$1/; } }else{ $rest[1] =~ /channel\=(\d\d)/; $record{"channel"} = $1; $record{"file"} = $rest[13]; $record{"chname"} = $rest[14]; $record{"file"} =~ s/^(.*\/)([^\/]*)$/$1/; $tmpfile = $2; $tmpfile =~ s/^(.*)\-([^\-]*)$/$2/; $tmpfile =~ s/^\_//; $date = &formatDate("\_",$s_yr,$s_mon,$s_day); $tmpfile =~ s/(\.avi)/\_$date$1/; $record{"file"} = $record{"file"}.$tmpfile; } # $record{"file"} =~ s/(\_)(\d)([\_\.])/\_0$2$3/g; # if($diff_end > 0){ # if(1){#$schedule[$i]{'file'}){ $schedule[$i]{'channel'} = $record{'channel'}; $schedule[$i]{'file'} = $record{'file'}; $schedule[$i]{'chname'} = $record{'chname'}; $schedule[$i]{'every'} = $cmmd; $schedule[$i]{'time'} = $s_hr.":".$s_min; $schedule[$i]{'date'} = $s_day." ".$months[$s_mon-1]; $schedule[$i]{'lasts'} = $r_last; $schedule[$i]{'start'} = $time_start; $schedule[$i]{'end'} = $time_end; $schedule[$i]{'diff_start'} = $diff_start; $schedule[$i]{'diff_end'} = $diff_end; $schedule_order[$i] = $time_start."_".$i; $i++; # } } return ($i-1); } sub updateSchedule { local(@lines,$line,$templine,@newlines,$newline,$newdate,$newtime); @newlines = ""; if(-e $DVR{'listings'} && -e $DVR{'schedule'}){ open(FILE,"$DVR{'schedule'}"); @lines = ; close(FILE); foreach $line (@lines){ if($line =~ /PERLDVR/ && $line =~ /VARIABLE/){ # need to open listings file here $line =~ /([^\s]*)\s([^\,]*)\,([^\,]*)\,(.*)/; push(@newlines,"$newdate\s$newtime\,$3,$4"); }else{ push(@newlines,$line); } } } } sub startRecording { # Kill already running TV so we can record local($channel,$file,$sec,$min,$hour); if($_[0]){ $channel = $_[0]; } else{ $channel = $record{'channel'}; } if($_[1]){ $file = $_[1]; } else{ $file = $record{'filename'}; } $pid = &getPID($DVR{'play'}); while($pid > 0){ &addLog(">\tKILLING $PROCESS{'play'} with $pid first\n"); &killIt($DVR{'play'}); $pid = &getPID($DVR{'play'}); } $cmdline = "/usr/local/bin/mencoder -tv on:driver=v4l:width=768:height=576:channel=$channel:chanlist=europe-west -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=350:vhq:vqmax=31:keyint=300 -oac mp3lame -lameopts cbr:br=48 -vop scale=384:288,pp=tn/lb,crop=720:540:24:18 -sws 1 -o $file"; $cmdline = "perl record.pl $channel $file"; ($sec,$min,$hour) = (localtime(time))[0,1,2]; &addLog("> ".&formatDate(":",$hour,$min,$sec)." RECORDING $file $channel\n"); system ($cmdline); return 1; } sub timeinseconds { # Here we run the system 'date' command as there was a # problem with the script quitting when this was done by Perl. @t = @_; my @months = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); # Correct months $t[4] = $t[4] - 1; if($t[4] < 0){ $t[4] = $t[4] + 12; } if($t[5] < 1900){ $t[5] += 1900; } if(length($t[3]) < 2){ $t[3] = "0".$t[3]; } if(length($t[2]) < 2){ $t[2] = "0".$t[2]; } if(length($t[1]) < 2){ $t[1] = "0".$t[1]; } my $date1 = `date -d \"$months[$t[4]] $t[3] $t[2]:$t[1]:00 $t[5]\" \+\%s`; #print LOG "> TIME: $t[1] $t[2] $t[3] ".$months[($t[4])]." $t[5]\n"; return ($date1); } sub killIt { # This kills the specified process id. # killIt(pid) local($name,$attempts,$pid); $name = $_[0]; $attempts = 0; $pid = &getPID($name); while($pid > 0){ if($attempts < 5){ `kill $pid`; $attempts++; $pid = &getPID($name); }else{ &addLog(">\tSERIOUSLY ATTEMPTING TO KILL PROCESS $pid\n"); `kill -9 $pid`; $pid = &getPID($name); if($pid > 0){ &addLog(">\tFAILED TO KILL PROCESS $pid\n"); return 1; } } } return 0; } sub getPID { # Get process ids so that e.g. we could kill them # Usage: getPID("process name") my($name,$line,@lines); $name = $_[0]; @lines = `ps -x`; $exists = ""; foreach $line (@lines){ if($line =~ /$name/ && !$exists){ $exists = $line; } } if($exists){ # remove excess spaces while($exists =~ / /){ $exists =~ s/ / /g; } # remove space at start of line $exists =~ s/^ //g; # split by spaces ($pid,@rest) = split(/ /,$exists); if($pid){ return $pid; } } return 0; } sub formatDate() { # Formats the date using specified delimiter # Usage: formatDate("/",31,12,2003) local($delim,$date1,$date2,$date3,$output); $delim = $_[0]; $date1 = $_[1]; $date2 = $_[2]; $date3 = $_[3]; # Pad with zeros if necessary if(length($date1) < 2){ $date1 = "0".$date1; } if(length($date2) < 2){ $date2 = "0".$date2; } if(length($date3) < 2 && $date3){ $date3 = "0".$date3; } $output = $date1.$delim.$date2; if($date3){ $output .= $delim.$date3; } return $output; } sub addLog() { # Add a line, passed as an argument, to the log file # Usage: addLog("Text that gets saved to the log") local($line); $line = $_[0]; if($DVR{'log'} && -e $DVR{'log'}){ open(LOG, ">>$DVR{'log'}"); print LOG $line; close(LOG); } } 1;