#!/usr/bin/perl -w #author: Chris Sincock #This software is provided as-is and is not guaranteed to be free of defects. Use it only at your own risk. use strict; #BEGIN { push(@INC,$ENV{"HOME"}."/perl","/home/lasagne/perl"); } #use lib $ENV{HOME}."/pgpanel2/perl"; my $mydvb="/usr/local/bin/mydvb.pl"; my $smydvb="/usr/local/sbin/smydvb.pl"; my %settings=(); my $progname=$0; $progname =~ s:.*/::g; my $pdir=$ENV{HOME}."/.$progname/"; my $pfile="$pdir/settings"; my $true=1; my $false=0; my $recdir=$ENV{HOME}."/tvrec/"; my $gui=$false; my $panel=undef; my $channels="sbs|abc|seven|nine|ten"; my $services="hd|sd|radio|epg|dump"; my $ltime=0; #modification date of settings file at loading time; my $nobg=0; $SIG{CHLD}='IGNORE'; sub getMiniPanel() { return $panel; } sub gui() { $gui=1; $panel=undef; print "Defining panel\n"; my @paneldeflines=split("\n", <<'#ENDPANELDEF'); #run like: minipanel %: print "***************starting*******************\n"; #%: do '/home/frob/bin/menc_tv_lib.pl'; %: #&starttv; %: print "***************started tv*******************\n"; #start xawtv begin=`print "begin\n";` #configuration %orient=h #%gtkrc=/usr/share/themes/ThinIce/gtk-2.0/gtkrc #%gtkrc=/usr/share/themes/BHgtk/gtk/gtkrc %gtkrc=/home/frob/.dvb-tv/gtkrc #%gtkrc=/usr/share/themes/BHgtk/gtk/gtkrc #%gtkrc=/usr/share/themes/BHgtk/gtk/gtkrc #%gtkrc=/usr/share/themes/BHgtk/gtk/gtkrc %decorations=0 %pos=0,0 %title=tv:dvb control=zapping -c procid=`$$` uid=``id -nu`` home=/home/frob vconf=$home/vid/.tvconfig #buttons follow Rec,%&main::startrec(); STOP,%&main::userstop(); Play,%&main::play(); cur,%&main::playcur(); last,%&main::playlast(); " " %value:curtp "-" %value:curserv " " Mute,%&main::mute("toggle"); D1,%&main::screen("monitor"); D2,%&main::screen("tv"); Wide,%&main::aspect("wide"); #wide 4:3,%&main::aspect("pal"); #PAL -,%&main::aspect("pal-"); #shift pal to right +,%&main::aspect("pal+"); #shift pal to left " HD ",%&main::setpref("curserv","hd"); " SD ",%&main::setpref("curserv","sd"); " " #Restart,%&main::restartprog; " " " " " ABC: ",%&main::setpref("curtp","abc");&main::restartaction(); " P ",%&main::play("abc"); " R ",%&main::rec("abc"); " " " Seven: ",%&main::setpref("curtp","seven");&main::restartaction(); " P ",%&main::play("seven"); " R ",%&main::rec("seven"); " " " Nine: ",%&main::setpref("curtp","nine");&main::restartaction(); " P ",%&main::play("nine"); " R ",%&main::rec("nine"); " " " " " Ten: ",%&main::setpref("curtp","ten");&main::restartaction(); " P ",%&main::play("ten"); " R ",%&main::rec("ten"); " " " SBS: ",%&main::setpref("curtp","sbs");&main::restartaction(); " P ",%&main::play("sbs"); " R ",%&main::rec("sbs"); " " "**" %value:state "**" " Quit ",%&main::exiting() && exit(0); #%value:filedesc #"::" #%value:spaceleft # cpu: #%value:cpu #%timer:2000:%perl:&main::checkRecording();return 1; #%timer:30000:%perl:&main::killUnkilled();return 1; %timer:10000:%perl:&main::updateLabels();return 1; #ENDPANELDEF my @paneldef = map { $_ =~ s/^\s*//; $_; } @paneldeflines; #get rid of spaces use csincock::Gnome; use csincock::Minipanel; use csincock::Gtk; csincock::Gtk->init; #csincock::Gnome->init("$appName"); $panel=new csincock::Minipanel(); print "\n**\nShowing Panel\n"; $panel->build(@paneldef); $panel->show; #$panel->showsub("settings",$false); #$panel->showsub("cropping",$false); &updateLabels; Gtk->main; } sub main() { use strict; use csincock::PrefsFile; my $appName=$0; $appName =~ s|.*/||g; $appName =~ s/.pl$//; #&init(); my $needsave=$false; for my $arg (@ARGV) { if($arg =~ /^[-@=:]/) { # if($arg =~ /^@([0-9:hms]+)$/) # { # $starttime=&timetill($1); # } # elsif($arg =~ /^:([0-9:hms]+)$/) # { # $duration=×pec($1); # } # if($arg =~ /^-(debug|d)$/) # { # $debug=1; # } if($arg =~ /^-nobg$/) { $nobg=1; } elsif($arg =~ /^[-]*gui$/i) { &gui; } else { print STDERR "unrecognised command line arg:$arg\n"; } next; } my @cmd=split(/\s+/,$arg); my $larg=lc($arg); if(@cmd && $cmd[0] =~ /^(play|rec)$/i) { &action(@cmd); } elsif($arg eq "stop") { &stop; } elsif($larg eq "cur") { &playcur(); } elsif($larg eq "status") { my $stat=&curstatus; my $curtp=&getpref("curtp"); my $curserv=&getpref("curserv-$curtp"); $stat = $curtp." - " . $curserv . " - " . $stat; system("pgprompt tell MESSAGE='$stat' &") } elsif($larg eq "last") { &playlast(); } elsif($arg =~ /^fpal|pal|wide/i) { &aspect(lc($arg)); $needsave=$true; # &restartplay; } elsif($arg =~ /^tv|monitor$/i) { &screen(lc($arg)); $needsave=$true; } elsif($larg =~ /^$channels$/i) { &setpref("curtp",lc($arg)); # &restartaction; $needsave=$true; } elsif($arg =~ /^$services$/i) { my $curtp=&getpref("curtp"); &setpref("curserv-$curtp",lc($arg)); # &restartaction; $needsave=$true; } elsif($arg =~ /^($channels)-($services)$/i) { &setpref("curtp",$1); &setpref("curserv-$1",$2); } elsif($arg =~ /^restart$/i) { &restartaction; } else { print STDERR "Unknown argument: $arg\n"; } } if($needsave) { &savesettings; } } ###################################### ###################################### sub play() { &action("play",@_); } sub playrec() { &action("playrec",@_); } sub rec() { &action("rec",@_); } sub stop() { print STDERR "KILLING dvbstream!\n"; my $sudo="sudo "; system("killall -TERM dvbscan"); system("ps -wef|grep -i dvbstream|grep -v grep"); print STDERR "TERM\n"; system("$sudo/bin/killall -TERM dvbstream"); system("ps -wef|grep -i dvbstream|grep -v grep"); print STDERR "KILL\n"; system("$sudo/bin/killall -KILL dvbstream"); system("ps -wef|grep -i dvbstream|grep -v grep"); } sub userstop() { #lastaction is the last action done #prevaction is the action before that #so, when the 'stop' action is done, we want to start the #playing again if prevaction was playing #eg, if the user was watching, then hit rec, then stop, # (to stop the recording) it should go back to playing #if(&getpref("prevaction") eq "play") #{ # print STDERR "... playing\n"; # &play; #} #else #{ my $cur=&getpref("lastaction"); my $new="stop"; $new = $cur =~ /pause/i ? "stop" : $cur."pause"; &setpref("lastaction",$new); &stop; &updateLabels; #} } sub stoprecandexit() { print STDERR "caught a signal : stopping and exiting\n"; &stop; exit 0; } sub action() { my ($action,$tp,$serv)=@_; # print STDERR "FUCKOFF"x100;print STDERR "\n".join("','",@_); $action=$action || ''; $tp=$tp || &getpref("curtp"); $serv=$serv || &getpref("curserv-$tp"); $tp=$tp || ''; $serv=$serv || ''; print STDERR "$action $tp $serv\n"; print STDERR "calling 'stop'\n"; &stop; print STDERR "now doing action: $action\n"; &setpref("prevaction",&getpref("lastaction")); &setpref("lastaction",$action); &setpref("curtp",$tp); #&setpref("curserv",$serv); &setpref("curserv-$tp",$serv); my $date=`filename_date`;chomp $date; my $file=""; if($action ne "play") { #TS is used by default, but if the prog is single-definition, #then the VOB extension is used, and the format shoudl be PS #this is so that single definition progs should be playable in a dvd player #which can play files. #The TS is still used for high definition because as far as I can tell #the video data is invalid for the PS format and wont play properly on th #computer OR dvd my $ext=".ts"; if(!($serv =~ /^hd|dump$/i)) { $ext=".vob"; } $file="$recdir/$tp-$serv-$date$ext"; &setpref("lastfile",&getpref("curfile")); &setpref("curfile",$file); $file="'=$file'"; } &setpref("curaction",$action); &setdisp; &setaspect; my $mute=&getpref("mute") =~ /mute/i ? " -mute " : ""; my $eq = &getpref("screen") =~ /tv/i ? "-eq" : ""; my $sudo=""; if($action =~ /rec/i) { $sudo="sudo "; $mute=""; $eq=""; #these are play options, not rec options } my $uid=`id -un`; chomp $uid; my $chown=""; if($uid) { $chown="'-chown=$uid'"; } my $recprog=$sudo?"sudo $smydvb":$mydvb; my $cmd="$recprog $tp $serv $action $mute $eq $chown $file"; $cmd .= $nobg ? " -nobg " : " &"; &savesettings(); print STDERR "sh -c 'DISPLAY= $cmd'\n"; if($nobg) { $SIG{TERM}=\&stoprecandexit; } system($cmd); if($nobg) { print STDERR "nobg flag was given, exiting\n"; exit 0; } sleep 0.3; &updateLabels; if(lc($action) eq "rec") { sleep 1.0; &updateLabels; } } sub playcur() { my $cf=&getpref("curfile"); print STDERR "curfile is $cf\n"; if($cf && -f $cf) { my $ss=0; if(lc(&getpref("curaction")) eq "rec") { $ss=`mplayer-finfo $cf | grep ID_LENGTH | cut -d= -f2`; print STDERR "mplayer-finfo $cf | grep ID_LENGTH | cut -d= -f2\n"; print STDERR "ss=$ss\n"; chomp $ss; $ss=$ss?$ss:0; my $before=5; $ss=$ss<$before?0:$ss-$before; } &playps($cf,$ss); } } sub playlast() { &playps(&getpref("lastfile"),0); } sub aspect() { my ($a)=@_; my $defaultstep=8; if($a =~ /pal[-+]$/) { $a=$a.$defaultstep; } if($a =~ /pal([-+]\d*)$/) { my $offset=&getpref("paloffset") || 0; &setpref("paloffset",$offset+$1); $a="pal"; } &setpref("aspect",$a); &updateLabels; &restartplay(); } sub mute() { my ($arg)=@_; if($arg =~ /toggle/i) { my $cur=&getpref("mute"); $arg= $cur =~ /mute/i ? "" : "mute"; } &setpref("mute",$arg); &updateLabels; } sub screen() { my ($s)=@_; &setpref("screen",$s); } sub killplayer() { my $pid=`cat "$pdir/pid-player"`; chomp $pid; $pid = -d "/proc/$pid" ? $pid : 0; if($pid) { my $real=`cat /proc/$pid/cmdline 2>/dev/null| tr '\0' ' ' | grep really-quiet`; chomp $real; if($real) { system("kill","-TERM",$pid); #system("kill","-KILL",$pid); } } } sub playps() { my ($file,$ss)=@_; &killplayer; if($file) { $ss=$ss ? "-ss $ss" : ""; my $cache = $ss ? "-nocache" : ""; &setdisp; &setaspect; my $mute = &getpref("mute") =~ /mute/i ? " -ao null " : ""; my $eq = &getpref("screen") =~ /tv/i ? "-eq" : ""; system("playps $eq $mute $ss $cache '$file' & echo '\$!' > '$pdir/pid-player'"); } } sub setdisp() { my $scr = &getpref("screen") || "0"; $scr= $scr =~ /tv/i ? 1 : 0; my $disp=$ENV{DISPLAY}; my ($dhost,$dnum,$dscr)= $disp =~ /^([^:]*)(:\d+)(|[.]\d+)$/; print STDERR "dhost=$dhost, dnum=$dnum, dscr=$dscr\n"; my $vdisp = "$dhost$dnum.$scr"; $ENV{VDISPLAY}=$vdisp; } sub setaspect() { my $aspect=&getpref("aspect"); my $poffset=&getpref("paloffset"); $poffset=$aspect =~ /pal/i ? ($poffset==0?"":($poffset>0?"+$poffset":$poffset)) :""; $ENV{VASPECT}= $aspect =~ /pal/i ? $aspect.$poffset : ""; print STDERR "using VASPECT=".$ENV{VASPECT}."\n"; } sub restartplay() { #similar to restartaction except it will only restart if #the action was play my $action=&getpref("lastaction"); print STDERR "lastacstion was: $action\n"; if($action =~ "play") { #stop any current player print STDERR "restarting play\n"; &play; } } sub restartaction() { my $action=&getpref("lastaction"); print STDERR "restarting - lastaction was $action\n"; my $stat=&curstatus; print STDERR "status = $stat\n"; print STDERR "stopping\n"; &stop; my $pacstion = &getpref("prevaction"); if(lc($stat) eq "rec") { print STDERR "restarting rec\n"; &startrec; } elsif($action =~ /play/i || (!$action)) { print STDERR "restarting play\n"; &play; } print STDERR "done\n"; } sub startrec() { my $stat=&curstatus; if($stat && lc($stat) eq "rec") { my $message="You are already recording! Do 'stop' first\n"; print STDERR "$message\n"; if($ENV{DISPLAY}) { system("pgprompt tell MESSAGE='$message' &"); } } else { my $tp=&getpref("curtp"); &action("rec",$tp,&getpref("curserv-$tp")); } } sub exiting() { savesettings(); return 1; } sub restartprog() { &exiting; system(join(" ",$0,@ARGV)." &"); exit 0; } sub getpref() { my ($pname)=@_; my $mod=(stat($pfile))[9]; if($mod > $ltime) { &loadsettings; } return $settings{$pname}; } sub setpref() { my ($pname,$val)=@_; $settings{$pname}=$val; print STDERR "set $pname to $val\n"; } sub loadsettings() { my @lines=`cat '$pfile'`; chomp @lines; $ltime=(stat($pfile))[9]; for my $l (@lines) { my ($name,$val)=split(/=/,$l); $settings{$name}=$val; } } sub savesettings() { print STDERR "saving settings too $pfile\n"; my $str=""; for my $key (keys %settings) { $str .= "$key=$settings{$key}\n"; } if(open(OUTF,">$pfile.new")) { print OUTF $str; close OUTF; my $fs=(stat("$pfile.new"))[7]; if($fs == length($str)) { print STDERR "successfully saved file\n"; system("mv","-f","$pfile.new",$pfile); } } else { print STDERR "Failed saving prefs\n"; } } sub updateLabels() { if($gui) { my $curtp=&getpref("curtp"); getMiniPanel()->setLabel("curtp",$curtp); getMiniPanel()->setLabel("curserv",&getpref("curserv-$curtp")); getMiniPanel()->setLabel("state",&curstatus); } } sub curstatus() { my $proc=`ps -u $ENV{USER} -o "pid,comm" | grep dvbstream | sed '/./ s/^[ ]*//g' | cut "-d " -f1`; chomp $proc; my $pid=$proc; my $of=""; if($pid) { $of=`ls -lL /proc/$pid/fd/1 | cut -c1`; chomp $of; } #my $isrec = my $aspect = &getpref("aspect"); my $offset = &getpref("paloffset"); $offset=$offset>0 ? "+$offset" : ($offset == 0 ?"" : $offset); $aspect= $aspect =~ /pal/i ? "[PAL$offset]":""; my $pact = &getpref("prevaction"); my $lact = &getpref("lastaction"); my $paused = $lact =~ /pause/i; my $pause = $paused ? ($lact =~ /play/i ? "On" : ($lact =~ /rec/i ? "RecPause" : $pact."Pause")) : ""; $proc=$proc?($of eq "p" ? "Play":"Rec"):( $pause || "Off"); #if($pid) { $proc .= " [$pid]"; } if(&getpref("mute") =~ /mute/i) { $proc .= "[Muted]"; } $proc .= $aspect; return $proc; } &loadsettings; &main; =pod my $stoptime=0; if($duration) { $stoptime=$starttime + $duration; } print STDERR $cmd . "\n"; if($starttime) { my $now=&nowsecs; my $tillstart=$starttime - $now; print STDERR "Seconds left till start \n"; if($tillstart >= 0) { if($debug) { print STDERR "sleep $tilstart\n"; } else { sleep $tillstart; } } else { print STDERR "record start time has already passed! reducing duration by $secsleft\n"; } } do { =cut