Index: trunk/install/perl/foltialib.pl =================================================================== --- trunk/install/perl/foltialib.pl (リビジョン 124) +++ trunk/install/perl/foltialib.pl (リビジョン 1) @@ -4,5 +4,5 @@ $path = $0; $path =~ s/foltialib.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -13,37 +13,18 @@ use DBI; use DBD::Pg; -use DBD::SQLite; -use POSIX qw(strftime); - -$DSN=$main::DSN; + + + $DBDriv=$main::DBDriv; + $DBHost=$main::DBHost; + $DBPort=$main::DBPort; + $DBName=$main::DBName; $DBUser=$main::DBUser; $DBPass=""; - - $FILESTATUSRESERVINGLONG = 10; - $FILESTATUSRESERVINGSHORT = 20; - $FILESTATUSRECORDING = 30; - $FILESTATUSRECTSSPLITTING = 40; - $FILESTATUSRECEND = 50; - $FILESTATUSWAITINGCAPTURE = 55; - $FILESTATUSCAPTURE = 60; - $FILESTATUSCAPEND = 70; - $FILESTATUSTHMCREATE = 72; - $FILESTATUSWAITINGTRANSCODE = 80; - $FILESTATUSTRANSCODETSSPLITTING = 90; - $FILESTATUSTRANSCODEFFMPEG = 100; - $FILESTATUSTRANSCODEWAVE = 110; - $FILESTATUSTRANSCODEAAC = 120; - $FILESTATUSTRANSCODEMP4BOX = 130; - $FILESTATUSTRANSCODEATOM = 140; - $FILESTATUSTRANSCODECOMPLETE = 150; - $FILESTATUSALLCOMPLETE = 200; - - #------------------------------ sub writelog{ my $messages = $_[0]; - my $timestump = strftime("%Y/%m/%d_%H:%M:%S", localtime); +my $timestump = `date +%Y/%m/%d_%H:%M:%S`; chomp($timestump); if ($debugmode == 1){ @@ -144,8 +125,9 @@ my $stationname = $_[0] ; my $stationid ; +my $DBQuery = "SELECT count(*) FROM foltia_station WHERE stationname = '$item{ChName}'"; my $sth; - $sth = $dbh->prepare($stmt{'foltialib.getstationid.1'}); - $sth->execute($item{'ChName'}); + $sth = $dbh->prepare($DBQuery); + $sth->execute(); my @stationcount; @stationcount= $sth->fetchrow_array; @@ -153,6 +135,7 @@ if ($stationcount[0] == 1){ #チャンネルID取得 - $sth = $dbh->prepare($stmt{'foltialib.getstationid.2'}); - $sth->execute($item{'ChName'}); +$DBQuery = "SELECT stationid,stationname FROM foltia_station WHERE stationname = '$item{ChName}'"; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @stationinfo= $sth->fetchrow_array; #局ID @@ -162,5 +145,6 @@ }elsif($stationcount[0] == 0){ #新規登録 - $sth = $dbh->prepare($stmt{'foltialib.getstationid.3'}); +$DBQuery = "SELECT max(stationid) FROM foltia_station"; + $sth = $dbh->prepare($DBQuery); $sth->execute(); @stationinfo= $sth->fetchrow_array; @@ -169,8 +153,10 @@ ##$DBQuery = "insert into foltia_station values ('$stationid' ,'$item{ChName}','0','','','','','','')"; #新規局追加時は非受信局をデフォルトに - $sth = $dbh->prepare($stmt{'foltialib.getstationid.4'}); - $sth->execute($stationid, $item{'ChName'}, -10); +$DBQuery = "insert into foltia_station (stationid , stationname ,stationrecch ) values ('$stationid' ,'$item{ChName}','-1')"; + + $sth = $dbh->prepare($DBQuery); + $sth->execute(); #print "Add station;$DBQuery\n"; - &writelog("foltialib Add station;$stmt{'foltialib.getstationid.4'}"); +&writelog("foltialib Add station;$DBQuery"); }else{ @@ -241,219 +227,4 @@ -sub getphpstyleconfig{ -my $key = $_[0]; -my $phpconfigpath = ""; -my $configline = ""; - # read -if (-e "$phptoolpath/php/foltia_config2.php"){ - $phpconfigpath = "$phptoolpath/php/foltia_config2.php"; -}elsif(-e "$toolpath/php/foltia_config2.php"){ - $phpconfigpath = "$toolpath/php/foltia_config2.php"; -}else{ - $phpconfigpath = `locate foltia_config2.php | head -1`; - chomp($phpconfigpath); -} - - -if (-r $phpconfigpath ){ -open (CONFIG ,"$phpconfigpath") || die "File canot read.$!"; -while(){ - if (/$key/){ - $configline = $_; - $configline =~ s/\/\/.*$//; - $configline =~ s/\/\*.*\*\///; - }else{ - } -} -close(CONFIG); -}#end if -r $phpconfigpath -return ($configline); -}#end sub getphpstyleconfig - - -sub getpidbympegfilename { -#引き数:m2pfilename -#戻り値:PID -my $m2pfilename = $_[0] ; -if ($m2pfilename eq ""){ - return 0 ; -} - -my $sth; - $sth = $dbh->prepare($stmt{'foltialib.getpidbympegfilename.1'}); - $sth->execute($m2pfilename); -#print "$stmt{'foltialib.getpidbympegfilename.1'}\n"; -my @pidinfo = $sth->fetchrow_array; -my $pid = $pidinfo[0]; - -if ($pid eq ""){ - return 0 ; -}else{ - return $pid; -} -}#end sub getpidbympegfilename - -sub changefilestatus { -#引き数:PID,updatestatus -#戻り値:エラーコード -my $pid = $_[0] ; -my $updatestatus = $_[1]; -if (($pid eq "" ) || ($updatestatus eq "")){ - return 0 ; -} - -if ($updatestatus > 0 ){ -my $sth; - $sth = $dbh->prepare($stmt{'foltialib.changefilestatus.1'}); - $sth->execute($updatestatus, $pid); -return 1; -}else{ - &writelog("foltialib changefilestatus ERR Sttus invalid:$updatestatus"); - return 0 ; -} -}# end sub changefilestatus - - -sub getfilestatus { -#引き数:PID -#戻り値:ステータス - -#10:予約中(5分以上先) -#20:予約中(5分以内) -#30:録画中 -#40:TSSplit中 -#50:MPEG2録画終了 -#55 静止画キャプチャ待 -#60:静止画キャプ中 -#70:静止画キャプ終了 -#72:サムネイル作成済み(.THM) -#80:トラコン待 -#90:トラコン中:TSsplit -#100:トラコン中:H264 -#110:トラコン中:WAVE -#120:トラコン中:AAC -#130:トラコン中:MP4Box -#140:トラコン中:ATOM -#150:トラコン完了 -#200:全完了 -my $pid = $_[0] ; -if ($pid eq "" ){ - return 0 ; -} - -my $sth; - $sth = $dbh->prepare($stmt{'foltialib.getfilestatus.1'}); - $sth->execute($pid); - -my @statusinfo = $sth->fetchrow_array; -my $status = $statusinfo[0]; - -if ($status eq ""){ - return 0 ; -}else{ - return $status; -} - - -}# end sub getfilestatus - - -sub makemp4dir{ -#TIDが100以上の3桁の場合はそのまま -my $pspfilnamehd = $_[0]; -my $tid = $_[0]; -my $pspdirname = "$tid.localized/"; -$pspdirname = $recfolderpath."/".$pspdirname; - -#なければ作る -unless (-e $pspdirname ){ - system("$toolpath/perl/mklocalizeddir.pl $tid"); - #&writelog("recwrap mkdir $pspdirname"); -} -$pspdirname = "$tid.localized/mp4/"; -$pspdirname = $recfolderpath."/".$pspdirname; -#なければ作る -unless (-e $pspdirname ){ - mkdir $pspdirname ,0777; - #&writelog("recwrap mkdir $pspdirname"); -} -return ("$pspdirname"); -}#endsub makemp4dir - -sub pid2sid{ -#番組IDからStation IDを取得 -my $pid = $_[0]; -my $sth; - $sth = $dbh->prepare($stmt{'foltialib.pid2sid.1'}); - $sth->execute($pid); -my @statusinfo = $sth->fetchrow_array; -my $sid = $statusinfo[0]; - -if ($sid eq ""){ - return 0 ; -}else{ - return $sid; -} - -}#end sub pid2sid - - -sub mp4filename2tid{ -#MPEG4ファイル名からTIDを得る -my $mp4filename = $_[0]; - -my $sth; - $sth = $dbh->prepare($stmt{'foltialib.mp4filename2tid.1'}); - $sth->execute($mp4filename); -my @statusinfo = $sth->fetchrow_array; -my $tid = $statusinfo[0]; - -if ($tid eq ""){ - return 0 ; -}else{ - return $tid; -} -}#end sub mp4filename2tid - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1; Index: trunk/install/perl/folprep.pl =================================================================== --- trunk/install/perl/folprep.pl (リビジョン 112) +++ trunk/install/perl/folprep.pl (リビジョン 1) @@ -23,5 +23,5 @@ $path = $0; $path =~ s/folprep.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -29,9 +29,9 @@ require "foltialib.pl"; - -#PID探し -my $pid = $ARGV[0]; +#XMLゲット & DB更新 +system("$toolpath/perl/getxml2db.pl"); #引き数がアルか? +$pid = $ARGV[0] ; if ($pid eq "" ){ #引き数なし出実行されたら、終了 @@ -40,19 +40,9 @@ } -my $stationid = ""; -if ($pid <= 0){#EPG録画/キーワード録画 - #EPG更新 & DB更新 - $dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; - $stationid = &pid2sid($pid); - &writelog("folprep DEBUG epgimport.pl $stationid"); - system("$toolpath/perl/epgimport.pl $stationid"); -}else{#しょぼかる録画 - #XMLゲット & DB更新 - &writelog("folprep DEBUG getxml2db.pl"); - system("$toolpath/perl/getxml2db.pl"); -} +#PID探し +$pid = $ARGV[0]; #キュー再投入 -&writelog("folprep $toolpath/perl/addpidatq.pl $pid"); + &writelog("folprep $toolpath/perl/addpidatq.pl $pid"); system("$toolpath/perl/addpidatq.pl $pid"); Index: trunk/install/perl/changestbch.pl =================================================================== --- trunk/install/perl/changestbch.pl (リビジョン 94) +++ trunk/install/perl/changestbch.pl (リビジョン 1) @@ -26,9 +26,8 @@ use DBI; use DBD::Pg; -use DBD::SQLite; $path = $0; $path =~ s/changestbch.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -55,8 +54,11 @@ # pidから局(送出コマンド)調べる #DB初期化 - $dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; - $sth = $dbh->prepare($stmt{'changestbch.1'}); - $sth->execute($pid); +$DBQuery = "SELECT foltia_station.tunertype,foltia_station.tunerch ,foltia_station.stationrecch ,foltia_station.stationid FROM foltia_subtitle,foltia_station WHERE foltia_subtitle.stationid = foltia_station.stationid AND foltia_subtitle.pid = '$pid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @chstatus = $sth->fetchrow_array; $tunertype = $chstatus[0]; Index: trunk/install/perl/updatem2pfiletable.pl =================================================================== --- trunk/install/perl/updatem2pfiletable.pl (リビジョン 101) +++ trunk/install/perl/updatem2pfiletable.pl (リビジョン 1) @@ -16,40 +16,41 @@ use DBI; use DBD::Pg; -use DBD::SQLite; $path = $0; $path =~ s/updatem2pfiletable.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } require "foltialib.pl"; -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; -$dbh->{AutoCommit} = 0; # ひとまず消す -$sth = $dbh->prepare($stmt{'updatem2pfiletable.1'}); +$query = "DELETE FROM foltia_m2pfiles "; + $sth = $dbh->prepare($query); $sth->execute(); -while ($file = glob("$recfolderpath/*.m2?")) { + +while ($file = glob("$recfolderpath/*.m2p")) { $file =~ s/$recfolderpath\///; - $sth = $dbh->prepare($stmt{'updatem2pfiletable.2'}); - $sth->execute($file); -# print "$file\n"; -}#while -while ($file = glob("$recfolderpath/*.aac")) { -$file =~ s/$recfolderpath\///; - $sth = $dbh->prepare($stmt{'updatem2pfiletable.2'}); - $sth->execute($file); +$query = "insert into foltia_m2pfiles values ('$file')"; + $sth = $dbh->prepare($query); + $sth->execute(); # print "$file\n"; }#while -$oserr = $dbh->commit; - # foltia_mp4files -@mp4filelist = `find ${recfolderpath}/ | grep MP4`;#by foltia dev ticket #5 http://www.dcc-jpl.com/foltia/ticket/5 # ひとまず消す -$sth = $dbh->prepare($stmt{'updatem2pfiletable.3'}); +$query = "DELETE FROM foltia_mp4files "; + $sth = $dbh->prepare($query); $sth->execute(); + +@mp4filelist = `find $recfolderpath | grep MP4`; +# find /home/foltia/php/tv | grep MP4 + +#/home/foltia/php/tv/1057.localized/mp4/M4V-1057-14-20061016-2345.MP4 +#/home/foltia/php/tv/1057.localized/mp4/M4V-1057-15-20061023-2345.MP4 @@ -57,14 +58,17 @@ chomp(); s/$recfolderpath\///; +# 1057.localized/mp4/M4V-1057-14-20061016-2345.MP4 +# 1057.localized/mp4/M4V-1057-15-20061023-2345.MP4 @fileline = split (/\//); $filetid = $fileline[0]; $filetid =~ s/[^0-9]//g; -if (($filetid ne "" )&& ($fileline[2] ne "" )){ - $sth = $dbh->prepare($stmt{'updatem2pfiletable.4'}); - $oserr = $sth->execute($filetid, $fileline[2]); + +$query = "insert into foltia_mp4files values ('$filetid','$fileline[2]')"; + $sth = $dbh->prepare($query); + $sth->execute(); + + #print "$filetid;$fileline[2];$query\n" # http://www.atmarkit.co.jp/fnetwork/rensai/sql03/sql1.html -}#end if -}# end foreach -$oserr = $dbh->commit; +} Index: trunk/install/perl/foltia_conf1.pl.template =================================================================== --- trunk/install/perl/foltia_conf1.pl.template (リビジョン 131) +++ trunk/install/perl/foltia_conf1.pl.template (リビジョン 1) @@ -11,30 +11,19 @@ #config section $toolpath = '/home/foltia'; #「perl」ディレクトリがあるPATH -$recunits = 0; #アナログキャプチャカード搭載エンコーダの数 +$recunits = '4'; #搭載エンコーダの数 $recfolderpath = '/home/foltia/php/tv'; #録画ファイルを置くPATH $uhfbandtype = 1; # CATVなら1 UHF帯なら0 : 0=ntsc-bcast-jp 1=ntsc-cable-jp $rapidfiledelete = 1;#1なら削除ファイルは「mita」ディレクトリに移動。0なら即時削除 -$tunerinputnum = 0; #IO-DATA DV-MVP/RX,RX2,RX2W -$svideoinputnum = 1;#IO-DATA DV-MVP/RX,RX2,RX2W -$comvideoinputnum= 2;#IO-DATA DV-MVP/RX,RX2,RX2W +$tunerinputnum = 6; #IO-DATA DV-MVP/RX,RX2,RX2W +$svideoinputnum = 7;#IO-DATA DV-MVP/RX,RX2,RX2W +$comvideoinputnum = 8;#IO-DATA DV-MVP/RX,RX2,RX2W $haveirdaunit = 1;#Tira-2をつないでいるときに1,なければ0 $mp4filenamestyle = 1 ;#0:PSP ファームウェアver.2.80より前と互換性を持つファイル名 1;よりわかりやすいファイル名 -$trconqty = 2; -#0:PSP/iPod XviD MPEG4(旧式):faacとMPEG4IPを使って変換(古い設定) -#1:iPod Xvid MPEG4 標準画質 15fps 300kbps / デジタル 360x202 24.00fps 300kbps -#2:iPod H.264 中画質 24fps 300kbps / デジタル 480x272 29.97fps 400kbps -#3:iPod H.264 高画質 30fps 300kbps / デジタル 640x352 29.97fps 600kbps -$phptoolpath = $toolpath ;#php版の初期設定の位置。デフォルトではperlと同じ位置 -#以下はデフォルトでインストールしてればいじらなくてもいい - -## for postgresql -#$main::DSN="dbi:Pg:dbname=foltia;host=localhost;port=5432"; -#require 'db/Pg.pl'; - -## for sqlite -$main::DSN="dbi:SQLite:dbname=/home/foltia/foltia.sqlite"; -require 'db/SQLite.pl'; - +#デフォルトでインストールしてればいじらなくてもいい +$main::DBDriv="Pg"; +$main::DBHost="localhost"; +$main::DBPort="5432"; +$main::DBName="foltia"; $main::DBUser="foltia"; $main::DBPass=""; Index: trunk/install/perl/singletranscode.pl =================================================================== --- trunk/install/perl/singletranscode.pl (リビジョン 94) +++ trunk/install/perl/singletranscode.pl (リビジョン 1) @@ -28,5 +28,4 @@ use DBI; use DBD::Pg; -use DBD::SQLite; use Schedule::At; use Time::Local; @@ -35,5 +34,5 @@ $path = $0; $path =~ s/singletranscode.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -64,11 +63,15 @@ #PSPトラコン必要かどうか -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; if ($ARGV[1] != ""){ $pid = $ARGV[1] ; }else{ - $sth = $dbh->prepare($stmt{'singletranscode.1'}); - $sth->execute($ARGV[0]); +$DBQuery = "SELECT pid FROM foltia_subtitle WHERE m2pfilename = '$ARGV[0]' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @pidarray = $sth->fetchrow_array; unless ($pidarray[0] == "" ){ @@ -83,11 +86,13 @@ # 追加部分 -$sth = $dbh->prepare($stmt{'singletranscode.2'}); -$sth->execute($tid, $countno); +$query = "SELECT count(*) FROM foltia_subtitle WHERE tid = '$tid' AND countno = '$countno' "; + $sth = $dbh->prepare($query); + $sth->execute(); @subticount= $sth->fetchrow_array; unless ($subticount[0] >= 1){ - $sth = $dbh->prepare($stmt{'singletranscode.3'}); - $sth->execute($tid); +$query = "SELECT count(*) FROM foltia_subtitle WHERE tid = '$tid' "; + $sth = $dbh->prepare($query); + $sth->execute(); @subticount= $sth->fetchrow_array; @@ -115,6 +120,7 @@ # PSP ------------------------------------------------------ #PSPトラコン必要かどうか -$sth = $dbh->prepare($stmt{'singletranscode.4'}); -$sth->execute($tid); +$DBQuery = "SELECT psp,aspect,title FROM foltia_program WHERE tid = '$tid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @psptrcn= $sth->fetchrow_array; if ($psptrcn[0] == 1 ){#トラコン番組 @@ -221,5 +227,5 @@ my $newestmp4filename = `cd $pspdirname ; ls -t *.MP4 | head -1`; if ($newestmp4filename =~ /M4V$tid/){ - $nowcountno = $' ;#' + $nowcountno = $' ; $nowcountno++; $pspfilnameft = sprintf("%02d",$nowcountno); @@ -255,6 +261,7 @@ #最適化 - $sth = $dbh->prepare($stmt{'singletranscode.5'}); - $sth->execute($tid, $countno); +$DBQuery = "SELECT subtitle FROM foltia_subtitle WHERE tid = '$tid' AND countno = '$countno' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @programtitle = $sth->fetchrow_array; @@ -278,5 +285,5 @@ if (-e "$pspdirname/M4V".$pspfilname.".THM"){ - $timestamp = strftime("%Y%m%d-%H%M%S", localtime); +$timestamp =`date "+%Y%m%d-%H%M%S"`; chomp $timestamp; system("convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/M4V".$pspfilname.".THM.".$timestamp.".THM"); @@ -290,16 +297,26 @@ system("rm -rf $pspdirname/0000000*.jpg "); + + + # MP4ファイル名をPIDレコードに書き込み unless ($pid eq ""){ - $sth = $dbh->prepare($stmt{'singletranscode.6'}); - $sth->execute("M4V$pspfilname.MP4", $pid); - &writelog("singletranscode UPDATEsubtitleDB $stmt{'singletranscode.6'}"); + $DBQuery = " + UPDATE foltia_subtitle + SET PSPfilename = 'M4V$pspfilname.MP4' + WHERE pid = '$pid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("singletranscode UPDATEsubtitleDB $DBQuery"); }else{ &writelog("singletranscode PID not found"); } # MP4ファイル名をfoltia_mp4files挿入 - $sth = $dbh->prepare($stmt{'singletranscode.7'}); - $sth->execute($tid, "M4V$pspfilname.MP4"); - &writelog("singletranscode UPDATEmp4DB $stmt{'singletranscode.7'}"); + $DBQuery = "insert into foltia_mp4files values ('$tid','M4V$pspfilname.MP4') "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("singletranscode UPDATEmp4DB $DBQuery"); }#PSPトラコンあり + + Index: trunk/install/perl/captureimagemaker.pl =================================================================== --- trunk/install/perl/captureimagemaker.pl (リビジョン 94) +++ trunk/install/perl/captureimagemaker.pl (リビジョン 1) @@ -14,5 +14,5 @@ $path = $0; $path =~ s/captureimagemaker.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -56,5 +56,5 @@ $date =~ s/[^0-9]//ig; if ($date eq "" ){ - $date = strftime("%Y%m%d", localtime); + $date = `date +%Y%m%d` } # print "DATE:$date\n"; @@ -65,5 +65,5 @@ $time =~ s/[^0-9]//ig; if ($time eq "" ){ - $time = strftime("%H%M", localtime); + $time = `date +%H%M` } # print "TIME:$time\n"; @@ -100,5 +100,5 @@ # $captureimgdir = "$tid"."-"."$countno"."-"."$date"."-"."$time"; $captureimgdir = $filename; -$captureimgdir =~ s/\.m2p$|\.m2t$//; +$captureimgdir =~ s/\.m2p$//; unless (-e "$capimgdirname/$captureimgdir"){ @@ -118,20 +118,4 @@ # 10秒ごとに -if ($filename =~ /m2t$/){ - &writelog("captureimagemaker DEBUG mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf scale=192:108 -ao null -sstep 9 $recfolderpath/$filename"); - system ("mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf scale=192:108 -ao null -sstep 9 $recfolderpath/$filename"); - if(-e "$capimgdirname/$captureimgdir/00000001.jpg" ){ #$capimgdirname/$captureimgdir/があったらなにもしない - }else{ #空っぽなら再試行 - &writelog("captureimagemaker DEBUG RETRY mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf framestep=300step,scale=192:108 -ao null $recfolderpath/$filename"); - system ("mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf framestep=300step,scale=192:108 -ao null $recfolderpath/$filename"); - } - -}else{ - &writelog("captureimagemaker DEBUG mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf crop=690:460:12:10,scale=160:120 -ao null -sstep 9 -v 3 $recfolderpath/$filename"); - system ("mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf crop=690:460:12:10,scale=160:120 -ao null -sstep 9 $recfolderpath/$filename"); - if(-e "$capimgdirname/$captureimgdir/00000001.jpg" ){ #$capimgdirname/ - }else{ - system ("mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf framestep=300step,crop=690:460:12:10,scale=160:120 -ao null $recfolderpath/$filename"); - } -} +system ("mplayer -ss 00:00:10 -vo jpeg:outdir=$capimgdirname/$captureimgdir/ -vf crop=690:460:12:10,scale=160:120 -ao null -sstep 9 -v 3 $recfolderpath/$filename"); Index: trunk/install/perl/tvrecording.pl =================================================================== --- trunk/install/perl/tvrecording.pl (リビジョン 94) +++ trunk/install/perl/tvrecording.pl (リビジョン 1) @@ -5,5 +5,5 @@ # #tvrecording.pl -# record-v4l2.plを呼びだす録画モジュール。 +# record-v4l2.plに準備処理を加えた録画モジュール。 # #usage tvrecording.pl ch length(sec) [clip No(000-)] [filename] [bitrate(5)] [TID] [NO] [/dev/video0] @@ -11,5 +11,5 @@ #ch :録画チャンネル 0だとS入力、-1だとコンポジット入力 [必須項目] #length(sec) :録画秒数 [必須項目] -#[sleeptype] :0かN Nならスリープなしで録画 +#[clip No(000-)] :歴史的に0 #[filename] :出力ファイル名 #[bitrate(5)] :ビットレート Mbps単位で指定 @@ -24,10 +24,10 @@ -#use Time::HiRes qw(usleep); +use Time::HiRes qw(usleep); $path = $0; $path =~ s/tvrecording.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -42,7 +42,6 @@ #tvConfig.pl ------------------------------- $extendrecendsec = 10; #recording end second. -#$startupsleeptime = 52; #process wait(MAX60sec) -$startupsleeptime = 37; #process wait(MAX60sec) - +$startupsleeptime = 52; #process wait(MAX60sec) +#$startupsleeptime = 1; #process wait(MAX60sec) #------------------------------- @@ -64,6 +63,5 @@ $recfolderpath = '/home/foltia/php/tv'; }#end sub getRecPath -# -# -- ここからメイン ---------------------------- + #準備 &prepare; @@ -75,9 +73,9 @@ $reclengthsec = $reclengthsec + $extendrecendsec ; -&callrecordv4l; - &writelog("tvrecording:$recch:$reclengthsec:$outputfile:$recdevice:$capturedeviceinputnum:$ivtvrecch:$stdbitrate:$peakbitrate"); -# -- これ以下サブルーチン ---------------------------- +#------------------------------ + + sub chkextinput{ @@ -88,5 +86,5 @@ $capturedeviceinputnum = 7 ; } - $capturedeviceinputName = "S-Video 1"; + $capturedeviceinputName = "S-Video 0"; $ivtvrecch = ''; }elsif($recch == -1){ @@ -96,5 +94,5 @@ $capturedeviceinputnum = 8; } - $capturedeviceinputName = "Composite 1"; + $capturedeviceinputName = "Composite 0"; $ivtvrecch = ''; }else{ @@ -104,5 +102,5 @@ $capturedeviceinputnum = 6 ; } - $capturedeviceinputName = "Tuner 1"; + $capturedeviceinputName = "Tuner 0"; $ivtvrecch = $recch; } @@ -252,28 +250,16 @@ } #1分前にプロセス起動するから指定時間スリープ -#srand(time ^ ($$ + ($$ << 15))); -#my $useconds = int(rand(12000000)); -#my $intval = int ($useconds / 1000000); -#my $startupsleeptimemicro = ($startupsleeptime * 1000000) - $useconds; -#$reclengthsec = $reclengthsec + $intval + 1; -#&writelog("tvrecording: DEBUG SLEEP $startupsleeptime:$useconds:$intval:$startupsleeptimemicro"); -# usleep ( $startupsleeptimemicro ); - +srand(time ^ ($$ + ($$ << 15))); +my $useconds = int(rand(12000000)); +my $intval = int ($useconds / 1000000); +my $startupsleeptimemicro = ($startupsleeptime * 1000000) - $useconds; +$reclengthsec = $reclengthsec + $intval + 1; # $recch でウェイト調整入れましょう -#52 -#my $intval = $recch % 50; # 0〜49 -#my $startupsleep = $startupsleeptime - $intval; # 3〜52 (VHF 40-51) -#37 -my $intval = $recch % 35; # 0〜34 -my $startupsleep = $startupsleeptime - $intval; # 3-37 (VHF 25-36,tvk 30) -$reclengthsec = $reclengthsec + (60 - $startupsleep) + 1; # - -if ( $ARGV[2] ne "N"){ - &writelog("tvrecording: DEBUG SLEEP $startupsleeptime:$intval:$startupsleep:$reclengthsec"); - sleep ( $startupsleep); -}else{ - &writelog("tvrecording: DEBUG RAPID START"); - -} + + +&writelog("tvrecording: DEBUG SLEEP $startupsleeptime:$useconds:$intval:$startupsleeptimemicro"); + + usleep ( $startupsleeptimemicro ); + if ($recunits > 1){ my $deviceno = $recunits - 1;#3枚差しのとき/dev/video2から使う @@ -301,19 +287,19 @@ # $outputfile .= "$ARGV[3]"; # }else{ -# $outputfile .= strftime("%Y%m%d-%H%M", localtime(time + 60)); +# $outputfile .= `date +%Y%m%d-%H%M --date "1 min "`; # } $outputfile = $ARGV[3]; $outputfile = &filenameinjectioncheck($outputfile); - $outputfilewithoutpath = $outputfile ; $outputfile = $outputpath.$outputfile ; # $outputfile .= "$ARGV[3]"; -# $outputfile .= strftime("%Y%m%d-%H%M", localtime(time + 60)); - &writelog("tvrecording: DEBUG ARGV[2] ne null \$outputfile $outputfile "); +# $outputfile .= `date +%Y%m%d-%H%M --date "1 min "`; + &writelog("tvrecording: DEBUG ARGV[2] ne null \$outputfile $outputfile "); + }else{ - $outputfile .= strftime("%Y%m%d-%H%M", localtime(time + 60)); - chomp($outputfile); - $outputfile .= ".m2p"; - $outputfilewithoutpath = $outputfile ; - &writelog("tvrecording: DEBUG ARGV[2] is null \$outputfile $outputfile "); + $outputfile .= `date +%Y%m%d-%H%M --date "1 min "`; + chomp($outputfile); + $outputfile .= ".m2p"; +&writelog("tvrecording: DEBUG ARGV[2] is null \$outputfile $outputfile "); + } @@ -325,8 +311,6 @@ #二重録りなど既に同名ファイルがあったら中断 if ( -e "$outputfile" ){ - if ( -s "$outputfile" ){ - &writelog("tvrecording :ABORT :recfile $outputfile exist."); - exit 1; - } +&writelog("tvrecording :ABORT :recfile $outputfile exist."); +exit 1; } @@ -342,32 +326,1490 @@ }#end setbitrate - -sub callrecordv4l{ - -#$frequency = `ivtv-tune -d $recdevice -t $frequencyTable -c $ivtvrecch | awk '{print $2}'|tr -d .`; -my $ivtvtuneftype = ''; -if ($frequencyTable eq "ntsc-cable-jp"){ - $ivtvtuneftype = 'japan-cable'; -}else{ - $ivtvtuneftype = 'japan-bcast'; -} -#print "ivtv-tune -d $recdevice -t $ivtvtuneftype -c $ivtvrecch\n"; -&writelog("tvrecording DEBUG ivtv-tune -d $recdevice -t $ivtvtuneftype -c $ivtvrecch"); -&writelog("tvrecording DEBUG $ENV{PATH}"); - -$frequency = `env PATH=PATH=/usr/kerberos/bin:/usr/lib/ccache:/usr/local/bin:/bin:/usr/bin:/home/foltia/bin ivtv-tune -d $recdevice -t $ivtvtuneftype -c $ivtvrecch`; -&writelog("tvrecording DEBUG frequency:$frequency"); -@frequency = split(/\s/,$frequency); -$frequency[1] =~ s/\.//gi; -$frequency = $frequency[1] ; -&writelog("tvrecording DEBUG frequency:$frequency"); - -my $recordv4lcallstring = "$toolpath/perl/record-v4l2.pl --frequency $frequency --duration $reclengthsec --input $recdevice --directory $recfolderpath --inputnum $capturedeviceinputnum --inputname '$capturedeviceinputName' --freqtable $frequencyTable --bitrate $stdbitrate --peakbitrate $peakbitrate --output $outputfilewithoutpath "; - -&writelog("tvrecording $recordv4lcallstring"); -&writelog("tvrecording DEBUG $ENV{HOME}/.ivtvrc"); -$oserr = `env HOME=$toolpath $recordv4lcallstring`; -&writelog("tvrecording DEBUG $oserr"); - -}#end callrecordv4l - +#------------------------------------------------------------------------------------------------- +# record-v4l2.pl created by James A. Pattie 04/10/2003 +# Copyright 2003 +# Purpose: to record from the specified channel for the specified amount +# of time to the video OutputDirectory under the channel-start time name as video.mpg. + +# +# You can always get the latest version of this script at +# http://www.pcxperience.org/ +# + +#2003.11.18 patched by DCC-JPL + +# 20030425 - 1.4 - Added devfs support based upon patch submitted by +# Jonathan Kolb +# 20030426 - 1.5 - Imported the ptune.pl functionality +# 20030426 - 1.6 - moved -F -> -L, -F now lets you specify the frequency to tune to. +# 20030427 - 1.7 - renamed to record_ivtv.pl per Kevin's request. Added -R option. +# 20030430 - 1.8 - fixing some comparisons that needed to be strings, etc. +# 20030504 - 1.9 - Migrating to Video::ivtv for video resolution support. +# 20030505 - 1.10- Replaced open w/ sysopen but it doesn't make a difference. +# Starting to replace the Standard code w/ Video::ivtv methods. +# Added the version numbers that I require to the use statements. +# 20030507 - 1.11- Migrated to using get/setFrequency from Video::ivtv 0.03. +# 20030510 - 1.12- Migrated to using get/setInput from Video::ivtv 0.04. Moved to using +# the exported method names rather than Video::ivtv::method(). +# Converted to using enumerateStandard(). +# Fixed the condition where switching Video Standards will most likely +# not get the correct channel and so would switch back with channel = 0 +# which is invalid. In this case I store the previous frequency, do the +# channel change but signal to restore the previous frequency on cleanup. +# Converted to using enumerateInput(). +# 20030512 - 1.13- Added initial support for setting the bitrate/bitrate_peak values. +# 20030513 - 1.14- Tweaked the bitrate values to be closer to real DVD bitrates. +# Added support for the .ivtvrc config file and User Profiles. +# 20030516 - 1.15- Updated to the OO interface that Video::ivtv 0.06 now requires. +# Cleaned up a lot of the global variables into a settings hash. +# Made the -S command add any config items you specified on the command line +# that were not in the Profile being updated. This way you can add new items. +# Made the config file work from a mapping hash so that we can easily add/remove +# config items in the future. +# 20030518 - 1.16- Fixed a Frequency bug that happened when changing Video Standards and the +# Frequency came from a user specified Profile. +# 20030519 - 1.17- Adding the rest of the Codec related options to the config file / defaults. +# Switched to using Getopt::Long. You can specify all config file options at +# least by a --long version and still by the original -X command option. +# Cleaned up the option parsing code to take advantage of the mappings hash. +# 20030520 - 1.18- Fixing the handling of the Profile command line option. +# 20030524 - 1.19- Cleaned up the output for -L/--list-freqtable. Changed --list -> --list-freqtable. +# Added support to detect the v4l2 driver in use and disable the ivtv "enhancements" +# if driver != "ivtv". +# Renamed to record-v4l2.pl to reflect the ability of this program to record from any +# v4l2 device but with special support for the ivtv driver. +# 20030524 - 1.20- Improving the Ctrl-C handling (cleanup before dying). It may take a second or two +# before the program exits, but it should exit after resetting anything it changed, unless +# you had specified not to reset the card. +# Allow layering of profiles by calling -P/--profile multiple times. Each profile will +# be layered over the last. You will not be able to create/update a profile if you +# specify more than one though. +# Fixed a bug that would cause a parameter from the profile to be set n times, where n was +# the number of characters in the mapping string that consisted of the single letter | and +# the long command option name. Ex: Channel has 'c|channel' so the Channel value was being +# set 9 times instead of just the first time if it was in the profile. +# 20030525 - 1.21- Fixed devfsd detection code as it was overriding what came from the config file. +# Adding --no-record option so that we can start to implement the replacement functionality for +# ptune.pl (ie. Set all values and then exit, do not reset the card and do not capture) +# 20030607 - 1.22- Adding --directory-format and --date-format options so that the user can specify the +# naming convention to use when specifying the directory the output file should be put in. +# Tweaked some of the defaults. +# Create the config file if it doesn't exist, regardless of the --save flag being specified. +# Added method error() to output an error condition that doesn't warrant the whole usage and +# converted all relevant usage() calls to error() calls. +# Added option --debug to dynamically on the fly enable debug output. +# 20030609 - 1.23- Added option --list-channels to display the currently selected frequency tables contents. +# Changed the default output directory to '.'. +# Moved $debug -> $settings{Debug} so it can be stored in the config file. This allows you to +# turn debugging on for only certain profiles, etc. +# Restructured some of the validity tests to only happen as long as we are recording since they +# do not need to be validated when we are not recording. Mainly to do with the output stuff. +# 20030610 - 1.24- Moved the tunerNum variable into the config file: TunerNum +# Added --tuner-num option to dynamically set it. +# 20030614 - 1.25- I now require Video::ivtv 0.09 to make sure everyone is using the version that fixes the known +# reported segfault issues. +# Added freqtable "custom" support so that people using the new feature in ptune-ui.pl and have +# set their default frequency table to be "custom" will just work when they specify channel X, etc. +# I'm now sorting the command line input since otherwise I can't guarantee the order options get +# processed in, but even that is wrong. I need to use Tie::IxHash, but that isn't standard. +# 20030626 - 1.26- Updated to cover the audio -> audio_bitmask changes that Video::ivtv 0.11 implemented to cover +# the ivtv_ioctl_codec structure changes. +# Implemented config file versioning so that I know when the Audio entry needs to be updated in case it +# comes back in a future version of the ivtv_ioctl_codec structure. +# 20030628 - 1.27- Adding --list-inputs and --list-standards to display the available inputs and video standards. +# 20030713 - 1.28- Added code to make sure the codec properties are proper when switching standard to PAL/SECAM. +# Added config options SetMSPMatrix, MSPInput, MSPOutput, MSPSleep to allow the user to specify if they +# want the msp matrix updated any time the Video Standard is changed and to specify what they want programmed. +# Bumping the config file version to 2 to account for the new options. +# 20030715 - 1.29- Adding the missing msp matrix reset code in the reset section. +# Adding codec checks to make sure that they are right for NTSC. +# Made it legal to specify the channel by itself without -c/--channel. + + +#use strict; +use Getopt::Long qw(:config no_ignore_case bundling); +use Fcntl; +use Video::Frequencies 0.03; +use Video::ivtv 0.12; +use Config::IniFiles; + +my $version="1.29"; +my $cfgVersion = "2"; +my $cfgVersionStr = "_configVersion_"; # hopefully unique [defaults] value to let me know what version the config file is. + +my @capabilities = (); # The cards capabilities + +my %settings = ( + Channel => $ivtvrecch , # default to the ivtv default channel + RecordDuration => $reclengthsec , # default to 59 minutes 50 seconds (in seconds) - This lets 2 back to back cron jobs work! + InputNum => $capturedeviceinputnum , # TV-Tuner 0 on GV-MVP/RX $capturedeviceinputnum + InputName => "$capturedeviceinputName", + OutputDirectory => "$recfolderpath", + VideoDevice => "$recdevice", + VideoWidth => "720", # 720x480-fullscreen NTSC + VideoHeight => "480", + VideoStandard => "NTSC", # NTSC, PAL or SECAM + VideoType => "mpeg", # mpeg, yuv + Bitrate => "$stdbitrate", + PeakBitrate => "$peakbitrate", # peak bitrate + Aspect => 2, + AudioBitmask => 0x00e9, + BFrames => 3, + DNRMode => 0, + DNRSpatial => 0, + DNRTemporal => 0, + DNRType => 0, + Framerate => 0, + FramesPerGOP => 15, + GOPClosure => 1, + Pulldown => 0, + StreamType => 0, # 10 = DVD format (almost) + OutputFileName => "$outputfile", + FrequencyTable => "$frequencyTable", # default to NTSC_CABLE mapping. + Frequency => "", # user specified frequency. + ResetCardSettings => 1, + ConfigFileName => "$ENV{HOME}/.ivtvrc", + UpdateConfigFile => 0, + UseConfigFile => 0, + UsingIvtvDriver => 1, # default to being able to use the ivtv "enhancements". + DontRecord => 0, # default to always recording data. + DirectoryFormatString => " ", # format string used to define the sub directory under OutputDirectory + DateTimeFormatString => "+%Y%m%d-%H%M", # format string used to represent the date/time if the user wants it in their DirectoryFormatString + # define the Codec related min/max values + minBitrate => 1, + maxBitrate => 14500000, + minPeakBitrate => 1500, + maxPeakBitrate => 16000000, + # msp matrix settings + SetMSPMatrix => 1, + MSPInput => 3, + MSPOutput => 1, + MSPSleep => 2, # number of seconds the card needs before we can set the msp matrix. + # other settings + Debug => 0,#DEBUG + TunerNum => 0, +); + + +print " $settings{InputNum} / $settings{InputName} /IVTVRECCH:$settings{Channel}/$recdevice \n\n" if $settings{Debug}; + + +my $result=""; +my @profileNames=(); # list of user defined sections to work with in the config file. +my %configIni; # config hash we tie to for Config::IniFiles. +my $ivtvObj = Video::ivtv->new(); + +# map the Settings/Config file parameter to the command line variable that specifies it. +my %mappings = ( + "Channel" => "c|channel", + "RecordDuration" => "t|duration", + "InputNum" => "i|inputnum", + "InputName" => "I|inputname", + "OutputDirectory" => "D|directory", + "VideoDevice" => "d|input", + "VideoWidth" => "W|width", + "VideoHeight" => "H|height", + "VideoStandard" => "s|standard", + "VideoType" => "T|type", + "Bitrate" => "b|bitrate", + "PeakBitrate" => "B|peakbitrate", + "Aspect" => "aspect", + "AudioBitmask" => "audio-bitmask", + "BFrames" => "bframes", + "DNRMode" => "dnrmode", + "DNRSpatial" => "dnrspatial", + "DNRTemporal" => "dnrtemporal", + "DNRType" => "dnrtype", + "Framerate" => "framerate", + "FramesPerGOP" => "framespergop", + "GOPClosure" => "gopclosure", + "Pulldown" => "pulldown", + "StreamType" => "streamtype", + "OutputFileName" => "o|output", + "FrequencyTable" => "f|freqtable", + "Frequency" => "F|frequency", + "ResetCardSettings" => "R|noreset", + "DirectoryFormatString" => "directory-format", + "DateTimeFormatString" => "date-format", + "Debug" => "debug", + "TunerNum" => "tuner-num", + "SetMSPMatrix" => "set-msp-matrix", + "MSPInput" => "msp-input", + "MSPOutput" => "msp-output", + "MSPSleep" => "msp-sleep", + "OutputMPGFileName" => "outputmpgfilename", + ); + +my %codecMappings = ( + "Aspect" => "aspect", + "AudioBitmask" => "audio_bitmask", + "BFrames" => "bframes", + "Bitrate" => "bitrate", + "PeakBitrate" => "bitrate_peak", + "DNRMode" => "dnr_mode", + "DNRSpatial" => "dnr_spatial", + "DNRTemporal" => "dnr_temporal", + "DNRType" => "dnr_type", + "Framerate" => "framerate", + "FramesPerGOP" => "framespergop", + "GOPClosure" => "gop_closure", + "Pulldown" => "pulldown", + "StreamType" => "stream_type", + ); + +# check for devfs support +if ( -e "/dev/.devfsd" ) +{ + $settings{VideoDevice} = "/dev/v4l/video0"; +} + +## check for the config file +#if (-f $settings{ConfigFileName}) +#{ +# $settings{UseConfigFile} = 1; +# +# # tie to it. +# tie %configIni, 'Config::IniFiles', (-file => $settings{ConfigFileName}) or die "Error: Opening config file '$settings{ConfigFileName}' failed! $!\n"; +# +# my $profile = "defaults"; +# if (exists $configIni{$profile}) +# { +# my $saveFile = 0; +# # check version of the config file. +# if (!exists $configIni{$profile}{$cfgVersionStr}) +# { +# print "Updating config file to version 1...\n"; +# +# # first version config file! Update the Audio -> AudioBitmask entries. +# $configIni{$profile}{$cfgVersionStr} = 1; +# +# # find all entries that have Audio and move to AudioBitmask. +# foreach my $p (keys %configIni) +# { +# if (exists $configIni{$p}{Audio}) +# { +# $configIni{$p}{AudioBitmask} = $configIni{$p}{Audio}; +# delete $configIni{$p}{Audio}; +# } +# } +# +# $saveFile = 1; # signal we need to save the config changes. +# } +# if ($configIni{$profile}{$cfgVersionStr} != $cfgVersion) +# { +# # we need to upgrade +# if ($configIni{$profile}{$cfgVersionStr} == 1) +# { +# print "Updating config file to version 2...\n"; +# # add the MSP Matrix related options. +# $configIni{$profile}{SetMSPMatrix} = $settings{SetMSPMatrix}; +# $configIni{$profile}{MSPInput} = $settings{MSPInput}; +# $configIni{$profile}{MSPOutput} = $settings{MSPOutput}; +# $configIni{$profile}{MSPSleep} = $settings{MSPSleep}; +# $configIni{$profile}{$cfgVersionStr} = 2; +# $saveFile = 1; +# } +# } +# +# if ($saveFile) +# { +# # now save the updated config file before we continue. +# tied(%configIni)->RewriteConfig or die "Error: Writing config file '$settings{ConfigFileName}' failed! $!\n"; +# } +# +# # update the defaults stored. +# foreach my $arg (keys %mappings) +# { +# if (exists $configIni{$profile}{$arg}) +# { +# $settings{$arg} = $configIni{$profile}{$arg}; +# print "settings{$arg} = '" . $settings{$arg} . "'\n"; +# } +# } +# } +# else +# { +# print "Warning: config file '$settings{ConfigFileName}' exists but does not have the\n[$profile] section! Use -S to create it without specifying -P.\n\n"; +# } +#} +#else # create the config file +#{ +# print "Auto Creating config file $settings{ConfigFileName}...\n"; +# my $profile = "defaults"; +# +# # we have to create the config file and tie to it. +# tie %configIni, 'Config::IniFiles', () or die "Error: Initializing config file '$settings{ConfigFileName}' failed! $!\n"; +# +# # now set the name to work with. +# tied(%configIni)->SetFileName($settings{ConfigFileName}) or die "Error: Setting config file to '$settings{ConfigFileName}' failed! $!\n"; +# +# $configIni{$profile} = {}; # make sure the section exists. +# +# foreach my $arg (keys %mappings) +# { +# $configIni{$profile}{$arg} = $settings{$arg}; +# print "configIni{$profile}{$arg} = '" . $settings{$arg} . "'\n" if $settings{Debug}; +# } +# +# # set the config file version +# $configIni{$profile}{$cfgVersionStr} = $cfgVersion; +# +# # write the config file out. +# tied(%configIni)->RewriteConfig or die "Error: Writing config file '$settings{ConfigFileName}' failed! $!\n"; +#} + +# build up the "custom" frequency table +my %customMap = (); +foreach my $profileName (keys %configIni) +{ + next if $profileName =~ /^(defaults)$/; + + if (exists $configIni{$profileName}{Frequency}) + { + $customMap{$profileName} = $configIni{$profileName}{Frequency}; + } +} +$CHANLIST{custom} = \%customMap; + +# enumerations +my @standards; +my %name2std; +my @inputs; +my %name2input; +my @codecInfo; # stores the Codec Info +my @newCodecInfo; # the version we mess with. +# Current settings (Input, Channel, Standard) +my $curinput; +my $curinputName; +my $std; +my $curstd = "???"; +my $curStandard = 0; # numeric representation. +my $curChannel = 0; +my $curFrequency = 0; + +my $tuner; +my $err; +my $v4l2input; + +my $tmpDirectoryStr = formatDirectoryString(); +my $versionStr = "record-v4l2.pl $version for use with http://ivtv.sf.net/"; +my $usageStr = <<"END_OF_USAGE"; +$versionStr + +Usage: record-v4l2.pl [--channel CHANNEL] [--duration TIME] + [--directory DIRECTORY] [--output OUTPUT] + [--directory-format FORMAT] [--date-format FORMAT] + [--input VIDEO_DEV][--width WIDTH --height HEIGHT] + [--standard STANDARD] [--type TYPE] + [--inputnum INPUT#] [--inputname INPUT NAME] + [--freqtable FREQENCY MAP] [--frequency FREQUENCY] + [--bitrate BITRATE] [--peakbitrate PEAK_BITRATE] + [--set-msp-matrix BOOL] [--msp-sleep SLEEP] + [--msp-input INPUT] [--msp-output OUTPUT] + [--profile PROFILE] [--list-freqtable] [--list-channels] + [--no-record] [--noreset] [--save] [--help] [--version] + [--aspect ASPECT] [--audio-bitmask AUDIO-BITMASK] [--bframes BFRAMES] + [--dnrmode DNRMODE] [--dnrspatial DNRSPATIAL] + [--dnrtemporal DNRTEMPORAL] [--dnrtype DNRTYPE] + [--framerate FRAMERATE] [--framespergop FRAMESPERGOP] + [--gopclosure GOPCLOSURE] [--pulldown PULLDOWN] + [--streamtype STREAMTYPE] [--debug] + [--tuner-num TUNERNUM] + [--list-inputs] [--list-standards] [CHANNEL] + + -c/--channel CHANNEL: channel number to switch to + NOTE: You can also specify the channel by itself. + Ex. record-v4l2.pl 73 + would change to channel 73 using the default settings + or the settings from your ~/.ivtvrc config file. + -t/--duration TIME: number of seconds to record + -D/--directory DIRECTORY: Base directory to record into + --directory-format FORMAT: format string that specifies the + sub-directory to create under the base directory that + the output file will be created in. This can be empty + to indicate no sub-directory should be created. + + Available tokens are: + %d - date formatted by --date-format + %I - input name recorded from + Any white space in the name is converted to + underscores (_). Ex. 'Tuner 0' => 'Tuner_0' + + %c - channel or "freq-#" frequency + + --date-format FORMAT: format string that specifies the + date format string to generate and substitute for + %d in the --directory-format string. + + Available tokens: see the date commands man page. + The string must start with a + (plus). + + -o/--output OUTPUT: name of file to create + -d/--input VIDEO_DEV: video device to capture from + -W/--width WIDTH: width of screen (720 for NTSC fullscreen) + -H/--height HEIGHT: height of screen (480 for NTSC fullscreen) + -s/--standard STANDARD: NTSC, PAL or SECAM - video standard to record in + -T/--type TYPE: mpeg or yuv output + -i/--inputnum INPUT#: + The index number of the input you want to use (0 -> n-1) + -I/--inputname INPUT NAME: The name of the input you want to use. + -f/--freqtable FREQUENCY MAP: Specify the frequency mapping to use. + -F/--frequency FREQUENCY: Specify the frequency to tune to. + ex. 517250 = NTSC Cable 73 (SCiFi) + --tuner-num TUNERNUM: Specify the tuner to use. + --set-msp-matrix BOOL: 1 - set the msp matrix after Video Standard changes + 0 - never set the msp matrix + Uses the --msp-input and --msp-output options. + --msp-sleep SLEEP: number of seconds the card needs before we can program + the msp matrix. + --msp-input INPUT: Specify the input parameter to program the msp matrix. + Valid values are from 1 - 8. + --msp-output OUTPUT: Specify the output parameter to program the msp matrix. + Valid values are from 0 - 3. + -L/--list-freqtable: + list all available frequency mappings that Video::Frequencies knows + --list-channels: lists all channels and their frequencies for the + specified frequency table being used. + --list-inputs: lists all inputs the v4l2 driver reports. + --list-standards: lists all Video Standards the v4l2 driver supports. + -R/--noreset: Do not Reset anything that was changed + (standard, channel, resolution, etc.) + --no-record: Do not create any directories, capture data or reset the card + back to original settings. This is the ptune.pl mode. + -h/--help: display this help + -v/--version: display the version of this program + --debug: turns on debug output + + Codec related options: + -b/--bitrate BITRATE: Specify the Bitrate to capture at + -B/--peakbitrate PEAK_BITRATE: Specify the Peak Bitrate to capture at + --aspect ASPECT: Specify the aspect value + --audio-bitmask AUDIO-BITMASK: Specify the audio bitmask value + --bframes BFRAMES: Specify the bframes value + --dnrmode DNRMODE: Specify the dnr_mode value + --dnrspatial DNRSPATIAL: Specify the dnr_spatial value + --dnrtemporal DNRTEMPORAL: Specify the dnr_temporal value + --dnrtype DNRTYPE: Specify the dnr_type value + --framerate FRAMERATE: Specify the framerate value + --framespergop FRAMESPERGOP: Specify the framespergop value + --gopclosure GOPCLOSURE: Specify the gop_closure value + --pulldown PULLDOWN: Specify the pulldown value + --streamtype STREAMTYPE: Specify the stream_type value + + Config file related options: + -P/--profile PROFILE: Override defaults and command line values with the + config entries in the section labeled [PROFILE] from the + config file $settings{ConfigFileName}. + Examples: -P NTSC-DVD, -P PAL-DVD, --profile MY-SETTINGS + + You can specify this option multiple times and each successive + profile will overlay the defaults and any previous profiles. + You will not be able to create/update a profile if you do + specify multiple profiles. + -S/--save: save the current values as the defaults in + $settings{ConfigFileName}. + If -P/--profile PROFILE is specified, then those values that exist in + the specified profile will be updated. If the profile doesn't exist, + then it will be created, but will have all possible config items + defined in it. It will be your responsibility to hand check the + config file and remove any config items you do not want set for + that profile. + Any options specified on the command line will override options + defined in the config file. + +Notes: + If you specify both -i/--inputnum and -I/--inputname then + -i/--inputnum will take precedence. + + If you specify both -c/--channel and -F/--frequency then + -F/--frequency will take precedence. + + If you use a Profile, it has the ability to override all command line + arguments, so check your Profile first if things seem to be ignored. + +Defaults: + --duration $settings{RecordDuration} --input $settings{VideoDevice} --width $settings{VideoWidth} --height $settings{VideoHeight} --standard $settings{VideoStandard} + --type $settings{VideoType} --directory $settings{OutputDirectory} --output $settings{OutputFileName} + --directory-format "$settings{DirectoryFormatString}" --date-format "$settings{DateTimeFormatString}" + --inputnum $settings{InputNum} --inputname '$settings{InputName}' --freqtable $settings{FrequencyTable} + --set-msp-matrix $settings{SetMSPMatrix} --msp-sleep $settings{MSPSleep} --msp-input $settings{MSPInput} --msp-output $settings{MSPOutput} + --bitrate $settings{Bitrate} --peakbitrate $settings{PeakBitrate} --aspect $settings{Aspect} --audio-bitmask $settings{AudioBitmask} --bframes $settings{BFrames} + --dnrmode $settings{DNRMode} --dnrspatial $settings{DNRSpatial} --dnrtemporal $settings{DNRTemporal} --dnrtype $settings{DNRType} + --framerate $settings{Framerate} --framespergop $settings{FramesPerGOP} --gopclosure $settings{GOPClosure} --pulldown $settings{Pulldown} --streamtype $settings{StreamType} + --tuner-num $settings{TunerNum} + + config file = '$settings{ConfigFileName}' + + If Channel = $settings{Channel}, this would create: + $tmpDirectoryStr$settings{OutputFileName} + + Note: This script relies on Perl Modules: Video::Frequencies, Video::ivtv, + Config::IniFiles and Getopt::Long. +END_OF_USAGE + +# handle user input here +my %opts; +#getopts('c:t:o:hd:W:H:s:T:D:vi:I:f:F:LRb:B:P:S', \%opts); +GetOptions(\%opts, "channel|c=s", "duration|t=i", "output|o=s", "help|h", "input|d=s", "width|W=i", "height|H=i", "standard|s=s", + "type|T=s", "directory|D=s", "version|v", "inputnum|i=i", "inputname|I=s", "freqtable|f=s", "frequency|F=i", "list-freqtable|L", + "noreset|R", "bitrate|b=i", "peakbitrate|B=i", "profile|P=s@", "save|S", "aspect=i", "audio-bitmask=s", "bframes=i", "dnrmode=i", "dnrspatial=i", + "dnrtemporal=i", "dnrtype=i", "framerate=i", "framespergop=i", "gopclosure=i", "pulldown=i", + "streamtype=i", "no-record", "directory-format=s", "date-format=s", "debug", "list-channels", + "tuner-num=i", "list-inputs", "list-standards", "set-msp-matrix=i", "msp-input=i", "msp-output=i", "outputmpgfilename=s"); +if (scalar keys %opts == 0 && @ARGV == 0) +{ + usage(0, ""); +} +foreach my $option (sort keys %opts) +{ + my $found = 0; + foreach my $mapName (keys %mappings) + { + if ($option =~ /^($mappings{$mapName})$/) + { + $settings{$mapName} = $opts{$option}; + $found = 1; + print "$mapName = '$opts{$option}'\n" if $settings{Debug}; + } + } + if (!$found) + { + # handle the non-settings cases. + if ($option =~ /^(L|list-freqtable)$/) + { + my $errStr = "\nAvailable Frequency Mappings:\n"; + foreach my $name (sort keys %CHANLIST) + { + $errStr .= "$name\n"; + } + print "$versionStr\n$errStr"; + exit 0; + } + elsif ($option eq "list-channels") + { + my $errStr = "\nAvailable Channels for $settings{FrequencyTable}:\n"; + foreach my $name (sort { $a <=> $b } keys %{$CHANLIST{$settings{FrequencyTable}}}) + { + $errStr .= "$name\t= $CHANLIST{$settings{FrequencyTable}}->{$name}\n"; + } + print "$versionStr\n$errStr"; + exit 0; + } + elsif ($option =~ /^(no-record)$/) + { + $settings{DontRecord} = 1; + } + elsif ($option =~ /^(S|save)$/) + { + $settings{UpdateConfigFile} = 1; + } + elsif ($option =~ /^(P|profile)$/) + { + @profileNames = @{$opts{$option}}; + } + elsif ($option =~ /^(v|version)$/) + { + print "$versionStr\n"; + exit 0; + } + elsif ($option =~ /^(h|help)$/) + { + usage(0, ""); + } + elsif ($option =~ /^(list-inputs|list-standards)$/) + { + # do nothing for now since they will be handled later. + } + + else + { + usage(1, "-$option is an unknown option!"); + } + } +} + +if (@profileNames) +{ + # loop over all profiles the user specified. + foreach my $profileName (@profileNames) + { + print "profile = '$profileName'\n" if $settings{Debug}; + # for now the profile can not be "defaults". + if ($profileName eq "defaults") + { + error(1, "Profile = '$profileName' is invalid!"); + } + if (exists $configIni{$profileName}) + { + # update defaults/override command line arguments that exist in this profile. + my $profileUpdating = (((exists $opts{S} || exists $opts{save}) && @profileNames == 1) ? 1 : 0); + my $profile = $profileName; + + foreach my $arg (keys %mappings) + { + foreach my $option (split(/\|/, $mappings{$arg})) # handle the long/short command option versions + { + #print "arg = '$arg', option = '$option'\n" if $settings{Debug}; + if (exists $configIni{$profile}{$arg} && !($profileUpdating && exists $opts{$option})) + { + $settings{$arg} = $configIni{$profile}{$arg}; + print "settings{$arg} = '" . $settings{$arg} . "'\n" if $settings{Debug}; + last; + } + } + } + } + else + { + if ($settings{UpdateConfigFile} && @profileNames == 1) + { + print "Warning: Profile = '$profileName' will be created.\n" if ($settings{Debug}); + } + else + { + error(1, "Profile = '$profileName' does not exist! You must specify -S/--save to create it."); + } + } + } +} + +# verify input + +if (@ARGV) +{ + if (exists $opts{c} || exists $opts{channel}) + { + print "Warning: ignoring channel argument and using '$ARGV[0]' instead.\n"; + } + $settings{Channel} = $ARGV[0]; +} + +if (!$settings{DontRecord}) +{ + print "RecordDuration = $settings{RecordDuration}\n" if $settings{Debug}; + + if ($settings{VideoType} !~ /^(mpeg|yuv)$/) + { + error(1, "Video Type = '$settings{VideoType}' is invalid!"); + } + if ($settings{VideoType} eq "yuv") + { + # see if we need to change our defaults. + if (!exists $opts{o} && !exists $opts{output}) + { + $settings{OutputFileName} = "video.yuv"; + } + if (!exists $opts{d} && !exists $opts{input}) + { + if ( -e "/dev/.devfsd" ) + { + $settings{VideoDevice} = "/dev/v4l/yuv0"; + } + else + { + $settings{VideoDevice} = "/dev/yuv0"; + } + } + } +} + +if ( ! -c "$settings{VideoDevice}") +{ + error(1, "Video Dev = '$settings{VideoDevice}' is invalid! $!"); +} + +# now that the video device has been semi validated, we can use it to lookup +# the inputs, standards, etc. and use that for validating some of the following +# pieces of user input. +sysopen($tuner, $settings{VideoDevice}, O_RDWR) or die "Error unable to open '$settings{VideoDevice}': $!"; +my $tunerFD = fileno($tuner); + +# get the current capabilities. +@capabilities = $ivtvObj->getCapabilities($tunerFD); +if (@capabilities != keys %{$ivtvObj->{capIndexes}}) +{ + error(1, "getCapabilities() failed!"); +} +if ($capabilities[$ivtvObj->{capIndexes}{driver}] ne "ivtv") +{ + $settings{UsingIvtvDriver} = 0; # we can't use the ivtv "enhancements". + print "Warning: V4l2 driver = '$capabilities[$ivtvObj->{capIndexes}{driver}]' does not support the ivtv \"enhancements\"!\n"; + print " All codec related options will be ignored.\n\n"; +} + +my $i; + +# get the current video standard +$std = $ivtvObj->getStandard($tunerFD); +if ($std > 0) +{ + printf("Standard: 0x%08x\n",$std) if ($settings{Debug}); +} +else +{ + die "Error: getStandard() failed!\n"; +} + +# get the current input +$curinput = $ivtvObj->getInput($tunerFD); +if ($curinput < 0) +{ + die "Error: getInput() failed!\n"; +} +printf("Input: 0x%08x\n",$curinput) if ($settings{Debug}); + +my $done=0; +# Standards +for ($i=0; !$done; ++$i) +{ + my($index,$std_id,$name,$frameperiod_n,$frameperiod_d,$framelines) = $ivtvObj->enumerateStandard($tunerFD, $i); + if ($index == -1) + { + $done = 1; + } + else + { + printf("%d 0x%08x %s %d/%d %d\n",$index,$std_id,$name,$frameperiod_n,$frameperiod_d,$framelines) if ($settings{Debug}); + push @standards, [($name,$std_id)]; + $name2std{$name} = $std_id; + if( (($std_id & $std) == $std)) + { + $curstd = $name; + $curStandard = $std; + } + } +} + +if (exists $opts{'list-standards'}) +{ + print "$versionStr\n"; + print "Available Video Standards:\n"; + foreach my $standard (@standards) + { + print "$standard->[0]\n"; + } + exit 0; +} + +$done=0; +# Inputs +for ($i=0; !$done; ++$i) +{ + my($index,$name,$type,$audioset,$tuner,$std,$status) = $ivtvObj->enumerateInput($tunerFD, $i); + if ($index == -1) + { + $done = 1; + } + else + { + push @inputs, $name; + $name2input{$name} = $index; + } +} +$curinputName = $inputs[$curinput]; + +if (exists $opts{'list-inputs'}) +{ + print "$versionStr\n"; + print "Available Inputs:\n"; + my $counter = 0; + foreach my $input (@inputs) + { + print "$counter: $input\n"; + $counter++; + } + exit 0; +} + +if ($settings{UsingIvtvDriver}) +{ + # get the current Codec Info + @codecInfo = $ivtvObj->getCodecInfo($tunerFD); + if (@codecInfo != keys %{$ivtvObj->{codecIndexes}}) + { + error(1, "getCodecInfo() failed!"); + } + @newCodecInfo = $ivtvObj->getCodecInfo($tunerFD); + if (@newCodecInfo != keys %{$ivtvObj->{codecIndexes}}) + { + error(1, "getCodecInfo() failed!"); + } +} + +# finish validating the user input. + +if (!$settings{DontRecord}) +{ + if ($settings{RecordDuration} !~ /^(\d+)$/) + { + error(1, "Time = '$settings{RecordDuration}' is invalid!"); + } + + if ( ! -d "$settings{OutputDirectory}") + { + error(1, "Directory = '$settings{OutputDirectory}' is invalid! $!"); + } + + # assume for now we are only generating mpeg files. +# if (($settings{VideoType} eq "mpeg" && $settings{OutputFileName} !~ /^.+\.mpg$/) || ($settings{VideoType} eq "yuv" && $settings{OutputFileName} !~ /^.+\.yuv$/)) +# { +# error(1, "Output = '$settings{OutputFileName}' is invalid!"); +# } +# + if ($settings{DateTimeFormatString} !~ /^(\+((\%.)|.)+)$/) + { + usage(1, "Date Format String = '$settings{DateTimeFormatString}' is invalid!"); + } +} + +if ($settings{VideoWidth} !~ /^(\d+)$/) +{ + error(1, "Width = '$settings{VideoWidth}' is invalid!"); +} + +if ($settings{VideoHeight} !~ /^(\d+)$/) +{ + error(1, "Height = '$settings{VideoHeight}' is invalid!"); +} + +if (!exists $name2std{$settings{VideoStandard}}) +{ + my $validStandards = join(", ", keys(%name2std)); + error(1, "Video Standard = '$settings{VideoStandard}' is invalid!\nValid Standards are: $validStandards"); +} + +if (exists $opts{i} || exists $opts{inputnum}) +{ + if ($settings{InputNum} < 0 || $settings{InputNum} >= scalar(@inputs)) + { + error(1, "Video Input = '$settings{InputNum}' is invalid!\nValid Inputs are from 0 - " . int(scalar(@inputs) - 1)); + } + $settings{InputName} = $inputs[$settings{InputNum}]; +} + +if ((exists $opts{I} || exists $opts{inputname}) && !(exists $opts{i} || exists $opts{inputnum})) +{ + if (!exists $name2input{$settings{InputName}}) + { + my $validInputs = join(", ", @inputs); + error(1, "Video Input Name = '$settings{InputName}' is invalid!\nValid Input Names are: $validInputs"); + } + $settings{InputNum} = $name2input{$settings{InputName}}; +} + +if (!exists $CHANLIST{$settings{FrequencyTable}}) +{ + error(1, "Frequency Table = '$settings{FrequencyTable}' is invalid!"); +} + +# only validate the channel if the input is a tuner. +if ($inputs[$settings{InputNum}] =~ /Tuner/) +{ + if ($settings{TunerNum} !~ /^(\d)$/) + { + error(1, "TunerNum = '$settings{TunerNum}' is invalid!"); + } + if (exists $opts{F} || exists $opts{frequency} || $settings{Frequency}) # the user may have specified a Frequency in their config file + { + if ($settings{Frequency} !~ /^(\d+)$/) + { + error(1, "Frequency = '$settings{Frequency}' is invalid!"); + } + $settings{Channel} = "freq-$settings{Frequency}"; # make sure we output the channel part. + } + # now verify that the channel exists in the frequency table! + else + { + if (!$settings{Channel}) + { + error(1, "channel = '$settings{Channel}' is invalid!"); + } + # first verify the freqency table is appropriate for the standard (NTSC, PAL, SECAM), + # unless they specified the frequency to tune to. + if ($settings{FrequencyTable} !~ /^(custom|$settings{VideoStandard})/i) + { + error(1, "You specified Video Standard '$settings{VideoStandard}' which is incompatible with Frequency Table '$settings{FrequencyTable}'!"); + } + if (!exists $CHANLIST{$settings{FrequencyTable}}->{$settings{Channel}}) + { + error(1, "Channel = '$settings{Channel}' does not exist in Frequency Table '$settings{FrequencyTable}'!"); + } + } + + # get the current channel/frequency value. + my $Frequency; + if(($Frequency = $ivtvObj->getFrequency($tunerFD, $settings{TunerNum})) >= 0) + { + my $freq = ($Frequency * 1000) / 16; + print "freq = $freq\n" if ($settings{Debug}); + # find the associated channel. + if ((!exists $opts{F} && !exists $opts{frequency} && !$settings{Frequency}) && ($curstd eq $settings{VideoStandard}) ) + { + foreach my $chan (keys %{$CHANLIST{$settings{FrequencyTable}}}) + { + if ($CHANLIST{$settings{FrequencyTable}}->{$chan} == $freq) + { + $curChannel = $chan; + } + } + print "curChannel = $curChannel\n" if ($settings{Debug}); + } + else + { + $curFrequency = $freq; + } + } + else + { + die "Error: getFrequency() failed!\n"; + } +} +else +{ + # set the channel = "" so we know to ignore it. + $settings{Channel} = ""; +} + +if ($settings{UsingIvtvDriver}) +{ + # validate the Codec related stuff. + if ($settings{Bitrate} < $settings{minBitrate} || $settings{Bitrate} > $settings{maxBitrate}) + { + error(1, "Bitrate = '$settings{Bitrate}' is invalid!"); + } + if ($settings{PeakBitrate} <= $settings{Bitrate}) + { + error(1, "PeakBitrate can not be less than or equal to Bitrate!"); + } + elsif ($settings{PeakBitrate} < $settings{minPeakBitrate} || $settings{PeakBitrate} > $settings{maxPeakBitrate}) + { + error(1, "PeakBitrate = '$settings{PeakBitrate}' is invalid!"); + } + + if ($settings{VideoStandard} !~ /^(NTSC)/) + { + my $warn = 0; + if ($settings{Framerate} == 0) + { + $settings{Framerate} = 1; + $warn = 1; + } + if ($settings{FramesPerGOP} == 15) + { + $settings{FramesPerGOP} = 12; + $warn = 1; + } + if ($warn) + { + print "Warning: Setting Framerate/FramesPerGOP to PAL settings for Video Standard '$settings{VideoStandard}'!\n\nYou should either specify on the command line or in the ~/.ivtvrc config file.\n"; + } + } + elsif ($settings{VideoStandard} =~ /^(NTSC)/) + { + my $warn = 0; + if ($settings{Framerate} == 1) + { + $settings{Framerate} = 0; + $warn = 1; + } + if ($settings{FramesPerGOP} == 12) + { + $settings{FramesPerGOP} = 15; + $warn = 1; + } + if ($warn) + { + print "Warning: Setting Framerate/FramesPerGOP to NTSC settings for Video Standard '$settings{VideoStandard}'!\n\nYou should either specify on the command line or in the ~/.ivtvrc config file.\n"; + } + } + + if ($settings{SetMSPMatrix} !~ /^(0|1)$/) + { + error(1, "SetMSPMatrix = '$settings{SetMSPMatrix}' is invalid! It can only be 0 or 1."); + } + if ($settings{MSPInput} < 1 || $settings{MSPInput} > 8) + { + error(1, "MSPInput = '$settings{MSPInput}' is invalid! It can only be 1 - 8."); + } + if ($settings{MSPOutput} < 0 || $settings{MSPOutput} > 3) + { + error(1, "MSPOutput = '$settings{MSPOutput}' is invalid! It can only be 0 - 3."); + } +} + +# update the config file if the user wants us to. +if ($settings{UpdateConfigFile}) +{ + my $profile; + if (@profileNames > 1) + { + print "Warning: Not updating config file as you have more than 1 profile specified!\n"; + } + elsif (@profileNames == 1) + { + $profile = $profileNames[0]; + } + else + { + $profile = "defaults"; + } + if ($profile) + { + my $createProfile = (exists $configIni{$profile} ? 0 : 1); + print "Creating Profile = '$profile': $createProfile\n" if ($settings{Debug}); + + if (!$settings{UseConfigFile}) + { + # we have to create the config file and tie to it. + tie %configIni, 'Config::IniFiles', () or die "Error: Initializing config file '$settings{ConfigFileName}' failed! $!\n"; + + # now set the name to work with. + tied(%configIni)->SetFileName($settings{ConfigFileName}) or die "Error: Setting config file to '$settings{ConfigFileName}' failed! $!\n"; + + $configIni{$profile} = {}; # make sure the section exists. + } + + foreach my $arg (keys %mappings) + { + foreach my $option (split(/\|/, $mappings{$arg})) # handle the long/short command option versions + { + if (exists $configIni{$profile}{$arg} || $createProfile || exists $opts{$option}) + { + $configIni{$profile}{$arg} = $settings{$arg}; + print "configIni{$profile}{$arg} = '" . $settings{$arg} . "'\n" if $settings{Debug}; + last; + } + } + } + + # write the config file out. + tied(%configIni)->RewriteConfig or die "Error: Writing config file '$settings{ConfigFileName}' failed! $!\n"; + } +} + +# this hash keeps track of those values I have to set back. +my %changedSettings = ( + resolution => 0, + standard => 0, + VideoType => 0, + InputNum => 0, + Channel => 0, + Frequency => 0, + codec => 0, + ); + +my $directoryName; +if (!$settings{DontRecord}) +{ + # make directory + #$directoryName = formatDirectoryString(); + #$result=`mkdir -p $directoryName`; + $directoryName = $settings{DirectoryFormatString}; +} + +# change the channel +if ($inputs[$settings{InputNum}] =~ /Tuner/) +{ + if (exists $opts{F} || exists $opts{frequency} || $settings{Frequency}) + { + if ($settings{Frequency} != $curFrequency) + { + $changedSettings{Frequency} = 1; + tuneFrequency($settings{Frequency}); + } + } + else + { + if ($curstd ne $settings{VideoStandard}) + { + # we have to set the channel regardless. + # but we want to tune back to the previous frequency. + $changedSettings{Frequency} = 1; + changeChannel($settings{Channel}); + } + elsif ($settings{Channel} ne $curChannel) + { + # otherwise we just changeChannel and restore the previous channel. + $changedSettings{Channel} = 1; + changeChannel($settings{Channel}); + } + } +} + +# set the video standard +if ($settings{VideoStandard} ne $curstd) +{ + $changedSettings{standard} = 1; + change_standard(); + + # see if we have to re-program the msp matrix + if ($settings{UsingIvtvDriver}) + { + if ($settings{SetMSPMatrix}) + { + print "Setting msp matrix: input = $settings{MSPInput}, output = $settings{MSPOutput}\n" if $settings{Debug}; + sleep ($settings{MSPSleep}); # sleep for 2 seconds to let card settle down. + $result = $ivtvObj->mspMatrixSet($tunerFD, $settings{MSPInput}, $settings{MSPOutput}); + if (not defined $result) + { + die "Error calling mspMatrixSet!\n"; + } + if (!$result) + { + die "Error in mspMatrixSet ioctl call!\n"; + } + } + } +} + +# set the input +if ($settings{InputNum} != $curinput || $settings{InputName} ne $curinputName) +{ + $changedSettings{InputNum} = 1; + if (!(exists $opts{i} || exists $opts{inputnum} || exists $opts{I} || exists $opts{inputname})) # our defaults are different than the current values! + { + ## print "Warning: Changing input from $curinputName to $settings{InputName}\n"; + &writelog("tvrecording: Changing input from $curinputName to $settings{InputName}"); + } + change_input(); +} + +# set the capture type + +# store the current width,height so we can restore afterwards +my ($oldWidth, $oldHeight) = $ivtvObj->getResolution($tunerFD); +print "oldWidth = '$oldWidth', oldHeight = '$oldHeight'\n" if ($settings{Debug}); + +if ($settings{VideoWidth} != $oldWidth || $settings{VideoHeight} != $oldHeight) +{ + $changedSettings{resolution} = 1; +} + +# specify the width,height to capture +if ($changedSettings{resolution}) +{ + $result = $ivtvObj->setResolution($tunerFD, $settings{VideoWidth}, $settings{VideoHeight}); + if (not defined $result) + { + die "Error calling setResolution!\n"; + } + if (!$result) + { + die "Error in setResolution ioctl call!\n"; + } +} + +if ($settings{UsingIvtvDriver}) +{ + # specify the codec options to capture mpeg's at. + foreach my $codecName (keys %codecMappings) + { + my $codecIndex = $ivtvObj->{codecIndexes}{$codecMappings{$codecName}}; + if ($codecInfo[$codecIndex] != $settings{$codecName}) + { + $changedSettings{codec} = 1; + $newCodecInfo[$codecIndex] = $settings{$codecName}; + print "new $codecName = '$settings{$codecName}', old $codecName = '$codecInfo[$codecIndex]'\n" if $settings{Debug}; + } + } +} + +if ($changedSettings{codec}) +{ + $result = $ivtvObj->setCodecInfo($tunerFD, @newCodecInfo); + if (!$result) + { + die "Error calling setCodecInfo()!\n"; + } +} + +if (!$settings{DontRecord}) +{ + # capture the video/audio to video.mpg + #print "directoryName:$directoryName, RecordDuration:$settings{RecordDuration},OutputFileName:$settings{OutputFileName}:tuner:$tuner ,OutputMPGFileName:$settings{OutputMPGFileName} \n"; + #directoryName:, RecordDuration:60,OutputFileName:/tv/JOAX-20040615-1411-000.MPG:tuner:GLOB(0x8224838) ,OutputMPGFileName: + captureVideo(directoryName => $directoryName, RecordDuration => $settings{RecordDuration}, + OutputFileName => $settings{OutputFileName}, tuner => $tuner ,OutputMPGFileName => $settings{OutputMPGFileName}); +} + +if ($settings{ResetCardSettings} && !$settings{DontRecord}) +{ + # restore Codec values + if ($changedSettings{codec}) + { + $result = $ivtvObj->setCodecInfo($tunerFD, @codecInfo); + if (!$result) + { + die "Error calling setCodecInfo()!\n"; + } + } + + # restore the previous width,height settings + if ($changedSettings{resolution}) + { + $result = $ivtvObj->setResolution($tunerFD, $oldWidth, $oldHeight); + if (not defined $result) + { + die "Error calling setResolution!\n"; + } + if (!$result) + { + die "Error in setResolution ioctl call!\n"; + } + } + + # restore the previous input setting + if ($changedSettings{InputNum}) + { + # reset back to the old input name + $settings{InputName} = $curinputName; + change_input(); + } + + # restore the previous video standard + if ($changedSettings{standard}) + { + $settings{VideoStandard} = $curstd; + change_standard(); + + # see if we have to re-program the msp matrix + if ($settings{UsingIvtvDriver}) + { + if ($settings{SetMSPMatrix}) + { + print "Setting msp matrix: input = $settings{MSPInput}, output = $settings{MSPOutput}\n" if $settings{Debug}; + sleep ($settings{MSPSleep}); # sleep for 2 seconds to let card settle down. + $result = $ivtvObj->mspMatrixSet($tunerFD, $settings{MSPInput}, $settings{MSPOutput}); + if (not defined $result) + { + die "Error calling mspMatrixSet!\n"; + } + if (!$result) + { + die "Error in mspMatrixSet ioctl call!\n"; + } + } + } + } + + # restore the previous channel + if ($changedSettings{Channel}) + { + changeChannel($curChannel); + } + if ($changedSettings{Frequency}) + { + tuneFrequency($curFrequency); + } +} + +# close the tuner device +close($tuner); + + +exit 0; + +# usage(returnValue, ErrorString) +# returnValue = 1 or 0 +# ErrorString = message you want to tell the user, but only if returnValue = 1. +sub usage +{ + my $errorCode = shift; + my $error = shift; + + print $usageStr; + print "\nError: $error\n" if ($errorCode == 1); + print "$error\n" if ($errorCode == 2); + + exit $errorCode; +} + +# error(returnValue, ErrorString) +# returnValue = 1 or 0 +# ErrorString = message you want to tell the user. +sub error +{ + my $errorCode = shift; + my $error = shift; + + print "$versionStr"; + print "\nError: $error\n"; + + exit $errorCode; +} + +# changes the input to $settings{InputNum} as long as it isn't = $curinput +sub change_input { + my $preinput = $name2input{$settings{InputName}}; + if($preinput != $curinput) + { + $curinput = $preinput; + print "input now $settings{InputName}, #$preinput\n" if ($settings{Debug}); + my $result = $ivtvObj->setInput($tunerFD, $preinput); + if (!$result) + { + die "Error: setInput($preinput) failed!\n"; + } + } +} + +# changes the video standard to $settings{VideoStandard} as long as it isn't = $curstd +sub change_standard { + my $standard = $name2std{$settings{VideoStandard}}; + if($standard != $curStandard) + { + $curStandard = $standard; + print "standard now $settings{VideoStandard}, #$standard\n" if ($settings{Debug}); + my $result = $ivtvObj->setStandard($tunerFD, $standard); + if (!$result) + { + die "Error: setStandard($standard) failed!\n"; + } + } +} + +# changes the channel +# takes the channel to change +sub changeChannel +{ + my $ch = shift; + my $freq = $CHANLIST{$settings{FrequencyTable}}->{$ch}; + my $driverf = ($freq * 16)/1000; + + print "Ch.$ch: $freq $driverf\n" if ($settings{Debug}); + + if (!$ivtvObj->setFrequency($tunerFD, $settings{TunerNum}, $driverf)) + { + die "Error: changeChannel($ch) failed!\n"; + } +} + +# tunes to the specified frequency +# takes the frequency to tune to +sub tuneFrequency +{ + my $freq = shift; + my $driverf = ($freq * 16)/1000; + + print "freq: $freq $driverf\n" if ($settings{Debug}); + + if (!$ivtvObj->setFrequency($tunerFD, $settings{TunerNum}, $driverf)) + { + die "Error: tuneFrequency($freq) failed!\n"; + } +} + +my $done = 0; + +sub catch_alarm { + $done = 1; +} +sub get_next_file_name +{ + + my $file_name = shift(@_); + $file_name =~ m/^(.+?)\-(\d{4})(\d{2})(\d{2})\-(\d{2})(\d{2})\-(\d{3})\.(.+?)$/; + + my $station = $1; + my $year = $2; + my $month = $3; + my $day = $4; + my $hour = $5; + my $min = $6; + my $seq = $7; + my $ext = $8; + $seq++; + my $new_file_name = sprintf("%s-%04d%02d%02d-%02d%02d-%03d.%s", + $station,$year,$month,$day,$hour,$min,$seq,$ext); + return $new_file_name +} + +# does the actual video capturing work. +# takes directoryName, RecordDuration, OutputFileName, tuner +sub captureVideo +{ + my %args = ( @_ ); + my $directoryName = $args{directoryName}; + my $RecordDuration = $args{RecordDuration}; + my $OutputFileName = $args{OutputFileName}; + my $tuner = $args{tuner}; + my $fname = "$directoryName/$OutputFileName"; +# "OutputMPGFileName" => "outputmpgfilename", +# my $OutputFileName = $args{OutputMPGFileName}; + my $OutputFileName = $args{OutputFileName}; +# my $fname = "$directoryName/$OutputFileName"; + my $fname = $args{OutputFileName}; + + + # setup global variables, signal handlers, etc. + + $SIG{ALRM} = \&catch_alarm; + $SIG{INT} = \&catch_alarm; # handle Ctrl-C + + # turn off file buffering. + #$|=1; + + # open the file for writing. + + + + sysopen(OUTPUT, "$fname", O_CREAT | O_WRONLY | O_LARGEFILE) or die "Error creating file '$fname': $!\n"; + + alarm($RecordDuration); + my $buf = ""; + my $len = 0; + while (!$done && read($tuner, $buf, 16384)) + { + $len += length($buf); +# if ($len >= $max_file_size ) +# { +# close(OUTPUT); +# $OutputFileName = get_next_file_name($OutputFileName); +## $fname = "$directoryName/$OutputFileName"; +# $fname = "$OutputFileName"; +# &writelog("tvrecording switch next clip.$fname"); +# sysopen(OUTPUT, "$fname", O_CREAT | O_WRONLY | O_LARGEFILE) +# or die "Error creating file '$fname': $!\n"; +# $len = 0; +# } + + # read from the device and write to the file. + print OUTPUT $buf; + } + + # close the file + close(OUTPUT); + + #$|=0; # turn file buffering back on. +} + +# returns the formatted directory string +sub formatDirectoryString +{ + my $temp = $settings{DirectoryFormatString}; + my $result = $settings{OutputDirectory}; + my %lookupTable = ( + "d" => `/bin/date "$settings{DateTimeFormatString}"`, + "I" => $settings{InputName}, + "c" => $settings{Channel}, + ); + + # fixup the InputName value + $lookupTable{I} =~ s/\s/_/g; + # cleanup the trailing slash on the date + chomp $lookupTable{d}; + + foreach my $option ("d", "I", "c") + { + $temp =~ s/\%$option/$lookupTable{$option}/g; + } + + $result .= "/" . ($temp ? "$temp/" : ""); + + return $result; +} + + + + + Index: trunk/install/perl/getxml2db.pl =================================================================== --- trunk/install/perl/getxml2db.pl (リビジョン 109) +++ trunk/install/perl/getxml2db.pl (リビジョン 1) @@ -19,10 +19,8 @@ use DBI; use DBD::Pg; -use DBD::SQLite; -use Digest::MD5 qw(md5_hex); $path = $0; $path =~ s/getxml2db.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -40,43 +38,28 @@ } -# http://sites.google.com/site/syobocal/spec/cal_chk-php -#if ($ARGV[0] eq "long"){ -# $uri="http://cal.syoboi.jp/cal_chk.php"; -# #$uri="http://syobocal.orz.hm/cal_chk.php"; -# &writelog("getxml2db use long mode."); -#}else{ -# $uri="http://cal.syoboi.jp/cal_chk.xml"; -# #$uri="http://syobocal.orz.hm/cal_chk.xml"; -#} -$uri = "http://cal.syoboi.jp/cal_chk.php?days="; -$uri .= ($ARGV[0] eq "long")? 14: 7; - -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; - -$dbh->{AutoCommit} = 0; - -# If-Modified-Since使うように変更#2008/11/14 -my $CacheDir = '/tmp/shobocal'; -if (! -e $CacheDir) { - mkdir $CacheDir or die "cannot create $CacheDir: $!"; -} -my $cache = sprintf("%s/%s.xml", $CacheDir, Digest::MD5::md5_hex($uri)); -LWP::Simple::mirror($uri, $cache) or die "cannot get content from $uri"; -open(SHOBO, "<$cache"); -my (@line) = ; -close(SHOBO); -#my ($content) = get("$uri"); -#if ($content eq ""){ -#&writelog("getxml2db no responce from $uri, exit:"); -# exit;#しょぼかるが落ちているなど -#} -#my (@line) = split(/\n/, $content); +if ($ARGV[0] eq "long"){ + $uri="http://cal.syoboi.jp/cal_chk.php"; + &writelog("getxml2db use long mode."); +}else{ + $uri="http://cal.syoboi.jp/cal_chk.xml"; +} + + + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; + +my ($content) = get("$uri"); +if ($content eq ""){ +&writelog("getxml2db no responce from $uri, exit:"); + exit;#しょぼかるが落ちているなど +} + +my (@line) = split(/\n/, $content); foreach(@line){ -s/\xef\xbd\x9e/\xe3\x80\x9c/g; #wavedash -s/\xef\xbc\x8d/\xe2\x88\x92/g; #hyphenminus -s/&#([0-9A-Fa-f]{2,6});/(chr($1))/eg; #'遊戯王5D's'とかの数値参照対応を - -Jcode::convert(\$_,'euc','utf8'); + +Jcode::convert(\$_,'euc'); # @@ -85,9 +68,7 @@ s/\"\/>/\" /i; s/\"[\s]/\";\n/gio; -s/\'/\\'/gio; s/\"/\'/gio; -#s/[\w]*=/\$item{$&}=/gio; -#s/\=}=/}=/gio; -s/(\w+)=/\$item{$1}=/gio;#by foltiaBBS +s/[\w]*=/\$item{$&}=/gio; +s/\=}=/}=/gio; #$item{PID}='21543'; @@ -102,35 +83,37 @@ #$item{ProgComment}=''; eval("$_"); -#Jcode::convert(\$item{Title},'euc'); - +Jcode::convert(\$item{Title},'euc'); $programtitlename = $item{Title}; -$programtitlename =~ s/\<\;//gi; -$programtitlename =~ s/\&\;/\&/gi; -# $programtitle = $dbh->quote($programtitlename); - $programtitle = $programtitlename; - -#Jcode::convert(\$item{ChName},'euc'); -#Jcode::convert(\$item{SubTitle},'euc'); - -#$programSubTitle = $dbh->quote($item{SubTitle}); -$programSubTitle = $item{SubTitle}; +$programtitle = $dbh->quote($item{Title}); +#print "$item{Title}\n"; +#print "$item{TID}\n"; +Jcode::convert(\$item{ChName},'euc'); +#print "$item{ChName}\n"; +Jcode::convert(\$item{SubTitle},'euc'); +$programSubTitle = $dbh->quote($item{SubTitle}); $programSubTitle =~ s/\<\;//gi; -$programSubTitle =~ s/\&\;/\&/gi; -# $programSubTitle = $dbh->quote($programSubTitle); - + +#print "$item{SubTitle}\n"; +#print "$item{Count}\n"; $offsetmin = $item{StOffset}/60; +#print "Offset:$offsetmin (min)\n"; +#print "$item{EdTime}/$item{StTime}\n"; $edtime = &syobocaldate2foltiadate($item{EdTime}); $sttime = &syobocaldate2foltiadate($item{StTime}); +#print "$sttime-$edtime\n"; $length = &calclength($sttime,$edtime); $recstartdate = &calcoffsetdate($sttime ,$offsetmin ); $recenddate = &calcoffsetdate($edtime ,$offsetmin ); +#print "$recstartdate-$recenddate\n"; +#print "Length:$length(min)\n"; $stationid = &getstationid($item{ChName}); +#print "StationID:$stationid \n"; #サブタイトル追加------------------------------------------------- #番組があるか確認 - $sth = $dbh->prepare($stmt{'getxml2db.1'}); - $sth->execute($item{TID}); +$DBQuery = "SELECT count(*) FROM foltia_program WHERE tid = '$item{TID}'"; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @titlecount= $sth->fetchrow_array; @@ -140,19 +123,23 @@ #200412012359 $nomalstarttime = substr($sttime,8,4); - - $sth = $dbh->prepare($stmt{'getxml2db.2'}); - $oserr = $sth->execute($item{TID}, $programtitle, '', $nomalstarttime, $length, '', '', 3, 1, '', ''); - &writelog("getxml2db ADD TV Progtam:$item{TID}:$programtitle"); +$DBQuery = "insert into foltia_program values ($item{TID},$programtitle,'','$nomalstarttime','$length','','','3','1','')"; + $sth = $dbh->prepare($DBQuery); +$sth->execute(); +&writelog("getxml2db ADD TV Progtam:$item{TID}:$programtitle"); + + }else{ #2006/2/26 #あったら、タイトル確認して - $sth = $dbh->prepare($stmt{'getxml2db.3'}); - $sth->execute($item{TID}); +$DBQuery = "SELECT title FROM foltia_program WHERE tid = '$item{TID}'"; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @titlearray = $sth->fetchrow_array; #更新などされてたらupdate #print "$titlearray[0] / $programtitle\n"; if ($titlearray[0] ne "$programtitlename" ){ - $sth = $dbh->prepare($stmt{'getxml2db.4'}); - $oserr = $sth->execute($programtitle, $item{TID}); + $DBQuery = "UPDATE foltia_program SET title = $programtitle where tid = '$item{TID}' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); &writelog("getxml2db UPDATE TV Progtam:$item{TID}:$programtitle"); }#end if update @@ -161,6 +148,7 @@ #PIDがあるか確認 - $sth = $dbh->prepare($stmt{'getxml2db.5'}); - $sth->execute($item{'TID'}, $item{'PID'}); +$DBQuery = "SELECT count(*) FROM foltia_subtitle WHERE tid = '$item{TID}' AND pid = '$item{PID}' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @subticount= $sth->fetchrow_array; if ($subticount[0] >= 1){ @@ -170,10 +158,30 @@ #UPDATE foltia_subtitle SET stationid = '42',countno = '8',subtitle = '京都行きます' ,startdatetime = '200503010035' ,enddatetime = '200503010050',startoffset = '0' ,lengthmin = '15' WHERE tid = '550' AND pid = '26000' if ($item{Count} == ""){ - $sth = $dbh->prepare($stmt{'getxml2db.6'}); - $oserr = $sth->execute($stationid, undef, $programSubTitle, $recstartdate, $recenddate, $offsetmin, $length, $item{'TID'}, $item{'PID'}); -}else{ - $sth = $dbh->prepare($stmt{'getxml2db.7'}); - $oserr = $sth->execute($stationid, $item{'Count'}, $programSubTitle, $recstartdate, $recenddate, $offsetmin, $length, $item{'TID'}, $item{'PID'}); - } + + $DBQuery = "UPDATE foltia_subtitle SET + stationid = '$stationid', + countno = null, + subtitle = $programSubTitle , + startdatetime = '$recstartdate' , + enddatetime = '$recenddate', + startoffset = '$offsetmin' , + lengthmin = '$length' + WHERE tid = '$item{TID}' AND pid = '$item{PID}' "; + +}else{ + + $DBQuery = "UPDATE foltia_subtitle SET + stationid = '$stationid', + countno = '$item{Count}', + subtitle = $programSubTitle , + startdatetime = '$recstartdate' , + enddatetime = '$recenddate', + startoffset = '$offsetmin' , + lengthmin = '$length' + WHERE tid = '$item{TID}' AND pid = '$item{PID}' "; +} + $sth = $dbh->prepare($DBQuery); + $sth->execute(); + # @subtitledata= $sth->fetchrow_array; }else{ #なければ追加 @@ -182,11 +190,13 @@ #そのままキューに入る形で if ($item{Count} eq ""){ - $sth = $dbh->prepare($stmt{'getxml2db.8'}); - $oserr = $sth->execute($item{'PID'}, $item{'TID'}, $stationid, undef, $programSubTitle, $recstartdate, $recenddate, $offsetmin, $length); + $DBQuery = "insert into foltia_subtitle values ( '$item{PID}','$item{TID}','$stationid',null,$programSubTitle,'$recstartdate','$recenddate','$offsetmin' ,'$length')"; }else{ - $sth = $dbh->prepare($stmt{'getxml2db.9'}); - $oserr = $sth->execute($item{'PID'}, $item{'TID'}, $stationid, $item{'Count'}, $programSubTitle, $recstartdate, $recenddate, $offsetmin, $length); + $DBQuery = "insert into foltia_subtitle values ( '$item{PID}','$item{TID}','$stationid','$item{Count}',$programSubTitle,'$recstartdate','$recenddate','$offsetmin' ,'$length')"; } -} + $sth = $dbh->prepare($DBQuery); + $sth->execute(); + # @subtitledata= $sth->fetchrow_array; +} + #print "$DBQuery\n\n\n"; @@ -198,4 +208,6 @@ }#foreach -$oserr = $dbh->commit; + ## $dbh->disconnect(); + + Index: trunk/install/perl/schedulecheck.pl =================================================================== --- trunk/install/perl/schedulecheck.pl (リビジョン 111) +++ trunk/install/perl/schedulecheck.pl (リビジョン 1) @@ -14,5 +14,4 @@ use DBI; use DBD::Pg; -use DBD::SQLite; use Schedule::At; use Time::Local; @@ -20,5 +19,5 @@ $path = $0; $path =~ s/schedulecheck.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -30,12 +29,17 @@ #予約番組探し -$now = &epoch2foldate(time()); +$now = &epoch2foldate(`date +%s`); $now = &epoch2foldate($now); $checkrangetime = $now + 15*60;#15分後まで $checkrangetime = &epoch2foldate($checkrangetime); -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; -$sth = $dbh->prepare($stmt{'schedulecheck.1'}); +$DBQuery = "SELECT count(*) FROM foltia_tvrecord "; + + + $sth = $dbh->prepare($DBQuery); $sth->execute(); @titlecount= $sth->fetchrow_array; @@ -44,5 +48,7 @@ exit; }else{ - $sth = $dbh->prepare($stmt{'schedulecheck.2'}); + +$DBQuery = "SELECT tid ,stationid FROM foltia_tvrecord "; + $sth = $dbh->prepare($DBQuery); $sth->execute(); while (($tid,$stationid ) = $sth->fetchrow_array()) { @@ -53,5 +59,4 @@ }#while -#EPG更新 -system("$toolpath/perl/epgimport.pl"); + } Index: trunk/install/perl/addpidatq.pl =================================================================== --- trunk/install/perl/addpidatq.pl (リビジョン 94) +++ trunk/install/perl/addpidatq.pl (リビジョン 1) @@ -14,5 +14,4 @@ use DBI; use DBD::Pg; -use DBD::SQLite; use Schedule::At; use Time::Local; @@ -20,5 +19,5 @@ $path = $0; $path =~ s/addpidatq.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -37,45 +36,36 @@ #DB検索(PID) -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; -$sth = $dbh->prepare($stmt{'addpidatq.1'}); -$sth->execute($pid); +$DBQuery = "SELECT count(*) FROM foltia_subtitle WHERE pid = '$pid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @titlecount= $sth->fetchrow_array; if ($titlecount[0] == 1 ){ - $sth = $dbh->prepare($stmt{'addpidatq.2'}); - $sth->execute($pid); + +$DBQuery = "SELECT bitrate FROM foltia_tvrecord , foltia_subtitle WHERE foltia_tvrecord.tid = foltia_subtitle.tid AND pid='$pid' "; + $sth = $dbh->prepare($DBQuery); +$sth->execute(); @titlecount= $sth->fetchrow_array; $bitrate = $titlecount[0];#ビットレート取得 -if ($titlecount[1] >= 1){ - $usedigital = $titlecount[1];#デジタル優先フラグ -}else{ - $usedigital = 0; -} #PID抽出 - $now = &epoch2foldate(time()); +$now = &epoch2foldate(`date +%s`); + +$DBQuery = "SELECT stationrecch FROM foltia_station,foltia_subtitle WHERE foltia_subtitle.pid = '$pid' AND foltia_subtitle.stationid = foltia_station.stationid "; + #stationIDからrecch - $stationh = $dbh->prepare($stmt{'addpidatq.3'}); - $stationh->execute($pid); - @stationl = $stationh->fetchrow_array(); + $stationh = $dbh->prepare($DBQuery); + $stationh->execute(); +@stationl = $stationh->fetchrow_array; $recch = $stationl[0]; -if ($recch eq ""){ - &writelog("addpidatq ERROR recch is NULL:$stmt{'addpidatq.3'}."); - exit 1; -} -if ($stationl[1] => 1){ - $digitalch = $stationl[1]; -}else{ - $digitalch = 0; -} -if ($stationl[2] => 1){ - $digitalstationband = $stationl[2]; -}else{ - $digitalstationband = 0; -} - $sth = $dbh->prepare($stmt{'addpidatq.4'}); - $sth->execute($pid); + +$DBQuery = "SELECT * FROM foltia_subtitle WHERE pid='$pid' "; + $sth = $dbh->prepare($DBQuery); +$sth->execute(); ($pid , $tid , @@ -119,11 +109,11 @@ } -Schedule::At::add (TIME => "$atdateparam", COMMAND => "$toolpath/perl/recwrap.pl $recch $reclength $bitrate $tid $countno $pid $stationid $usedigital $digitalstationband $digitalch" , TAG => "$pid"."_R"); - &writelog("addpidatq TIME $atdateparam COMMAND $toolpath/perl/recwrap.pl $recch $reclength $bitrate $tid $countno $pid $stationid $usedigital $digitalstationband $digitalch"); +Schedule::At::add (TIME => "$atdateparam", COMMAND => "$toolpath/perl/recwrap.pl $recch $reclength $bitrate $tid $countno $pid" , TAG => "$pid"."_R"); + &writelog("addpidatq TIME $atdateparam COMMAND $toolpath/perl/recwrap.pl $recch $reclength $bitrate $tid $countno $pid"); }#end #もし新開始時刻が15分移譲先なら再キュー }else{ -&writelog("addpidatq drop:expire $pid $startafter $now $startdatetime"); +&writelog("addpidatq drop:expire $pid $startafter $now $startdatetime"); }#放送が未来の日付なら Index: trunk/install/perl/xmltv2foltia.pl =================================================================== --- trunk/install/perl/xmltv2foltia.pl (リビジョン 134) +++ trunk/install/perl/xmltv2foltia.pl (リビジョン 1) @@ -4,11 +4,13 @@ # http://www.dcc-jpl.com/soft/foltia/ # -# xmltv2foltia.pl -# -# XMLTV日本語版形式のXMLを受け取り、EPGデータベースに挿入します。 -# アナログ時代はXMLTVを利用していましたが、現在はepgimport.plを使用します。 -# -# usage -# cat /tmp/__27-epg.xml | /home/foltia/perl/xmltv2foltia.pl +#xmltv2foltia.pl +#XMLTV日本語版の出力するXMLを受け取り、EPGデータベースに挿入します。 +#XMLTVは +# http://www.systemcreate-inc.com/gsxr/pc/mythtv.html#patches +#のパッチをあてたものを想定しています。オリジナルと比較して、サブタイトルや内容など +#より秀才な内容を取得できます。 +# +# usage;perl /usr/bin/tv_grab_jp | ./xmltv2foltia.pl +# # # DCC-JPL Japan/foltia project @@ -16,18 +18,17 @@ # -#use LWP::Simple; +use LWP::Simple; #use Encode qw(from_to); #use encoding 'euc-jp', STDIN=>'utf8', STDOUT=>'euc-jp' ; # 標準入力:utf8 # http://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html use Jcode; -#use Data::Dumper; +# use Data::Dumper; use Time::Local; use DBI; use DBD::Pg; -use DBD::SQLite; $path = $0; $path =~ s/xmltv2foltia.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -36,17 +37,14 @@ $currentworkdate = "" ; $currentworkch = "" ; -$today = strftime("%Y%m%d", localtime); -$todaytime = strftime("%Y%m%d%H%M", localtime); -@deleteepgid = (); +$today =`date "+%Y%m%d"`; +$todaytime =`date "+%Y%m%d%H%M"`; # DB Connect -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; while(<>){ #print $_; -s/\xef\xbd\x9e/\xe3\x80\x9c/g; #wavedash -s/\xef\xbc\x8d/\xe2\x88\x92/g; #hyphenminus -s/&#([0-9A-Fa-f]{2,6});/(chr($1))/eg; #'遊戯王5D's'とかの数値参照対応を - Jcode::convert(\$_,'euc','utf8'); # from_to($_, "utf8","euc-jp"); @@ -68,4 +66,12 @@ eval("$_"); #print Dumper($_) ; + +}elsif(/【無】こんなミニ番組があり、タイトル空白になってしまうことがある - $item{title} = $titlebackup; - } #print Dumper($_) ; #print "$result \n"; @@ -150,37 +147,4 @@ chomp(); $item{category} = &removetag($_); - - if ($item{category} =~ /情報/){ - $item{category} = "information"; - }elsif ($item{category} =~ /趣味・実用/){ - $item{category} = "hobby"; - }elsif ($item{category} =~ /教育/){ - $item{category} = "education"; - }elsif ($item{category} =~ /音楽/){ - $item{category} = "music"; - }elsif ($item{category} =~ /演劇/){ - $item{category} = "stage"; - }elsif ($item{category} =~ /映画/){ - $item{category} = "cinema"; - }elsif ($item{category} =~ /バラエティ/){ - $item{category} = "variety"; - }elsif ($item{category} =~ /ニュース・報道/){ - $item{category} = "news"; - }elsif ($item{category} =~ /ドラマ/){ - $item{category} = "drama"; - }elsif ($item{category} =~ /ドキュメンタリー・教養/){ - $item{category} = "documentary"; - }elsif ($item{category} =~ /スポーツ/){ - $item{category} = "sports"; - }elsif ($item{category} =~ /キッズ/){ - $item{category} = "kids"; - }elsif ($item{category} =~ /アニメ・特撮/){ - $item{category} = "anime"; - }elsif ($item{category} =~ /その他/){ - $item{category} = "etc"; - }else{ - $item{category} = "etc"; - } - #print Dumper($_) ; #print "$result \n"; @@ -189,13 +153,13 @@ }elsif(/<\/programme>/){ #登録処理はココで -#&writelog("xmltv2foltia DEBUG call chkerase $item{'start'},$item{'channel'}"); -#旧仕様 #&chkerase($item{'start'}, $item{'channel'}); - &replaceepg($item{'start'}, $item{'channel'},$item{'stop'}); - if ($item{'subtitle'} ne "" ){ - $registdesc = $item{'subtitle'}." ".$item{'desc'}; +#&writelog("xmltv2foltia DEBUG call chkerase $item{start},$item{channel}"); + +&chkerase($item{start},$item{channel}); +if ($item{subtitle} ne "" ){ + $registdesc = $item{subtitle}." ".$item{desc}; }else{ - $registdesc = $item{'desc'}; + $registdesc = $item{desc}; } - ®istdb($item{'start'},$item{'stop'},$item{'channel'},$item{'title'},$registdesc ,$item{'category'}); +®istdb($item{start},$item{stop},$item{channel},$item{title},$registdesc ,$item{category}); # print "$item{start} @@ -217,38 +181,34 @@ }# endif }# while -&commitdb; - - -#end -################ - -sub replaceepg{ -#消すEPGのIDを配列に追加します + +sub chkerase{ +# xmltvからきた日付とチャンネルをfoltia epgと比較 my $foltiastarttime = $_[0]; # 14桁 my $ontvepgchannel = $_[1]; -my $foltiaendtime = $_[2]; # 14桁 -my @data = (); - -$foltiastarttime = substr($foltiastarttime,0,12); # 12桁 200508072254 -$foltiaendtime = substr($foltiaendtime,0,12); # 12桁 200508072355 - -$sth = $dbh->prepare($stmt{'xmltv2foltia.replaceepg.1'}); -my $now = &epoch2foldate(time()); -$sth->execute($foltiastarttime , $foltiaendtime , $ontvepgchannel); -while (@data = $sth->fetchrow_array()) { - push(@deleteepgid,$data[0]); - #&writelog("xmltv2foltia DEBUG push(\@deleteepgid,$data[0]);"); -}#end while - -#上書きを消す -$sth = $dbh->prepare($stmt{'xmltv2foltia.replaceepg.2'}); -$sth->execute($foltiastarttime , $foltiaendtime , $ontvepgchannel); -while (@data = $sth->fetchrow_array()) { - push(@deleteepgid,$data[0]); - #&writelog("xmltv2foltia DEBUG push(\@deleteepgid,$data[0]);"); -}#end while - -}#endsub replaceepg - +my $epgstartdate = substr($foltiastarttime,0,8); # 8桁 20050807 +my @epgcounts = ""; +my $DBQuery = ""; + +#if ($currentworkdate eq "" ){#初回起動なら +if ( $currentworkch ne $ontvepgchannel){ + + +if ($epgstartdate >= $today){# xmltvtvから今日以降のデータが来ていれば +my $epgstartdatetime = $today * 10000 ; # 200508070000 12桁 +# 新規に入る予定の未来の番組表、全部いったん消す +# $DBQuery = "DELETE from foltia_epg where startdatetime > $epgstartdatetime AND ontvchannel = '$ontvepgchannel' "; + $DBQuery = "DELETE from foltia_epg where startdatetime > $todaytime AND ontvchannel = '$ontvepgchannel' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("xmltv2foltia DELETE EPG $epgstartdatetime:$DBQuery"); +#$currentworkdate = "$today"; +$currentworkch = $ontvepgchannel ; +}else{ + &writelog("xmltv2foltia ERROR EPG INVALID:$epgstartdate:$today"); + #exit(); +}# endif xmltvtvから今日のデータが来ていれば +}#end if 初回起動なら + +} sub registdb{ my $foltiastarttime = $_[0]; @@ -259,67 +219,54 @@ my $category = $_[5]; -#Encode::JP::H2Z::z2h(\$string); -$title = jcode($title)->tr('A-Za-z0-9!#$%&()*+,−./:;<=>?@[\]^_`{|} ','A-Za-z0-9!#$%&()*+,-./:;<=>?@[\]^_`{|} '); -$desc = jcode($desc)->tr('A-Za-z0-9!#$%&()*+,−./:;<=>?@[\]^_`{|} ','A-Za-z0-9!#$%&()*+,-./:;<=>?@[\]^_`{|} '); -#$title = jcode($title)->tr('A-Za-z0-9!#$%&()*+,−./:;<=>?@[\]^_`{|}','A-Za-z0-9!#$%&()*+,-./:;<=>?@[\]^_`{|}'); -#$desc = jcode($desc)->tr('A-Za-z0-9!#$%&()*+,−./:;<=>?@[\]^_`{|}','A-Za-z0-9!#$%&()*+,-./:;<=>?@[\]^_`{|}'); - #&writelog("xmltv2foltia DEBUG $foltiastarttime:$foltiaendtime"); + + $foltiastarttime = substr($foltiastarttime,0,12); $foltiaendtime = substr($foltiaendtime,0,12); -#if($foltiaendtime > $todaytime){#電波に乗ってきた情報は無条件更新 -# epgidはAUTOINCREMENTに変更した #2010/8/10 -# $sth = $dbh->prepare($stmt{'xmltv2foltia.registdb.1'}); -# $sth->execute(); -# @currentepgid = $sth->fetchrow_array; -# -# if ($currentepgid[0] < 1 ){ -# $newepgid = 1; -# }else{ -# $newepgid = $currentepgid[0]; -# $newepgid++; -# } +if($foltiastarttime > $todaytime){ + + my $DBQuery = "SELECT max(epgid) FROM foltia_epg "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); + @currentepgid = $sth->fetchrow_array; + + if ($currentepgid[0] < 1 ){ + $newepgid = 1; + }else{ + $newepgid = $currentepgid[0]; + $newepgid++; + } #&writelog("xmltv2foltia DEBUG $currentepgid[0] / $newepgid"); my $lengthmin = &calclength($foltiastarttime , $foltiaendtime); - -#print "xmltv2foltia DEBUG :INSERT INTO foltia_epg VALUES ($newepgid, $foltiastarttime, $foltiaendtime, $lengthmin, $channel, $title, $desc, $category)\n"; -push (@foltiastarttime,$foltiastarttime); -push (@foltiaendtime,$foltiaendtime); -push (@lengthmin,$lengthmin); -push (@channel,$channel); -push (@title,$title); -push (@desc,$desc); -push (@category,$category); -# $sth = $dbh->prepare($stmt{'xmltv2foltia.registdb.2'}); -# $sth->execute($newepgid, $foltiastarttime, $foltiaendtime, $lengthmin, $channel, $title, $desc, $category) || warn "error: $newepgid, $foltiastarttime, $foltiaendtime, $lengthmin, $channel, $title, $desc, $category\n"; +$newepgid = $dbh->quote($newepgid ); +$foltiastarttime = $dbh->quote($foltiastarttime); +$foltiaendtime = $dbh->quote($foltiaendtime ); +$lengthmin = $dbh->quote($lengthmin ); +$channel = $dbh->quote($channel ); +$title = $dbh->quote($title); +$desc = $dbh->quote($desc); +$category = $dbh->quote($category); + +$DBQuery = "insert into foltia_epg values ($newepgid,$foltiastarttime,$foltiaendtime,$lengthmin,$channel,$title,$desc,$category)"; +# $DBQuery = $dbh->quote($DBQuery); + $sth = $dbh->prepare($DBQuery); + $sth->execute(); + + # &writelog("xmltv2foltia DEBUG $DBQuery"); -#}else{ + +}else{ #&writelog("xmltv2foltia DEBUG SKIP $foltiastarttime:$foltiaendtime"); -#}#未来じゃなければ挿入しない - -}#end sub registdb - -sub commitdb{ -$dbh->{AutoCommit} = 0; -#print Dumper(\@dbarray); -my $loopcount = @foltiastarttime; -my $i = 0; - -#削除 -foreach $delid (@deleteepgid){ - $sth = $dbh->prepare($stmt{'xmltv2foltia.commitdb.1'}); - $sth->execute( $delid ) || warn "$delid\n"; - #&writelog("xmltv2foltia DEBUG $stmt{'xmltv2foltia.commitdb.1'}/$delid"); +}#未来じゃなければ挿入しない + } -#追加 -for ($i=0;$i<$loopcount;$i++){ - $sth = $dbh->prepare($stmt{'xmltv2foltia.commitdb.2'}); - $sth->execute( $foltiastarttime[$i],$foltiaendtime[$i], $lengthmin[$i], $channel[$i], $title[$i], $desc[$i], $category[$i]) || warn "error: $foltiastarttime, $foltiaendtime, $lengthmin, $channel, $title, $desc, $category\n"; - #&writelog("xmltv2foltia DEBUG $stmt{'xmltv2foltia.commitdb.2'}/$foltiastarttime[$i],$foltiaendtime[$i], $lengthmin[$i], $channel[$i], $title[$i], $desc[$i], $category[$i]"); -}# end for -$dbh->commit; -$dbh->{AutoCommit} = 1; -}#end sub commitdb + + + + + + + sub removetag(){ Index: trunk/install/perl/mklocalizeddir.pl =================================================================== --- trunk/install/perl/mklocalizeddir.pl (リビジョン 94) +++ trunk/install/perl/mklocalizeddir.pl (リビジョン 1) @@ -16,9 +16,9 @@ use DBI; use DBD::Pg; -use DBD::SQLite; + $path = $0; $path =~ s/mklocalizeddir.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -43,9 +43,12 @@ #接続 - $dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; #検索 - $sth = $dbh->prepare($stmt{'mklocalizeddir.1'}); - $sth->execute($tid); +$DBQuery = "select title from foltia_program where tid=$tid "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @subticount= $sth->fetchrow_array; $title = $subticount[0] ; Index: trunk/install/perl/addatq.pl =================================================================== --- trunk/install/perl/addatq.pl (リビジョン 94) +++ trunk/install/perl/addatq.pl (リビジョン 1) @@ -16,5 +16,4 @@ use DBI; use DBD::Pg; -use DBD::SQLite; use Schedule::At; use Time::Local; @@ -22,5 +21,5 @@ $path = $0; $path =~ s/addatq.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -39,13 +38,15 @@ #DB検索(TIDとStationIDからPIDへ) -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; + $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; if ($station == 0){ - $sth = $dbh->prepare($stmt{'addatq.1'}); - $sth->execute($tid); + $DBQuery = "SELECT count(*) FROM foltia_tvrecord WHERE tid = '$tid' "; }else{ - $sth = $dbh->prepare($stmt{'addatq.2'}); - $sth->execute($tid, $station); + $DBQuery = "SELECT count(*) FROM foltia_tvrecord WHERE tid = '$tid' AND stationid = '$station' "; } + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @titlecount = $sth->fetchrow_array; #件数数える @@ -53,7 +54,8 @@ #2以上だったら if ($titlecount[0] >= 2){ - #全局録りが含まれているか調べる - $kth = $dbh->prepare($stmt{'addatq.3'}); - $kth->execute($tid); + #全曲取りが含まれているか調べる + $DBQuery = "SELECT count(*) FROM foltia_tvrecord WHERE tid = '$tid' AND stationid ='0' "; + $kth = $dbh->prepare($DBQuery); + $kth->execute(); @reservecounts = $kth->fetchrow_array; @@ -61,10 +63,10 @@ if($tid == 0){ #今回の引き数がSID 0だったら - #全局録りだけ予約 -# &writelog("addatq DEBUG; ALL STATION RESERVE. TID=$tid SID=$station $titlecount[0] match:$stmt{'addatq.3'}"); + #全局取りだけ予約 +# &writelog("addatq DEBUG; ALL STATION RESERVE. TID=$tid SID=$station $titlecount[0] match:$DBQuery"); &addcue; }else{ #ほかの全局録画addatqが予約入れてくれるからなにもしない -# &writelog("addatq DEBUG; SKIP OPERSTION. TID=$tid SID=$station $titlecount[0] match:$stmt{'addatq.3'}"); +# &writelog("addatq DEBUG; SKIP OPERSTION. TID=$tid SID=$station $titlecount[0] match:$DBQuery"); exit; }#end if ふくまれていたら @@ -73,5 +75,5 @@ &addcue; }else{ - &writelog("addatq error; reserve impossible . TID=$tid SID=$station $titlecount[0] match:$stmt{'addatq.3'}"); +&writelog("addatq error; reserve impossible . TID=$tid SID=$station $titlecount[0] match:$DBQuery"); } @@ -80,5 +82,5 @@ # & addcue; # }else{ -#&writelog("addatq error record TID=$tid SID=$station $titlecount[0] match:$stmt{'addatq.3'}"); +#&writelog("addatq error record TID=$tid SID=$station $titlecount[0] match:$DBQuery"); #} @@ -86,30 +88,33 @@ if ($station == 0){ - $sth = $dbh->prepare($stmt{'addatq.addcue.1'}); - $sth->execute($tid); + $DBQuery = "SELECT * FROM foltia_tvrecord WHERE tid = '$tid' "; }else{ - $sth = $dbh->prepare($stmt{'addatq.addcue.2'}); - $sth->execute($tid, $station); + $DBQuery = "SELECT * FROM foltia_tvrecord WHERE tid = '$tid' AND stationid = '$station' "; } + $sth = $dbh->prepare($DBQuery); +$sth->execute(); @titlecount= $sth->fetchrow_array; $bitrate = $titlecount[2];#ビットレート取得 #PID抽出 - $now = &epoch2foldate(time()); - $twodaysafter = &epoch2foldate(time() + (60 * 60 * 24 * 2)); +$now = &epoch2foldate(`date +%s`); +$twodaysafter = &epoch2foldate(`date +%s` + (60 * 60 * 24 * 2)); #キュー入れは直近2日後まで if ($station == 0 ){ - $sth = $dbh->prepare($stmt{'addatq.addcue.3'}); - $sth->execute($tid, $now, $twodaysafter); + $DBQuery = " +SELECT * from foltia_subtitle WHERE tid = '$tid' AND startdatetime > '$now' AND startdatetime < '$twodaysafter' "; }else{ + $DBQuery = " +SELECT * from foltia_subtitle WHERE tid = '$tid' AND stationid = '$station' AND startdatetime > '$now' AND startdatetime < '$twodaysafter' "; #stationIDからrecch - $stationh = $dbh->prepare($stmt{'addatq.addcue.4'}); - $stationh->execute($station); +$getrecchquery="SELECT stationid , stationrecch FROM foltia_station where stationid = '$station' "; + $stationh = $dbh->prepare($getrecchquery); + $stationh->execute(); @stationl = $stationh->fetchrow_array; $recch = $stationl[1]; +} - $sth = $dbh->prepare($stmt{'addatq.addcue.5'}); - $sth->execute($tid, $station, $now, $twodaysafter); - } + $sth = $dbh->prepare($DBQuery); + $sth->execute(); while (($pid , @@ -126,6 +131,7 @@ if ($station == 0 ){ #stationIDからrecch - $stationh = $dbh->prepare($stmt{'addatq.addcue.6'}); - $stationh->execute($stationid); +$getrecchquery="SELECT stationid , stationrecch FROM foltia_station where stationid = '$stationid' "; + $stationh = $dbh->prepare($getrecchquery); + $stationh->execute(); @stationl = $stationh->fetchrow_array; $recch = $stationl[1]; Index: trunk/install/perl/cron_foltia_dayly.sh =================================================================== --- trunk/install/perl/cron_foltia_dayly.sh (リビジョン 111) +++ trunk/install/perl/cron_foltia_dayly.sh (リビジョン 1) @@ -10,13 +10,9 @@ # -#デジタル放送から一週間分のEPGを取得 -/home/foltia/perl/epgimport.pl long - -# XMLTVをつかってEPG番組表インポート(アナログ専用旧仕様) +# XMLTVをつかってEPG番組表インポート # -#/usr/bin/perl /usr/bin/tv_grab_jp | /home/foltia/perl/xmltv2foltia.pl -# 2つの局設定使うような場合 -#/usr/bin/perl /usr/bin/tv_grab_jp --config-file ~/.xmltv/tv_grab_jp.conf.jcom | /home/foltia/perl/xmltv2foltia.pl -#/usr/bin/perl /usr/bin/tv_grab_jp --config-file ~/.xmltv/tv_grab_jp.conf.tvk | /home/foltia/perl/xmltv2foltia.pl +# /usr/bin/perl /usr/bin/tv_grab_jp --config-file | /home/foltia/perl/xmltv2foltia.pl +/usr/bin/perl /usr/bin/tv_grab_jp --config-file ~/.xmltv/tv_grab_jp.conf.jcom | /home/foltia/perl/xmltv2foltia.pl +/usr/bin/perl /usr/bin/tv_grab_jp --config-file ~/.xmltv/tv_grab_jp.conf.tvk | /home/foltia/perl/xmltv2foltia.pl #録画ファイルとテーブルの整合性を更新 Index: trunk/install/perl/deletemovie.pl =================================================================== --- trunk/install/perl/deletemovie.pl (リビジョン 124) +++ trunk/install/perl/deletemovie.pl (リビジョン 1) @@ -14,11 +14,8 @@ # # -use DBI; -use DBD::Pg; -use DBD::SQLite; $path = $0; $path =~ s/deletemovie.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -35,5 +32,5 @@ #ファイル名正当性チェック -if ($fname =~ /.m2p$|.m2t$|.MP4$|.aac$/){ +if ($fname =~ /.m2p\z/){ }else{ @@ -43,14 +40,8 @@ } -#DB初期化 -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; +#ファイル存在チェック -#ファイル存在チェック -my $tid = &mp4filename2tid($fname); -my $mp4dirname = &makemp4dir($tid); if (-e "$recfolderpath/$fname"){ - $filemovepath = $recfolderpath; -}elsif(-e "$mp4dirname/$fname"){ - $filemovepath = $mp4dirname; + }else{ # print "deletemovie file not found.$recfolderpath/$fname\n"; @@ -61,9 +52,9 @@ #既読削除処理 if ($rapidfiledelete > 0){ #./mita/へ移動 - system ("mv $filemovepath/$fname $recfolderpath/mita/"); - &writelog("deletemovie mv filemovepath/$fname $recfolderpath/mita/."); + system ("mv $recfolderpath/$fname $recfolderpath/mita/"); + &writelog("deletemovie mv $recfolderpath/$fname $recfolderpath/mita/."); }else{ #即時削除 - system ("rm $filemovepath/$fname "); - &writelog("deletemovie rm $filemovepath/$fname "); + system ("rm $recfolderpath/$fname "); + &writelog("deletemovie rm $recfolderpath/$fname "); Index: trunk/install/perl/recwrap.pl =================================================================== --- trunk/install/perl/recwrap.pl (リビジョン 138) +++ trunk/install/perl/recwrap.pl (リビジョン 1) @@ -1,4 +1,4 @@ #!/usr/bin/perl -#usage recwrap.pl ch length(sec) [bitrate(5)] [TID] [NO] [PID] [stationid] [digitalflag] [digitalband] [digitalch] +#usage recwrap.pl ch length(sec) [bitrate(5)] [TID] [NO] [PID] # # Anime recording system foltia @@ -15,5 +15,4 @@ use DBI; use DBD::Pg; -use DBD::SQLite; use Schedule::At; use Time::Local; @@ -22,5 +21,5 @@ $path = $0; $path =~ s/recwrap.pl$//i; -if ($path ne "./"){ +if ($pwd ne "./"){ push( @INC, "$path"); } @@ -30,5 +29,5 @@ $recch = $ARGV[0] ; if ($recch eq "" ){ - #引き数なしで実行されたら、終了 + #引き数なし出実行されたら、終了 print "usage recwrap.pl ch length(sec) [bitrate(5)] [TID] [NO] [PID]\n"; exit; @@ -40,306 +39,273 @@ $tid = $ARGV[3] ; $countno = $ARGV[4] ; -$pid = $ARGV[5] ; -$stationid = $ARGV[6] ; -$usedigital = $ARGV[7] ; -$digitalstationband = $ARGV[8] ; -$digitalch= $ARGV[9] ; - -#DB初期化 -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; - - -if ($usedigital == 1){ - $extension = ".m2t";#TSの拡張子 -}else{ - $extension = ".m2p";#MPEG2の拡張子 -} -if ($recch == -2 ){ #ラジオ局 - $extension = ".aac";#MPEG2の拡張子 -} - -$outputfile = strftime("%Y%m%d-%H%M", localtime(time + 60)); +$pid = $ARGV[5] ; + +$outputfile = `date +%Y%m%d-%H%M --date "1 min "`; chomp($outputfile); - if ($tid == 0){ - if ($usedigital == 1){ - $outputfilename = "0--".$outputfile."-".$digitalch.$extension; - $mp4newstylefilename = "-0--".$outputfile."-".$digitalch; - }else{ - $outputfilename = "0--".$outputfile."-".$recch.$extension; + $outputfilename = "0--".$outputfile."-".$recch.".m2p"; $mp4newstylefilename = "-0--".$outputfile."-".$recch; - } }else{ if ($countno == 0){ - $outputfilename = $tid ."--".$outputfile.$extension; + $outputfilename = $tid ."--".$outputfile.".m2p"; $mp4newstylefilename = "-" . $tid ."--".$outputfile; }else{ - $outputfilename = $tid ."-".$countno."-".$outputfile.$extension; + $outputfilename = $tid ."-".$countno."-".$outputfile.".m2p"; $mp4newstylefilename = "-" . $tid ."-".$countno."-".$outputfile; } } - -if ($recch == -2 ){ #ラジオ局 -# stationIDからradiko識別子を取得 -$sth = $dbh->prepare($stmt{'recwrap.8'}); -$sth->execute($stationid); - @stationline= $sth->fetchrow_array; -$radikostationname = $stationline[3]; -my $starttime = time(); -my $endepochtime = time() + $reclength; -#録音 -$oserr = system("$toolpath/perl/digitalradiorecording.pl $radikostationname $reclength $outputfilename"); +#リモコン操作 +# $haveirdaunit = 1;リモコンつないでるかどうか確認 +if ($haveirdaunit == 1){ +# 録画チャンネルが0なら + if ($recch == 0){ +# &つけて非同期でchangestbch.pl呼び出し + &writelog("recwrap Call Change STB CH :$pid"); + system ("$toolpath/perl/changestbch.pl $pid &"); + }#end if +}#end if + +if($recch == -10){ +#非受信局なら + &writelog("recwrap Not recordable channel;exit:PID $pid"); + exit; + }#end if + +&writelog("recwrap RECSTART $recch $reclength 0 $outputfilename $bitrate $tid $countno $pid"); +#録画 +#system("$toolpath/perl/tvrecording.pl $recch $reclength 0 $outputfile $bitrate $tid $countno"); +$oserr = system("$toolpath/perl/tvrecording.pl $recch $reclength 0 $outputfilename $bitrate $tid $countno"); $oserr = $oserr / 256; -&writelog("recwrap DEBUG radiko rec finished. $oserr"); -#サーバビジーで即死してないか検出 -$now = time(); -if ($now < $endepochtime){ #終了予定より前に録音プロセスが戻ってきたなら -&writelog("recwrap radiko rec failed,will be retry. NOW:$now PlanedEnd:$endepochtime"); - -my $retrycounter = 0; -my $waitsecsbase = 10; -my $waitsec ; -my $waitsecsrand ; -my $recfilepath; - while($now < $endepochtime){ - if($retrycounter >= 15){ - &writelog("recwrap radiko rec failed,Giving up.Max retry counter over."); - last; - } - $waitsecsrand = int(rand($waitsecsbase/2)); - $waitsec = $waitsecsbase + $waitsecsrand ; - &writelog("recwrap DEBUG radiko rec retry waiting. $waitsec ($waitsecsbase + $waitsecsrand)"); - sleep($waitsec); - &writelog("recwrap DEBUG retry start."); - $recfilepath = "$recfolderpath"."/"."$outputfilename"; - if (-e $recfilepath ){ - unlink("$recfilepath"); - &writelog("recwrap DEBUG delete $recfilepath"); - } - #録音 - $oserr = system("$toolpath/perl/digitalradiorecording.pl $radikostationname $reclength $outputfilename N");#起動waitなしで - $oserr = $oserr / 256; - &writelog("recwrap DEBUG radiko rec retry finished. $oserr"); - - $retrycounter++; - if ($waitsecsbase < 600 ){ - $waitsecsbase = $waitsecsbase * 2; - } - $now = time(); - }# while -} # if - - -# aacファイル名をfoltia_subtitlePIDレコードに書き込み -$sth = $dbh->prepare($stmt{'recwrap.1'}); -$sth->execute($outputfilename, $pid); -&writelog("recwrap DEBUG UPDATEDB $stmt{'recwrap.1'}"); -&changefilestatus($pid,$FILESTATUSTRANSCODEMP4BOX); - -# aacファイル名をfoltia_m2pfilesPIDレコードに書き込み -$sth = $dbh->prepare($stmt{'recwrap.2'}); -$sth->execute($outputfilename); -&writelog("recwrap DEBUG UPDATEDB $stmt{'recwrap.2'}"); - - -}else{#非ラジオ局なら - -if ($usedigital == 1){ -#デジタルなら -&writelog("recwrap RECSTART DIGITAL $digitalstationband $digitalch $reclength $stationid 0 $outputfilename $tid $countno friio"); -#録画 - $starttime = time(); -$oserr = system("$toolpath/perl/digitaltvrecording.pl $digitalstationband $digitalch $reclength $stationid 0 $outputfilename $tid $countno friio"); -$oserr = $oserr / 256; - if ($oserr == 1){ - &writelog("recwrap ABORT recfile exist. [$outputfilename] $digitalstationband $digitalch $reclength $stationid 0 $outputfilename $tid $countno"); - exit; -}elsif ($oserr == 2){ - &writelog("recwrap ERR 2:Device busy;retry."); - &continuousrecordingcheck;#もうすぐ終わる番組をkill - sleep(2); - $oserr = system("$toolpath/perl/digitaltvrecording.pl $digitalstationband $digitalch $reclength $stationid N $outputfilename $tid $countno friio"); - $oserr = $oserr / 256; - if ($oserr == 2){ - &writelog("recwrap ERR 2:Device busy;Giving up digital recording."); - if ($recunits > 0 ){ - }else{ - exit; - } - } -}elsif ($oserr == 3){ -&writelog("recwrap ABORT:ERR 3"); -exit ; -} -}else{ # NOT $usedigital == 1 - if ($recunits > 0 ){ - #リモコン操作 - # $haveirdaunit = 1;リモコンつないでるかどうか確認 - if ($haveirdaunit == 1){ - # 録画チャンネルが0なら - if ($recch == 0){ - # &つけて非同期でchangestbch.pl呼び出し - &writelog("recwrap Call Change STB CH :$pid"); - system ("$toolpath/perl/changestbch.pl $pid &"); - }#end if - }#end if - - if($recch == -10){ - #非受信局なら - &writelog("recwrap Not recordable channel;exit:PID $pid"); - exit; - }#end if - # アナログ録画 - &writelog("recwrap RECSTART $recch $reclength 0 $outputfilename $bitrate $tid $countno $pid $usedigital $digitalstationband $digitalch"); - - #録画 - #system("$toolpath/perl/tvrecording.pl $recch $reclength 0 $outputfile $bitrate $tid $countno"); - $starttime = time(); - - $oserr = system("$toolpath/perl/tvrecording.pl $recch $reclength 0 $outputfilename $bitrate $tid $countno"); - $oserr = $oserr / 256; - if ($oserr == 1){ - &writelog("recwrap ABORT recfile exist. [$outputfilename] $recch $reclength 0 0 $bitrate $tid $countno $pid"); - exit; - } -#デバイスビジーで即死してないか検出 -$now = time(); - if ($now < $starttime + 100){ #録画プロセス起動してから100秒以内に戻ってきてたら - $retrycounter = 0; - while($now < $starttime + 100){ - if($retrycounter >= 5){ - &writelog("recwrap WARNING Giving up recording."); - last; - } - &writelog("recwrap retry recording $now $starttime"); - #アナログ録画 - $starttime = time(); -if($outputfilename =~ /.m2t$/){ - $outputfilename =~ s/.m2t$/.m2p/; -} -$oserr = system("$toolpath/perl/tvrecording.pl $recch $reclength N $outputfilename $bitrate $tid $countno"); - $now = time(); -$oserr = $oserr / 256; - if ($oserr == 1){ - &writelog("recwrap ABORT recfile exist. in resume process.[$outputfilename] $recch $reclength 0 0 $bitrate $tid $countno $pid"); - exit; - }# if - $retrycounter++; - }# while - } # if - + &writelog("recwrap ABORT recfile exist. [$outputfilename] $recch $reclength 0 0 $bitrate $tid $countno $pid"); +}else{ &writelog("recwrap RECEND [$outputfilename] $recch $reclength 0 0 $bitrate $tid $countno $pid"); - - }#end if $recunits > 0 -}#endif #デジタル優先フラグ - +} +#DB初期化 + my $data_source = sprintf("dbi:%s:dbname=%s;host=%s;port=%d", + $DBDriv,$DBName,$DBHost,$DBPort); + $dbh = DBI->connect($data_source,$DBUser,$DBPass) ||die $DBI::error;; # m2pファイル名をPIDレコードに書き込み -$sth = $dbh->prepare($stmt{'recwrap.1'}); -$sth->execute($outputfilename, $pid); -&writelog("recwrap DEBUG UPDATEDB $stmt{'recwrap.1'}"); -&changefilestatus($pid,$FILESTATUSRECEND); + $DBQuery = "UPDATE foltia_subtitle SET + m2pfilename = '$outputfilename' + WHERE pid = '$pid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("recwrap UPDATEDB $DBQuery"); # m2pファイル名をPIDレコードに書き込み -$sth = $dbh->prepare($stmt{'recwrap.2'}); -$sth->execute($outputfilename); -&writelog("recwrap DEBUG UPDATEDB $stmt{'recwrap.2'}"); + $DBQuery = "insert into foltia_m2pfiles values ('$outputfilename')"; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("recwrap UPDATEDB $DBQuery"); # Starlight breaker向けキャプチャ画像作成 if (-e "$toolpath/perl/captureimagemaker.pl"){ &writelog("recwrap Call captureimagemaker $outputfilename"); -&changefilestatus($pid,$FILESTATUSCAPTURE); system ("$toolpath/perl/captureimagemaker.pl $outputfilename"); -&changefilestatus($pid,$FILESTATUSCAPEND); -} -}#非ラジオ局 - -# MPEG4 ------------------------------------------------------ -#MPEG4トラコン必要かどうか -$sth = $dbh->prepare($stmt{'recwrap.3'}); -$sth->execute($tid); +} + + + +# PSP ------------------------------------------------------ +#PSPトラコン必要かどうか +$DBQuery = "SELECT psp,aspect,title FROM foltia_program WHERE tid = '$tid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); @psptrcn= $sth->fetchrow_array; -if ($psptrcn[0] == 1 ){#トラコン番組 - &writelog("recwrap Launch ipodtranscode.pl"); - exec ("$toolpath/perl/ipodtranscode.pl"); - exit; + if ($psptrcn[0] == 1 ){#トラコン番組 + + +#PSPムービーディレクトリがアルかどうか + +#TIDが100以上の3桁の場合はそのまま +my $pspfilnamehd = ""; + + $pspfilnamehd = $tid; +$pspdirname = "$tid.localized/"; +$pspdirname = $recfolderpath."/".$pspdirname; + +#なければ作る +unless (-e $pspdirname ){ + system("$toolpath/perl/mklocalizeddir.pl $tid"); + #&writelog("recwrap mkdir $pspdirname"); +} +$pspdirname = "$tid.localized/mp4/"; +$pspdirname = $recfolderpath."/".$pspdirname; +#なければ作る +unless (-e $pspdirname ){ + mkdir $pspdirname ,0777; + #&writelog("recwrap mkdir $pspdirname"); +} + +#ファイル名決定 +if ($mp4filenamestyle == 1){# 1;よりわかりやすいファイル名 + $pspfilname = $mp4newstylefilename ; + +}else{##0:PSP ファームウェアver.2.80より前と互換性を持つファイル名 +#・フォルダ名[100MNV01]の100の部分は変更可(100〜999)。 +# MP_ROOT ━ 100MNV01 ┳ M4V00001.MP4(動画) +#┃   ┗ M4V00001.THM(サムネイル)※必須ではない + +#ファイル名決定 +#ファイル名決定 #新アルゴリズム +#TID 0000-3599まで[3桁] +#話数 00-999まで[2桁] + +my $pspfilnameft = ""; +my $pspfilnameyearhd = ""; +my $pspfilnameyearft = ""; + +$btid = $tid % 3600; +# print "$btid\n"; + +if($btid >= 0 && $btid < 1000){ + + $pspfilnamehd = sprintf("%03d",$btid); + +}elsif ($btid >= 1000 && $btid < 3600){ + $pspfilnameyearhd = substr($btid, 0, 2); + $pspfilnameyearhd =~ s/10/A/; + $pspfilnameyearhd =~ s/11/B/; + $pspfilnameyearhd =~ s/12/C/; + $pspfilnameyearhd =~ s/13/D/; + $pspfilnameyearhd =~ s/14/E/; + $pspfilnameyearhd =~ s/15/F/; + $pspfilnameyearhd =~ s/16/G/; + $pspfilnameyearhd =~ s/17/H/; + $pspfilnameyearhd =~ s/18/I/; + $pspfilnameyearhd =~ s/19/J/; + $pspfilnameyearhd =~ s/20/K/; + $pspfilnameyearhd =~ s/21/L/; + $pspfilnameyearhd =~ s/22/M/; + $pspfilnameyearhd =~ s/23/N/; + $pspfilnameyearhd =~ s/24/O/; + $pspfilnameyearhd =~ s/25/P/; + $pspfilnameyearhd =~ s/26/Q/; + $pspfilnameyearhd =~ s/27/R/; + $pspfilnameyearhd =~ s/28/S/; + $pspfilnameyearhd =~ s/29/T/; + $pspfilnameyearhd =~ s/30/U/; + $pspfilnameyearhd =~ s/31/V/; + $pspfilnameyearhd =~ s/32/W/; + $pspfilnameyearhd =~ s/33/X/; + $pspfilnameyearhd =~ s/34/Y/; + $pspfilnameyearhd =~ s/35/Z/; + +$pspfilnameyearft = substr($btid, 2, 2); +$pspfilnameyearft = sprintf("%02d",$pspfilnameyearft); +$pspfilnamehd = $pspfilnameyearhd . $pspfilnameyearft; + +} + +# 話数 +if (0 < $countno && $countno < 100 ){ +# 2桁 + $pspfilnameft = sprintf("%02d",$countno); +}elsif(100 <= $countno && $countno < 1000 ){ +# 3桁 + $pspfilnameft = sprintf("%03d",$countno); # 話数3桁 + $pspfilnamehd = substr($pspfilnamehd, 0, 2); # TID 二桁 後ろ1バイト落とし +}elsif(1000 <= $countno && $countno < 10000 ){ +# 4桁 + $pspfilnameft = sprintf("%04d",$countno); # 話数4桁 + $pspfilnamehd = substr($pspfilnamehd, 0, 1); # TID 1桁 後ろ2バイト落とし + + +}elsif($countno == 0){ +#タイムスタンプが最新のMP4ファイル名取得 +my $newestmp4filename = `cd $pspdirname ; ls -t *.MP4 | head -1`; + if ($newestmp4filename =~ /M4V$tid/){ + $nowcountno = $' ; + $nowcountno++; + $pspfilnameft = sprintf("%02d",$nowcountno); + while (-e "$pspdirname/M4V".$pspfilnamehd.$pspfilnameft.".MP4"){ + $nowcountno++; + $pspfilnameft = sprintf("%02d",$nowcountno); + print "File exist:$nowcountno\n"; + } +#print "NeXT\n"; +}else{ +# 0の場合 週番号を100から引いたもの +# week number of year with Monday as first day of week (01..53) +#だったけど常に0に +# my $weeno = `date "+%V"`; +# $weeno = 100 - $weeno ; +# $pspfilnameft = sprintf("%02d",$weeno); + $pspfilnameft = sprintf("%02d",0); +#print "WEEKNO\n"; +} + +} + +my $pspfilname = $pspfilnamehd.$pspfilnameft ; +# print "$pspfilname($pspfilnamehd/$pspfilnameft)\n"; +}# endif MP4ファイル名が新styleなら + +&writelog("recwrap TRCNSTART vfr4psp.sh $recfolderpath/$outputfilename $pspfilname $pspdirname $psptrcn[1]"); +#トラコン開始 +system("$toolpath/perl/transcode/vfr4psp.sh $recfolderpath/$outputfilename $pspfilname $pspdirname $psptrcn[1]"); + +&writelog("recwrap TRCNEND vfr4psp.sh $recfolderpath/$outputfilename $pspfilname $pspdirname $psptrcn[1]"); + +#最適化 + +$DBQuery = "SELECT subtitle FROM foltia_subtitle WHERE tid = '$tid' AND countno = '$countno' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); + @programtitle = $sth->fetchrow_array; + +if ( $countno == "0" ){ + $pspcountno = ""; +}else{ + $pspcountno = $countno ; +} +&writelog("recwrap OPTIMIZE mp4psp -p $pspdirname/M4V$pspfilname.MP4 -t '$psptrcn[2] $pspcountno $programtitle[0]' "); +Jcode::convert(\$programtitle[0],'euc'); +system ("/usr/local/bin/mp4psp -p $pspdirname/M4V$pspfilname.MP4 -t '$psptrcn[2] $pspcountno $programtitle[0]'") ; + + +#サムネール + +# mplayer -ss 00:01:20 -vo jpeg:outdir=/home/foltia/php/tv/443MNV01 -ao null -sstep 1 -frames 3 -v 3 /home/foltia/php/tv/443-07-20050218-0030.m2p +#2005/02/22_18:30:05 recwrap TRCNSTART vfr4psp.sh /home/foltia/php/tv/447-21-20050222-1800.m2p 44721 /home/foltia/php/tv/447MNV01 3 +&writelog("recwrap THAMJ mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -sstep 1 -frames 3 -v 3 $recfolderpath/$outputfilename "); +system ("mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -sstep 1 -frames 3 -v 3 $recfolderpath/$outputfilename"); +&writelog("recwrap THAMI convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/M4V$pspdirname.THM "); + +if (-e "$pspdirname/M4V".$pspfilname.".THM"){ +$timestamp =`date "+%Y%m%d-%H%M%S"`; +chomp $timestamp; + system("convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/M4V".$pspfilname.".THM.".$timestamp.".THM"); + +}else{ + system("convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/M4V".$pspfilname.".THM"); +} +# rm -rf 00000001.jpg +# convert -resize 160x120\! 00000002.jpg M4V44307.THM +# rm -rf 00000002.jpg +system("rm -rf $pspdirname/0000000*.jpg "); + + + + +# MP4ファイル名をPIDレコードに書き込み + $DBQuery = "UPDATE foltia_subtitle SET + PSPfilename = 'M4V$pspfilname.MP4' + WHERE pid = '$pid' "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("recwrap UPDATEsubtitleDB $DBQuery"); + +# MP4ファイル名をfoltia_mp4files挿入 + $DBQuery = "insert into foltia_mp4files values ('$tid','M4V$pspfilname.MP4') "; + $sth = $dbh->prepare($DBQuery); + $sth->execute(); +&writelog("recwrap UPDATEmp4DB $DBQuery"); + }#PSPトラコンあり -sub continuousrecordingcheck(){ - my $now = time() + 60 * 2; -&writelog("recwrap DEBUG continuousrecordingcheck() now $now"); -my @processes =`ps ax | grep -e recpt1 -e recfriio`; #foltiaBBS もうすぐ終了する番組のプロセスをkill 投稿日 2010年08月05日03時19分33秒 投稿者 Nis - -my $psline = ""; -my @processline = ""; -my $pid = ""; -my @pid; -my $sth; -foreach (@processes){ - if (/recpt1|friiodetect/) { - if (/^.[0-9]*\s/){ - push(@pid, $&); - }#if - }#if -}#foreach - -if (@pid > 0){ -my @filenameparts; -my $tid = ""; -my $startdate = ""; -my $starttime = ""; -my $startdatetime = ""; -my @recfile; -my $endtime = ""; -my $endtimeepoch = ""; -foreach $pid (@pid){ -#print "DEBUG PID $pid\n"; -&writelog("recwrap DEBUG continuousrecordingcheck() PID $pid"); - - my @lsofoutput = `/usr/sbin/lsof -p $pid`; - my $filename = ""; - #print "recfolferpath $recfolderpath\n"; - foreach (@lsofoutput){ - if (/m2t/){ - @processline = split(/\s+/,$_); - $filename = $processline[8]; - $filename =~ s/$recfolderpath\///; - &writelog("recwrap DEBUG continuousrecordingcheck() FILENAME $filename"); - # 1520-9-20081201-0230.m2t - @filenameparts = split(/-/,$filename); - $tid = $filenameparts[0]; - $startdate = $filenameparts[2]; - $starttime = $filenameparts[3]; - @filenameparts = split(/\./,$starttime); - $startdatetime = $startdate.$filenameparts[0]; - #DBから録画中番組のデータ探す - &writelog("recwrap DEBUG continuousrecordingcheck() $stmt{'recwrap.7'}"); - $sth = $dbh->prepare($stmt{'recwrap.7'}); - &writelog("recwrap DEBUG continuousrecordingcheck() prepare"); - $sth->execute($tid, $startdatetime); - &writelog("recwrap DEBUG continuousrecordingcheck() execute"); - @recfile = $sth->fetchrow_array; - &writelog("recwrap DEBUG continuousrecordingcheck() @recfile $recfile[0] $recfile[1] $recfile[2] $recfile[3] $recfile[4] $recfile[5] $recfile[6] $recfile[7] $recfile[8] $recfile[9] "); - #終了時刻 - $endtime = $recfile[4]; - $endtimeepoch = &foldate2epoch($endtime); - &writelog("recwrap DEBUG continuousrecordingcheck() $recfile[0] $recfile[1] $recfile[2] $recfile[3] $recfile[4] $recfile[5] endtimeepoch $endtimeepoch"); - if ($endtimeepoch < $now){#まもなく終わる番組なら - #kill - system("kill $pid"); - &writelog("recwrap recording process killed $pid/$endtimeepoch/$now"); - }else{ - &writelog("recwrap No processes killed: $endtimeepoch/$now"); - } - }#endif m2t - }#foreach lsofoutput -}#foreach -}else{ -#print "DEBUG fecfriio NO PID\n"; -&writelog("recwrap No recording process killed."); -} -}#endsub - - - + + + Index: trunk/install/perl/epgimport.pl =================================================================== --- trunk/install/perl/epgimport.pl (リビジョン 129) +++ (リビジョン ) @@ -1,255 +1,0 @@ -#!/usr/bin/perl -# -# -# Anime recording system foltia -# http://www.dcc-jpl.com/soft/foltia/ -# -# epgimport.pl -# -# EPG番組表取得 -# tsを取得してepgdump経由でepgテーブルにインポートします。 -# 内部でxmltv2foltia.plを呼んで実際の追加処理を行います。 -# -# usage -# epgimport.pl [long] #longがつくと一週間分 -# epgimport.pl [stationid] #放送局ID指定でそのチャンネルだけ短時間で取得 -# -# DCC-JPL Japan/foltia project -# - -use DBI; -use DBD::Pg; -use DBD::SQLite; -#use Schedule::At; -#use Time::Local; -use Jcode; - -$path = $0; -$path =~ s/epgimport.pl$//i; -if ($path ne "./"){ -push( @INC, "$path"); -} - -require "foltialib.pl"; - -my $ontvcode = ""; -my $channel = ""; -my @date = (); -my $recpt1path = $toolpath . "/perl/tool/recpt1"; #ほかのキャプチャデバイス作ってる人はココを変更 -my $epgdumppath = $toolpath ."/perl/tool"; #epgdumpのあるディレクトリ -my $xmloutpath = "/tmp"; -my %stations; -my $uset = ""; -my $usebs = ""; -my $usecs = ""; -my $stationid = "" ; -my $rectime = 0; -my $bsrectime = 0; -my $cs1rectime = 0; -my $cs2rectime = 0; - - -#引き数がアルか? -if ( $ARGV[0] eq "long" ){ - #長期番組表取得 - $rectime = 60; - $bsrectime = 120; - $cs1rectime = 60; - $cs2rectime = 60; -}elsif( $ARGV[0] > 0 ){ - $stationid = $ARGV[0]; - $rectime = 3; - $bsrectime = 36; - $cs1rectime = 15; - $cs2rectime = 5; -}else{ - #短期番組表取得 - $rectime = 3; - $bsrectime = 36; - $cs1rectime = 15; - $cs2rectime = 5; -} -#データ量比較 -#3秒 16350 Aug 10 16:21 __27-epg-short.xml -#12秒 56374 Aug 10 16:21 __27-epg-long.xml -#60秒 127735 Aug 10 16:23 __27-epg-velylong.xml - -#重複起動確認 -$processes = &processfind("epgimport.pl"); -if ($processes > 1 ){ -&writelog("epgimport processes exist. exit:"); -exit; -} - - -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; - -#局指定があるなら、単一放送局指定モード -if ($stationid > 0){ - $sth = $dbh->prepare($stmt{'epgimport.1'}); - $sth->execute($stationid); - @data = $sth->fetchrow_array(); - unless($data[0] == 1){#局の数が1でなければ異常終了 - &writelog("epgimport ERROR Invalid station id ($stationid)."); - exit 1; - }else{ - $sth = $dbh->prepare($stmt{'epgimport.2'}); - $sth->execute($stationid); - @data = $sth->fetchrow_array(); - $channel = $data[0]; - $ontvcode = $data[1]; - if ($channel > 0){ - &writelog("epgimport DEBUG Single station mode (ch:$channel / $ontvcode)."); - }else{#ラジオ局などの場合 - &writelog("epgimport ABORT SID $stationid is not Digital TV ch."); - exit; - }#endif ラジオ局かどうか - }#end unless($data[0] == 1 -}#endif $stationid > 0 - -#地デジ---------------------------------------- -#受信局確認 -if ($channel >= 13 && $channel <= 62){#局指定があるなら - $stations{$channel} = $ontvcode; - $uset = 1; -}elsif($channel >= 100){ - $uset = 0; #地デジ範囲外の局 -}else{ - $sth = $dbh->prepare($stmt{'epgimport.3'}); - $sth->execute(); - - while (@data = $sth->fetchrow_array()) { - $stations{$data[0]} = $data[1]; - }#end while - $uset = 1; -}#end if - -if ($uset == 1){ -foreach $channel ( keys %stations ) { - $ontvcode = $stations{$channel}; - #print "$ontvcode $digitalch\n"; - &chkrecordingschedule; - #print "$recpt1path $channel $rectime $recfolderpath/__$channel.m2t\n"; - $oserr = `$recpt1path $channel $rectime $recfolderpath/__$channel.m2t`; - #print "$epgdumppath/epgdump $ontvcode $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml\n"; - $oserr = `$epgdumppath/epgdump $ontvcode $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml`; - #print "cat $xmloutpath/__$channel-epg.xml | $toolpath/perl/xmltv2foltia.pl\n"; - $oserr = `cat $xmloutpath/__$channel-epg.xml | $toolpath/perl/xmltv2foltia.pl`; - unlink "$recfolderpath/__$channel.m2t"; - unlink "$xmloutpath/__$channel-epg.xml"; -}#end foreach -}#endif - -#BS---------------------------------------- -#受信局確認 -if ($channel >= 100 && $channel <= 222 ){#局指定があるなら - $usebs = 1; -}elsif($channel >= 13 && $channel <= 62){ - $usebs = 0; #地デジ局指定の場合、スキップ。 -}elsif($channel >= 223){ - $usebs = 0; #CS局指定の場合もスキップ -}else{ - $sth = $dbh->prepare($stmt{'epgimport.4'}); - $sth->execute(); - @data = $sth->fetchrow_array(); - if ($data[0] > 0 ){ - $usebs = 1; - } -}#end if - -if ($usebs == 1){ - #$ontvcode = $stations{$channel}; - $channel = 211; - #print "$ontvcode $digitalch\n"; - &chkrecordingschedule; - #print "$recpt1path $channel $bsrectime $recfolderpath/__$channel.m2t\n"; - $oserr = `$recpt1path $channel $bsrectime $recfolderpath/__$channel.m2t`; - #print "$epgdumppath/epgdump /BS $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml\n"; - $oserr = `$epgdumppath/epgdump /BS $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml`; - #print "cat $xmloutpath/__$channel-epg.xml | $toolpath/perl/xmltv2foltia.pl\n"; - $oserr = `cat $xmloutpath/__$channel-epg.xml | $toolpath/perl/xmltv2foltia.pl`; - unlink "$recfolderpath/__$channel.m2t"; - unlink "$xmloutpath/__$channel-epg.xml"; -}else{ - &writelog("epgimport DEBUG Skip BS.$channel:$usebs"); -} - - - -#CS---------------------------------------- -#if ( $ARGV[0] eq "long" ){ #短時間録画なら異常に重くはならないことを発見した -#受信局確認 -if ($channel >= 223 ){#局指定があるなら - $usecs = 1; -}else{ - $sth = $dbh->prepare($stmt{'epgimport.5'}); - $sth->execute(); - @data = $sth->fetchrow_array(); - if ($data[0] > 0 ){ - $usecs = 1; - } -}#end if - -if ($usecs == 1){ -#一気に録画して - $channela = "CS8"; - #print "$ontvcode $digitalch\n"; - &chkrecordingschedule; - #print "$recpt1path $channela $bsrectime $recfolderpath/__$channela.m2t\n"; - $oserr = `$recpt1path $channela $cs1rectime $recfolderpath/__$channela.m2t`; - - $channelb = "CS24"; - &chkrecordingschedule; - #print "$recpt1path $channelb $bsrectime $recfolderpath/__$channelb.m2t\n"; - $oserr = `$recpt1path $channelb $cs2rectime $recfolderpath/__$channelb.m2t`; - -#時間のかかるepgdumpまとめてあとまわし - #print "nice -n 19 $epgdumppath/epgdump /CS $recfolderpath/__$channela.m2t $xmloutpath/__$channela-epg.xml\n"; - $oserr = `$epgdumppath/epgdump /CS $recfolderpath/__$channela.m2t $xmloutpath/__$channela-epg.xml`; - #print "cat $xmloutpath/__$channela-epg.xml | $toolpath/perl/xmltv2foltia.pl\n"; - $oserr = `cat $xmloutpath/__$channela-epg.xml | $toolpath/perl/xmltv2foltia.pl`; - unlink "$recfolderpath/__$channela.m2t"; - unlink "$xmloutpath/__$channela-epg.xml"; - - #print "nice -n 19 $epgdumppath/epgdump /CS $recfolderpath/__$channelb.m2t $xmloutpath/__$channelb-epg.xml\n"; - $oserr = `$epgdumppath/epgdump /CS $recfolderpath/__$channelb.m2t $xmloutpath/__$channelb-epg.xml`; - #print "cat $xmloutpath/__$channelb-epg.xml | $toolpath/perl/xmltv2foltia.pl\n"; - $oserr = `cat $xmloutpath/__$channelb-epg.xml | $toolpath/perl/xmltv2foltia.pl`; - unlink "$recfolderpath/__$channelb.m2t"; - unlink "$xmloutpath/__$channelb-epg.xml"; -}else{ - &writelog("epgimport DEBUG Skip CS."); -}#endif use -#}else{ -# if ($channel >= 223 ){#局指定があるなら -# &writelog("epgimport ERROR CS Station No. was ignored. CS EPG get long mode only."); -# } -#}#end if long - - -sub chkrecordingschedule{ -#放送予定まで近くなったら、チューナー使いつづけないようにEPG取得中断 -my $now = time() ; -my $fiveminitsafter = time() + 60 * 4; -my $rows = -2; -$now = &epoch2foldate($now); -$fiveminitsafter = &epoch2foldate($fiveminitsafter); - -#録画予定取得 -$sth = $dbh->prepare($stmt{'epgimport.6'}); -$sth->execute($now,$fiveminitsafter,$now,$fiveminitsafter); - -while (@data = $sth->fetchrow_array()) { -# -}#end while - -$rows = $sth->rows; - -if ($rows > 0 ){ - &writelog("epgimport ABORT The recording schedule had approached."); - exit ; -}else{ - &writelog("epgimport DEBUG Near rec program is $rows.:$now:$fiveminitsafter"); -}#end if -}#endsub chkrecordingschedule - Index: trunk/install/perl/envpolicyupdate.pl =================================================================== --- trunk/install/perl/envpolicyupdate.pl (リビジョン 94) +++ (リビジョン ) @@ -1,70 +1,0 @@ -#!/usr/bin/perl -# -# Anime recording system foltia -# http://www.dcc-jpl.com/soft/foltia/ -# -# -# envpolicyupdate.pl -# -# 環境ポリシー利用時に.htpasswdを再編する。 -# -# -# DCC-JPL Japan/foltia project -# -# - -use DBI; -use DBD::Pg; -use DBD::SQLite; - -$path = $0; -$path =~ s/envpolicyupdate.pl$//i; -if ($path ne "./"){ -push( @INC, "$path"); -} - -require "foltialib.pl"; - -# 環境ポリシーを使っているかPHPコンフィグファイル解析 -$returnparam = getphpstyleconfig("useenvironmentpolicy"); -eval "$returnparam\n"; - -if ($useenvironmentpolicy == 1){ -$returnparam = getphpstyleconfig("environmentpolicytoken"); -eval "$returnparam\n"; - - $dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; - - $envph = $dbh->prepare($stmt{'envpolicyupdate.1'}); - $envph->execute(); - -#なければつくる -unless (-e "$toolpath/.htpasswd"){ - $oserr = `touch $toolpath/.htpasswd`; -}else{ - $oserr = `mv $toolpath/.htpasswd $toolpath/htpasswd_foltia_old`; - $oserr = `touch $toolpath/.htpasswd`; -} - -while (@ref = $envph->fetchrow_array ){ - -if ($ref[0] == 0){ -#ユーザクラス -#0:特権管理者 -#1:管理者:予約削除、ファイル削除が出来る -#2:利用者:EPG追加、予約追加が出来る -#3:ビュアー:ファイルダウンロードが出来る -#4:ゲスト:インターフェイスが見れる - - $htpasswd = "$ref[2]"; -}else{ - $htpasswd = "$ref[2]"."$environmentpolicytoken"; -} - -$oserr = `htpasswd -b $toolpath/.htpasswd $ref[1] $htpasswd`; - - -}#end while -&writelog("envpolicyupdate htpasswd updated."); - -}#endif Index: trunk/install/perl/channelscan.pl =================================================================== --- trunk/install/perl/channelscan.pl (リビジョン 111) +++ (リビジョン ) @@ -1,387 +1,0 @@ -#!/usr/bin/perl -# -# -# Anime recording system foltia -# http://www.dcc-jpl.com/soft/foltia/ -# -# -# チャンネルスキャン -# 初期インストール時に受信可能局をスキャンします -# -# DCC-JPL Japan/foltia project -# - -#use DBI; -#use DBD::Pg; -#use DBD::SQLite; -#use Schedule::At; -#use Time::Local; -#use Jcode; - -#$path = $0; -#$path =~ s/channelscan.pl$//i; -#if ($path ne "./"){ -#push( @INC, "$path"); -#} - -#require "foltialib.pl"; - -my $recpt1path = "/home/foltia/perl/tool/recpt1"; #ほかのキャプチャデバイス作ってる人はココを変更 -my $epgdumppath = "/home/foltia/perl/tool"; #epgdumpのあるディレクトリ -my $recfolderpath = "/home/foltia/php/tv";#tsを出力するディレクトリ -my $xmloutpath = "/tmp"; -my $channel = 13 ; #地デジチャンネルは13-62 -my $oserr = ""; -my $line = ""; - -print "Initialize\n"; -print "Tool path are\n"; -print "REC:$recpt1path\n"; -print "EPGDUMP:$epgdumppath/epgdump\n"; -print "TS OUT:$recfolderpath/\n"; -print "XML OUT:$xmloutpath/\n"; - -#ツールがあるか確認 -unless (-e "$recpt1path"){ - print "Please install $recpt1path.\n"; - exit 1; -} -unless (-e "$epgdumppath/epgdump"){ - print "Please install $epgdumppath/epgdump.\n"; - exit 1; -} -unless (-e "$recfolderpath"){ - print "Please make directory $recfolderpath.\n"; - exit 1; -} -unless (-e "$xmloutpath"){ - print "Please make directory $xmloutpath.\n"; - exit 1; -} - - -#地デジスキャンループ -for ($channel = 13; $channel <= 62 ; $channel++){ - print "\nChannel: $channel\n"; - $oserr = `$recpt1path $channel 4 $recfolderpath/__$channel.m2t`; - $oserr = `$epgdumppath/epgdump $channel $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml`; - - if (-s "$xmloutpath/__$channel-epg.xml" ){ - print "\t\t This channel can view : $channel \n"; - open(XML, "< $xmloutpath/__$channel-epg.xml"); - while ( $line = ) { - #Jcode::convert(\$line,'euc','utf8'); - if($line =~ ///g; - #Jcode::convert(\$line,'utf8','euc'); - print "\t\t $channel $line\n"; - }#end if - }#end while - close(XML); - }else{ - print "\t\t Not Available : $channel \n"; - }#end if -}#end for - - -#BSデジタル -$channel = 211; - print "\nBS Digital Scan\n"; - $oserr = `$recpt1path $channel 4 $recfolderpath/__$channel.m2t`; - $oserr = `$epgdumppath/epgdump /BS $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml`; - - if (-s "$xmloutpath/__$channel-epg.xml" ){ - print "\t\t BS Digital can view : \n"; - open(XML, "< $xmloutpath/__$channel-epg.xml"); - while ( $line = ) { - #Jcode::convert(\$line,'euc','utf8'); - if($line =~ ///g; - #Jcode::convert(\$line,'utf8','euc'); - print "\t\t $line\n"; - }#end if - }#end while - close(XML); - }else{ - print "\t\t Not Available : BS Digital \n"; - }#end if - - -# -# NHK BS1 -# -# -# NHK BS2 -# -# -# NHK BSh -# -# -# BS日テレ -# -# -# BS朝日 -# -# -# BS-TBS -# -# -# BSジャパン -# -# -# BSフジ -# -# -# WOWOW -# -# -# WOWOW2 -# -# -# WOWOW3 -# -# -# スター・チャンネル -# -# -# BS11 -# -# -# TwellV -# -# - -#CSデジタル -$channel = "CS8"; - print "\nCS Digital Scan\n"; - $oserr = `$recpt1path $channel 4 $recfolderpath/__$channel.m2t`; - $oserr = `$epgdumppath/epgdump /CS $recfolderpath/__$channel.m2t $xmloutpath/__$channel-epg.xml`; - - if (-s "$xmloutpath/__$channel-epg.xml" ){ - print "\t\t CS Digital can view : \n"; - open(XML, "< $xmloutpath/__$channel-epg.xml"); - while ( $line = ) { - #Jcode::convert(\$line,'euc','utf8'); - if($line =~ ///g; - #Jcode::convert(\$line,'utf8','euc'); - print "\t\t $line\n"; - }#end if - }#end while - close(XML); - }else{ - print "\t\t Not Available : CS Digital \n"; - }#end if - -# -# スターchプラス -# -# -# 日本映画専門chHD -# -# -# フジテレビCSHD -# -# -# ショップチャンネル -# -# -# ザ・シネマ -# -# -# スカチャンHD800 -# -# -# スカチャン801 -# -# -# スカチャン802 -# -# -# e2プロモ -# -# -# インターローカルTV -# -# -# Jスポーツ ESPN -# -# -# FOX -# -# -# スペースシャワーTV -# -# -# カートゥーン ネット -# -# -# トゥーン・ディズニー -# -# -# 東映チャンネル -# -# -# 衛星劇場 -# -# -# チャンネルNECO -# -# -# 洋画★シネフィル -# -# -# スター・クラシック -# -# -# 時代劇専門チャンネル -# -# -# スーパードラマ -# -# -# AXN -# -# -# ナショジオチャンネル -# -# -# ワンテンポータル -# -# -# ゴルフチャンネル -# -# -# テレ朝チャンネル -# -# -# MTV -# -# -# ミュージック・エア -# -# -# 朝日ニュースター -# -# -# BBCワールド -# -# -# CNNj -# -# -# ジャスト・アイ -# -# -# Jスポーツ 1 -# -# -# Jスポーツ 2 -# -# -# JスポーツPlusH -# -# -# GAORA -# -# -# sky・Aスポーツ+ -# -# -# 宝塚プロモチャンネル -# -# -# SKY・STAGE -# -# -# チャンネル銀河 -# -# -# AT-X -# -# -# ヒストリーチャンネル -# -# -# スカチャン803 -# -# -# スカチャン804 -# -# -# ムービープラスHD -# -# -# ゴルフネットワーク -# -# -# LaLa HD -# -# -# フジテレビ739 -# -# -# フジテレビ721 -# -# -# アニマックス -# -# -# ディスカバリー -# -# -# アニマルプラネット -# -# -# C-TBSウエルカム -# -# -# QVC -# -# -# プライム365.TV -# -# -# ファミリー劇場 -# -# -# TBSチャンネル -# -# -# ディズニーチャンネル -# -# -# MUSIC ON! TV -# -# -# キッズステーション -# -# -# TBSニュースバード -# -# -# CS日本番組ガイド -# -# -# 日テレG+ -# -# -# fashion TV -# -# -# 日テレプラス -# -# -# エコミュージックTV -# -# -# Music Japan TV -# -# -# 日テレNEWS24 -# - - -#CATV -# /home/foltia/perl/tool/recpt1 --b25 C13 10 /home/foltia/php/tv/__C13.m2t -# /home/foltia/perl/tool/epgdump /CS /home/foltia/php/tv/__C13.m2t /tmp/__C13-epg.xml Index: trunk/install/perl/digitaltvrecording.pl =================================================================== --- trunk/install/perl/digitaltvrecording.pl (リビジョン 131) +++ (リビジョン ) @@ -1,409 +1,0 @@ -#!/usr/bin/perl -# -# Anime recording system foltia -# http://www.dcc-jpl.com/soft/foltia/ -# -#digitaltvrecording.pl -# PT1,PT2,friioをはじめとするデジタル録画プログラムを呼びだす録画モジュール。 -# -#usage digitaltvrecording.pl bandtype ch length(sec) [stationid] [sleeptype] [filename] [TID] [NO] [unittype] -#引数 -#bandtype : 0:地デジ 1:BSデジタル 2:CSデジタル -#ch :録画チャンネル (地デジはそのまま渡す、BS/CSデジタルは基本的にチャンネル BS1/BS2など同じ数時に) -#length(sec) :録画秒数 [必須項目] -#[stationid] :foltia stationid -#[sleeptype] :0かN Nならスリープなしで録画 -#[filename] :出力ファイル名 -#[TID] :しょぼかるタイトルID -#[NO] :その番組の放送話数 -#[unittype] :friioかfriioBSかユニデンチューナかHDUSかなど(未使用) -# -# DCC-JPL Japan/foltia project -# -# - -$path = $0; -$path =~ s/digitaltvrecording.pl$//i; -if ($path ne "./"){ -push( @INC, "$path"); -} - -#tvConfig.pl ------------------------------- -$extendrecendsec = 10; #recording end second. -#$startupsleeptime = 52; #process wait(MAX60sec) -$startupsleeptime = 32; #process wait(MAX60sec) -#------------------------------- - -require 'foltialib.pl'; - - &writelog("digitaltvrecording: DEBUG $ARGV[0] $ARGV[1] $ARGV[2] $ARGV[3] $ARGV[4] $ARGV[5] $ARGV[6] $ARGV[7] $ARGV[8]"); - - -#準備 -&prepare; -#もし録画が走ってたら、止める -#$reclengthsec = &chkrecprocess(); -#&setbitrate; -#&chkextinput; -#$reclengthsec = $reclengthsec + $extendrecendsec ; - -&calldigitalrecorder; - -&writelog("digitaldigitaltvrecording:RECEND:$bandtype $recch $lengthsec $stationid $sleeptype $filename $tid $countno $unittype -"); - -# -- これ以下サブルーチン ---------------------------- - - -sub prepare{ - -#引数エラー処理 -$bandtype = $ARGV[0] ; -$recch = $ARGV[1] ; -$lengthsec = $ARGV[2] ; -$stationid = $ARGV[3] ; -$sleeptype = $ARGV[4] ; -$filename = $ARGV[5] ; -$tid = $ARGV[6] ; -$countno = $ARGV[7] ; -$unittype = $ARGV[8] ; - -if (($bandtype eq "" )|| ($recch eq "")|| ($lengthsec eq "")){ - print "usage digitaltvrecording.pl bandtype ch length(sec) [stationid] [sleeptype] [filename] [TID] [NO] [unittype]\n"; - exit; -} - -my $intval = $recch % 10; # 0〜9 sec -my $startupsleep = $startupsleeptime - $intval; # 18〜27 sec -$reclengthsec = $lengthsec + (60 - $startupsleep) + 1; # - -if ( $sleeptype ne "N"){ - &writelog("digitaltvrecording: DEBUG SLEEP $startupsleeptime:$intval:$startupsleep:$reclengthsec"); - sleep ( $startupsleep); - #2008/08/12_06:39:00 digitaltvrecording: DEBUG SLEEP 17:23:-6:367 -}else{ - &writelog("digitaltvrecording: DEBUG RAPID START"); -} -## recfriio このへんどうなってるの? -#if ($recunits > 1){ -#my $deviceno = $recunits - 1;#3枚差しのとき/dev/video2から使う -# $recdevice = "/dev/video$deviceno"; -# $recch = $ARGV[0] ; -#}else{ -##1枚差し -# $recdevice = "/dev/video0"; -# $recch = $ARGV[0] ; -#} - -$outputpath = "$recfolderpath"."/"; - -if ($countno eq "0"){ - $outputfile = $outputpath.$tid."--"; -}else{ - $outputfile = $outputpath.$tid."-".$countno."-"; -} -#2番目以降のクリップでファイル名指定があったら - if ($filename ne ""){ - - $outputfile = $filename ; - $outputfile = &filenameinjectioncheck($outputfile); - $outputfilewithoutpath = $outputfile ; - $outputfile = $outputpath.$outputfile ; - &writelog("digitaltvrecording: DEBUG FILENAME ne null \$outputfile $outputfile "); - }else{ - $outputfile .= strftime("%Y%m%d-%H%M", localtime(time + 60)); - chomp($outputfile); - $outputfile .= ".m2t"; - $outputfilewithoutpath = $outputfile ; - &writelog("digitaltvrecording: DEBUG FILENAME is null \$outputfile $outputfile "); - } - - -@wday_name = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); -$sleepcounter = 0; -$cmd=""; - -#二重録りなど既に同名ファイルがあったら中断 -if ( -e "$outputfile" ){ - if ( -s "$outputfile" ){ - &writelog("digitaltvrecording :ABORT :recfile $outputfile exist."); - exit 1; - } -} - -}#end prepare - - -#------------------------------------------------------------------------------------ -# -sub calldigitalrecorder{ -# -#白friioと黒friio、PT1対応 -#2008/10/23 recfriio4仕様に変更 -# -my $oserr = 0; -my $originalrecch = $recch; -my $pt1recch = $recch; -my $errorflag = 0; -if ($bandtype == 0){ -# 地デジ friio - -}elsif($bandtype == 1){ -# BS/CS friio - #recfriiobs用チャンネルリマップ - if ($recch == 101) { - $bssplitflag = $recch; - $recch = "b10";#22 : NHK BS1/BS2 - }elsif($recch == 102){ - $bssplitflag = $recch; - $recch = "b10";#22 : NHK BS1/BS2 - }elsif($recch == 103){ - $recch = "b11";#23 : NHK hi - }elsif($recch == 141){ - $recch = "b8";# 20 : BS-NTV - }elsif($recch == 151){ - $recch = "b1";#13 : BS-Asahi - }elsif($recch == 161){ - $recch = "b2";#14 : BS-i - }elsif($recch == 171){ - $recch = "b4";#16 : BS-Japan - }elsif($recch == 181){ - $recch = "b9";#21 : BS-Fuji - }elsif($recch == 191){ - $recch = "b3";#15 : WOWOW - }elsif($recch == 192){ - $recch = "b3";#15 : WOWOW - }elsif($recch == 193){ - $recch = "b3";#15 : WOWOW - }elsif($recch == 200){ - $recch = "b6";# b6 # Star Channel - }elsif($recch == 211){ - $recch = "b5";#17 : BS11 - }else{ - $recch = "b7";#19 : TwellV - } -#PT1はそのまま通る - -}elsif($bandtype == 2){ -# recpt1でのみ動作確認 - if($recch == 335){ - $pt1recch = "CS8";#335ch:キッズステーション HD - }elsif($recch == 237){ - $pt1recch = "CS2";#237ch:スター・チャンネル プラス - }elsif($recch == 239){ - $pt1recch = "CS2";#239ch:日本映画専門チャンネルHD - }elsif($recch == 306){ - $pt1recch = "CS2";#306ch:フジテレビCSHD - }elsif($recch == 100){ - $pt1recch = "CS4";#100ch:e2プロモ - }elsif($recch == 256){ - $pt1recch = "CS4";#256ch:J sports ESPN - }elsif($recch == 312){ - $pt1recch = "CS4";#312ch:FOX - }elsif($recch == 322){ - $pt1recch = "CS4";#322ch:スペースシャワーTV - }elsif($recch == 331){ - $pt1recch = "CS4";#331ch:カートゥーンネットワーク - }elsif($recch == 194){ - $pt1recch = "CS4";#194ch:インターローカルTV - }elsif($recch == 334){ - $pt1recch = "CS4";#334ch:トゥーン・ディズニー - }elsif($recch == 221){ - $pt1recch = "CS6";#221ch:東映チャンネル - }elsif($recch == 222){ - $pt1recch = "CS6";#222ch:衛星劇場 - }elsif($recch == 223){ - $pt1recch = "CS6";#223ch:チャンネルNECO - }elsif($recch == 224){ - $pt1recch = "CS6";#224ch:洋画★シネフィル・イマジカ - }elsif($recch == 292){ - $pt1recch = "CS6";#292ch:時代劇専門チャンネル - }elsif($recch == 238){ - $pt1recch = "CS6";#238ch:スター・チャンネル クラシック - }elsif($recch == 310){ - $pt1recch = "CS6";#310ch:スーパー!ドラマTV - }elsif($recch == 311){ - $pt1recch = "CS6";#311ch:AXN - }elsif($recch == 343){ - $pt1recch = "CS6";#343ch:ナショナルジオグラフィックチャンネル - }elsif($recch == 055){ - $pt1recch = "CS8";#055ch:ショップ チャンネル - }elsif($recch == 228){ - $pt1recch = "CS10";#228ch:ザ・シネマ - }elsif($recch == 800){ - $pt1recch = "CS10";#800ch:スカチャンHD800 - }elsif($recch == 801){ - $pt1recch = "CS10";#801ch:スカチャン801 - }elsif($recch == 802){ - $pt1recch = "CS10";#802ch:スカチャン802 - }elsif($recch == 260){ - $pt1recch = "CS12";#260ch:ザ・ゴルフ・チャンネル - }elsif($recch == 303){ - $pt1recch = "CS12";#303ch:テレ朝チャンネル - }elsif($recch == 323){ - $pt1recch = "CS12";#323ch:MTV 324ch:大人の音楽専門TV◆ミュージック・エア - }elsif($recch == 352){ - $pt1recch = "CS12";#352ch:朝日ニュースター - }elsif($recch == 353){ - $pt1recch = "CS12";#353ch:BBCワールドニュース - }elsif($recch == 354){ - $pt1recch = "CS12";#354ch:CNNj - }elsif($recch == 361){ - $pt1recch = "CS12";#361ch:ジャスト・アイ インフォメーション - }elsif($recch == 251){ - $pt1recch = "CS14";#251ch:J sports 1 - }elsif($recch == 252){ - $pt1recch = "CS14";#252ch:J sports 2 - }elsif($recch == 253){ - $pt1recch = "CS14";#253ch:J sports Plus - }elsif($recch == 254){ - $pt1recch = "CS14";#254ch:GAORA - }elsif($recch == 255){ - $pt1recch = "CS14";#255ch:スカイ・Asports+ - }elsif($recch == 305){ - $pt1recch = "CS16";#305ch:チャンネル銀河 - }elsif($recch == 333){ - $pt1recch = "CS16";#333ch:アニメシアターX(AT-X) - }elsif($recch == 342){ - $pt1recch = "CS16";#342ch:ヒストリーチャンネル - }elsif($recch == 290){ - $pt1recch = "CS16";#290ch:TAKARAZUKA SKYSTAGE - }elsif($recch == 803){ - $pt1recch = "CS16";#803ch:スカチャン803 - }elsif($recch == 804){ - $pt1recch = "CS16";#804ch:スカチャン804 - }elsif($recch == 240){ - $pt1recch = "CS18";#240ch:ムービープラスHD - }elsif($recch == 262){ - $pt1recch = "CS18";#262ch:ゴルフネットワーク - }elsif($recch == 314){ - $pt1recch = "CS18";#314ch:LaLa HDHV - }elsif($recch == 258){ - $pt1recch = "CS20";#258ch:フジテレビ739 - }elsif($recch == 302){ - $pt1recch = "CS20";#302ch:フジテレビ721 - }elsif($recch == 332){ - $pt1recch = "CS20";#332ch:アニマックス - }elsif($recch == 340){ - $pt1recch = "CS20";#340ch:ディスカバリーチャンネル - }elsif($recch == 341){ - $pt1recch = "CS20";#341ch:アニマルプラネット - }elsif($recch == 160){ - $pt1recch = "CS22";#160ch:C-TBSウェルカムチャンネル - }elsif($recch == 161){ - $pt1recch = "CS22";#161ch:QVC - }elsif($recch == 185){ - $pt1recch = "CS22";#185ch:プライム365.TV - }elsif($recch == 293){ - $pt1recch = "CS22";#293ch:ファミリー劇場 - }elsif($recch == 301){ - $pt1recch = "CS22";#301ch:TBSチャンネル - }elsif($recch == 304){ - $pt1recch = "CS22";#304ch:ディズニー・チャンネル - }elsif($recch == 325){ - $pt1recch = "CS22";#325ch:MUSIC ON! TV - #}elsif($recch == 330){ - # $pt1recch = "CS22";#330ch:キッズステーション #HD化により2010/4変更 - }elsif($recch == 351){ - $pt1recch = "CS22";#351ch:TBSニュースバード - }elsif($recch == 257){ - $pt1recch = "CS24";#ch:日テレG+ - }elsif($recch == 291){ - $pt1recch = "CS24";#ch:fashiontv - }elsif($recch == 300){ - $pt1recch = "CS24";#ch:日テレプラス - }elsif($recch == 320){ - $pt1recch = "CS24";#ch:安らぎの音楽と風景/エコミュージックTV - }elsif($recch == 321){ - $pt1recch = "CS24";#ch:MusicJapan TV - }elsif($recch == 350){ - $pt1recch = "CS24";#ch:日テレNEWS24 - }# end if CSリマップ - -}else{ - &writelog("digitaltvrecording :ERROR :Unsupported and type (digital CS)."); - exit 3; -} - -# PT1 -# b25,recpt1があるか確認 - if (-e "$toolpath/perl/tool/recpt1"){ - if ($bandtype >= 1){ #BS/CSなら - &writelog("digitaltvrecording DEBUG recpt1 --b25 --sid $originalrecch $pt1recch $reclengthsec $outputfile "); - $oserr = system("$toolpath/perl/tool/recpt1 --b25 --sid $originalrecch $pt1recch $reclengthsec $outputfile "); - }else{ #地デジ - &writelog("digitaltvrecording DEBUG recpt1 --b25 $originalrecch $reclengthsec $outputfile "); - $oserr = system("$toolpath/perl/tool/recpt1 --b25 $originalrecch $reclengthsec $outputfile "); - } - $oserr = $oserr >> 8; - if ($oserr > 0){ - &writelog("digitaltvrecording :ERROR :PT1 is BUSY.$oserr"); - $errorflag = 2; - } - }else{ # エラー recpt1がありません - &writelog("digitaltvrecording :ERROR :recpt1 not found. You must install $toolpath/tool/b25 and $toolpath/tool/recpt1."); - $errorflag = 1; - } -# friio -if ($errorflag >= 1 ){ -# b25,recfriioがあるか確認 - if (-e "$toolpath/perl/tool/recfriio"){ - - if (! -e "$toolpath/perl/tool/friiodetect"){ - system("touch $toolpath/perl/tool/friiodetect"); - system("chown foltia:foltia $toolpath/perl/tool/friiodetect"); - system("chmod 775 $toolpath/perl/tool/friiodetect"); - &writelog("digitaltvrecording :DEBUG make lock file.$toolpath/perl/tool/friiodetect"); - } - &writelog("digitaltvrecording DEBUG recfriio --b25 --lockfile $toolpath/perl/tool/friiodetect $recch $reclengthsec $outputfile "); - $oserr = system("$toolpath/perl/tool/recfriio --b25 --lockfile $toolpath/perl/tool/friiodetect $recch $reclengthsec $outputfile "); - $oserr = $oserr >> 8; - if ($oserr > 0){ - &writelog("digitaltvrecording :ERROR :friio is BUSY.$oserr"); - exit 2; - } - -#BS1/BS2などのスプリットを -if ($bssplitflag == 101){ - if (-e "$toolpath/perl/tool/TsSplitter.exe"){ - # BS1 - system("wine $toolpath/perl/tool/TsSplitter.exe -EIT -ECM -EMM -OUT \"$outputpath\" -HD -SD2 -SD3 -1SEG -LOGFILE -WAIT2 $outputfile"); - $splitfile = $outputfile; - $splitfile =~ s/\.m2t$/_SD1.m2t/; - if (-e "$splitfile"){ - system("rm -rf $outputfile ; mv $splitfile $outputfile"); - &writelog("digitaltvrecording DEBUG rm -rf $outputfile ; mv $splitfile $outputfile: $?."); - }else{ - &writelog("digitaltvrecording ERROR File not found:$splitfile."); - } - }else{ - &writelog("digitaltvrecording ERROR $toolpath/perl/tool/TsSplitter.exe not found."); - } -}elsif($bssplitflag == 102){ - if (-e "$toolpath/perl/tool/TsSplitter.exe"){ - # BS2 - system("wine $toolpath/perl/tool/TsSplitter.exe -EIT -ECM -EMM -OUT \"$outputpath\" -HD -SD1 -SD3 -1SEG -LOGFILE -WAIT2 $outputfile"); - $splitfile = $outputfile; - $splitfile =~ s/\.m2t$/_SD2.m2t/; - if (-e "$splitfile"){ - system("rm -rf $outputfile ; mv $splitfile $outputfile"); - &writelog("digitaltvrecording DEBUG rm -rf $outputfile ; mv $splitfile $outputfile: $?."); - }else{ - &writelog("digitaltvrecording ERROR File not found:$splitfile."); - } - }else{ - &writelog("digitaltvrecording ERROR $toolpath/perl/tool/TsSplitter.exe not found."); - } -}else{ - &writelog("digitaltvrecording DEBUG not split TS.$bssplitflag"); -}# endif #BS1/BS2などのスプリットを - - }else{ # エラー recfriioがありません - &writelog("digitaltvrecording :ERROR :recfriio not found. You must install $toolpath/perl/tool/b25 and $toolpath/perl/tool/recfriio:$errorflag"); - #exit 1; - exit $errorflag; - } -}#end if errorflag -}#end calldigitalrecorder - - Index: trunk/install/perl/digitalradiorecording.pl =================================================================== --- trunk/install/perl/digitalradiorecording.pl (リビジョン 105) +++ (リビジョン ) @@ -1,143 +1,0 @@ -#!/usr/bin/perl -# -# Anime recording system foltia -# http://www.dcc-jpl.com/soft/foltia/ -# -#digitalradiorecording.pl -# IPサイマルラジオ「radiko」を録音する。 -# -#usage digitalradiorecording.pl stationname length(sec) filename -#引数 -#stationname : radikoの使う曲識別子 例:文化放送 QRR [必須項目] -#length(sec) :録画秒数 [必須項目] -#filename :出力ファイル名 [必須項目] -# -# DCC-JPL Japan/foltia project -# -# - -$path = $0; -$path =~ s/digitalradiorecording.pl$//i; -if ($path ne "./"){ -push( @INC, "$path"); -} - -#tvConfig.pl ------------------------------- -$extendrecendsec = 10; #recording end second. -#$startupsleeptime = 52; #process wait(MAX60sec) -$startupsleeptime = 57; #process wait(MAX60sec) -#------------------------------- - -require 'foltialib.pl'; - -# &writelog("digitalradiorecording.pl: DEBUG $ARGV[0] $ARGV[1] "); - - -#準備 -&prepare; - - -&calldigitalrecorder; - -# &writelog("digitaldigitalradiorecording:RECEND:$bandtype $recch $lengthsec $stationid $sleeptype $filename $tid $countno $unittype"); - -# -- これ以下サブルーチン ---------------------------- - - -sub prepare{ - -#引数エラー処理 -$stationname = $ARGV[0] ; -$lengthsec = $ARGV[1] ; -$filename = $ARGV[2] ; - - -if (($stationname eq "" ) || ($lengthsec eq "") || ($filename eq "")){ - print "usage digitalradiorecording.pl stationname length(sec) filename\n"; - exit; -} - -#my $intval = $recch % 10; # 0〜9 sec -my $intval = 0; -my $startupsleep = $startupsleeptime - $intval; # 18〜27 sec -$reclengthsec = $lengthsec + (60 - $startupsleep) + 10; # - -if ( $sleeptype ne "N"){ - &writelog("digitalradiorecording: DEBUG SLEEP $startupsleeptime:$intval:$startupsleep:$reclengthsec"); - sleep ( $startupsleep); - #2008/08/12_06:39:00 digitalradiorecording: DEBUG SLEEP 17:23:-6:367 -}else{ - &writelog("digitalradiorecording: DEBUG RAPID START"); -} - -$outputpath = "$recfolderpath"."/"; - -if ($countno eq "0"){ - $outputfile = $outputpath.$tid."--"; -}else{ - $outputfile = $outputpath.$tid."-".$countno."-"; -} -#2番目以降のクリップでファイル名指定があったら - if ($filename ne ""){ - - $outputfile = $filename ; - $outputfile = &filenameinjectioncheck($outputfile); - $outputfilewithoutpath = $outputfile ; - $outputfile = $outputpath.$outputfile ; - &writelog("digitalradiorecording: DEBUG FILENAME ne null \$outputfile $outputfile "); - }else{ - $outputfile .= strftime("%Y%m%d-%H%M", localtime(time + 60)); - chomp($outputfile); - $outputfile .= ".aac"; - $outputfilewithoutpath = $outputfile ; - &writelog("digitalradiorecording: DEBUG FILENAME is null \$outputfile $outputfile "); - } - - -@wday_name = ("Sun","Mon","Tue","Wed","Thu","Fri","Sat"); -$sleepcounter = 0; -$cmd=""; - -#二重録りなど既に同名ファイルがあったら中断 -if ( -e "$outputfile" ){ - if ( -s "$outputfile" ){ - &writelog("digitalradiorecording :ABORT :recfile $outputfile exist."); - exit 1; - } -} - -}#end prepare - - - -sub calldigitalrecorder{ - -#if (-e "$toolpath/perl/tool/ffmpeg"){ -#2010/4/7 radikoに対策されたのでffmpeg直接受信できなくなった -#./ffmpeg -i rtmp://radiko.smartstream.ne.jp:1935/QRR/_defInst_/simul-stream -t 180 -acodec copy ~/php/tv/qrr.aac -#&writelog("digitalradiorecording :DEBUG :$toolpath/perl/tool/ffmpeg -y -i rtmp://radiko.smartstream.ne.jp:1935/$stationname/_defInst_/simul-stream -t $reclengthsec -acodec copy $outputfile."); -#system("$toolpath/perl/tool/ffmpeg -y -i rtmp://radiko.smartstream.ne.jp:1935/$stationname/_defInst_/simul-stream -t $reclengthsec -acodec copy $outputfile"); - -if (-e "$toolpath/perl/tool/rtmpdump"){ -#./rtmpdump -y "simul-stream" -n "radiko.smartstream.ne.jp" -c 1935 -p "http://radiko.jp/player/player.html#QRR" -a "QRR/_defInst_" -f "WIN 10,0,45,2" -v -B 180 -o joqr.flv - -&writelog("digitalradiorecording :DEBUG :$toolpath/perl/tool/rtmpdump -r \"rtmpe://radiko.smartstream.ne.jp:1935/$stationname/_defInst_/simul-stream\" -s \"http://radiko.jp/player/player.html#${stationname}\" -f \"WIN 10,0,45,2\" -v -B $reclengthsec -o ${outputfile}.flv"); - -#system("$toolpath/perl/tool/rtmpdump -y \"simul-stream\" -n \"radiko.smartstream.ne.jp\" -c 1935 -p \"http://radiko.jp/player/player.html#${stationname}\" -a \"$stationname/_defInst_\" -f \"WIN 10,0,45,2\" -v -B $reclengthsec -o ${outputfile}.flv"); -system("$toolpath/perl/tool/rtmpdump -r \"rtmpe://radiko.smartstream.ne.jp:1935/$stationname/_defInst_/simul-stream\" -s \"http://radiko.jp/player/player.html#${stationname}\" -f \"WIN 10,0,45,2\" -v -B $reclengthsec -o ${outputfile}.flv"); - -&writelog("digitalradiorecording :DEBUG :ffmpeg -y -i ${outputfile}.flv -vn -acodec copy $outputfile"); - -system("ffmpeg -y -i ${outputfile}.flv -vn -acodec copy $outputfile"); - -unlink("${outputfile}.flv"); -}else{ - &writelog("digitalradiorecording :ABORT :File not found,recordable ffmpeg on $toolpath/perl/tool/ffmpeg. Show http://d.hatena.ne.jp/nazodane/20100315/1268646192 "); - exit 1; -} - - - -}# end sub calldigitalrecorder - - Index: trunk/install/perl/ipodtranscode.pl =================================================================== --- trunk/install/perl/ipodtranscode.pl (リビジョン 125) +++ (リビジョン ) @@ -1,553 +1,0 @@ -#!/usr/bin/perl -#usage ipodtranscode.pl -# -# Anime recording system foltia -# http://www.dcc-jpl.com/soft/foltia/ -# -# iPod MPEG4/H.264トラコン -# ffmpegを呼び出して変換 -# -# DCC-JPL Japan/foltia project -# - -use DBI; -use DBD::Pg; -use DBD::SQLite; -use Jcode; - -$path = $0; -$path =~ s/ipodtranscode.pl$//i; -if ($path ne "./"){ -push( @INC, "$path"); -} -require "foltialib.pl"; - - -# 二重起動の確認! -$processes = &processfind("ipodtranscode.pl"); -#$processes = $processes + &processfind("ffmpeg"); - -if ($processes > 1 ){ -&writelog("ipodtranscode processes exist. exit:"); -exit; -}else{ -#&writelog("ipodtranscode.pl Normal launch."); -} - -#DB初期化 -$dbh = DBI->connect($DSN,$DBUser,$DBPass) ||die $DBI::error;; - -# タイトル取得 -#トラコンフラグがたっていてステータス50以上150未満のファイルを古い順にひとつ探す -# 数数える -#$DBQuery = "SELECT count(*) FROM foltia_subtitle, foltia_program, foltia_m2pfiles -#WHERE filestatus >= $FILESTATUSRECEND AND filestatus < $FILESTATUSTRANSCODECOMPLETE AND foltia_program.tid = foltia_subtitle.TID AND foltia_program.PSP = 1 AND foltia_m2pfiles.m2pfilename = foltia_subtitle.m2pfilename "; -#$sth = $dbh->prepare($DBQuery); -#$sth->execute(); -#@titlecount= $sth->fetchrow_array; -&writelog("ipodtranscode starting up."); - -$counttranscodefiles = &counttranscodefiles(); -if ($counttranscodefiles == 0){ - &writelog("ipodtranscode No MPEG2 files to transcode."); - exit; -} -sleep 30; - -while ($counttranscodefiles >= 1){ - $sth = $dbh->prepare($stmt{'ipodtranscode.1'}); - $sth->execute($FILESTATUSRECEND, $FILESTATUSTRANSCODECOMPLETE, ); -@dbparam = $sth->fetchrow_array; -#print "$dbparam[0],$dbparam[1],$dbparam[2],$dbparam[3],$dbparam[4],$dbparam[5]\n"; -#&writelog("ipodtranscode DEBUG $DBQuery"); -&writelog("ipodtranscode DEBUG $dbparam[0],$dbparam[1],$dbparam[2],$dbparam[3],$dbparam[4],$dbparam[5]"); -$pid = $dbparam[0]; -$tid = $dbparam[1]; -$inputmpeg2 = $recfolderpath."/".$dbparam[2]; # path付き -$mpeg2filename = $dbparam[2]; # pathなし -$filestatus = $dbparam[3]; -$aspect = $dbparam[4];# 16,1 (超額縁),4,3 -$countno = $dbparam[5]; -$mp4filenamestring = &mp4filenamestringbuild($pid); - -if (-e $inputmpeg2){#MPEG2ファイルが存在していれば - -&writelog("ipodtranscode DEBUG mp4filenamestring $mp4filenamestring"); -#展開ディレクトリ作成 -$pspdirname = &makemp4dir($tid); -$mp4outdir = $pspdirname ; -# 実際のトラコン -# タイトル取得 -if ($pid ne ""){ - $sth = $dbh->prepare($stmt{'ipodtranscode.2'}); - $sth->execute($pid); -@programtitle = $sth->fetchrow_array; -$programtitle[0] =~ s/\"/\\"/gi; -$programtitle[2] =~ s/\"/\\"/gi; - - if ($pid > 0){ - if ($programtitle[1] ne ""){ - $movietitle = " -title \"$programtitle[0] 第$programtitle[1]話 $programtitle[2]\" "; - $movietitleeuc = " -t \"$programtitle[0] 第$programtitle[1]話 $programtitle[2]\" "; - }else{ - $movietitle = " -title \"$programtitle[0] $programtitle[2]\" "; - $movietitleeuc = " -t \"$programtitle[0] $programtitle[2]\" "; - } - }elsif($pid < 0){ - #EPG - $movietitle = " -title \"$programtitle[2]\" "; - $movietitleeuc = " -t \"$programtitle[2]\" "; - }else{# 0 - #空白 - $movietitle = ""; - $movietitleeuc = ""; - } -#Jcode::convert(\$movietitle,'utf8');# Title入れるとiTunes7.0.2がクラッシュする - $movietitle = ""; - $movietitleeuc = ""; - -} - -if ($filestatus <= $FILESTATUSRECEND){ -} - -if ($filestatus <= $FILESTATUSWAITINGCAPTURE){ -#なにもしない -} - -if ($filestatus <= $FILESTATUSCAPTURE){ -#unlink -# Starlight breaker向けキャプチャ画像作成 -if (-e "$toolpath/perl/captureimagemaker.pl"){ - &writelog("ipodtranscode Call captureimagemaker $mpeg2filename"); -&changefilestatus($pid,$FILESTATUSCAPTURE); - system ("$toolpath/perl/captureimagemaker.pl $mpeg2filename"); -&changefilestatus($pid,$FILESTATUSCAPEND); -} -} - -if ($filestatus <= $FILESTATUSCAPEND){ -# サムネイル作る -&makethumbnail(); -&changefilestatus($pid,$FILESTATUSTHMCREATE); -} - -if ($filestatus <= $FILESTATUSWAITINGTRANSCODE){ -} - -$filenamebody = $inputmpeg2 ; -$filenamebody =~ s/.m2t$|.ts$|.m2p$|.mpg$|.aac$//gi; - -#デジタルかアナログか -if ($inputmpeg2 =~ /m2t$|ts$|aac$/i){ - -if ($filestatus <= $FILESTATUSTRANSCODETSSPLITTING){ - unlink("${filenamebody}_tss.m2t"); - unlink("${filenamebody}_HD.m2t"); -} -if ($filestatus <= $FILESTATUSTRANSCODEFFMPEG){ - unlink("$filenamebody.264"); - # H.264出力 - $trcnmpegfile = $inputmpeg2 ; - # アスペクト比 - if ($aspect == 1){#超額縁 - $cropopt = " -croptop 150 -cropbottom 150 -cropleft 200 -cropright 200 "; - }elsif($aspect == 4){#SD - $cropopt = " -croptop 6 -cropbottom 6 -cropleft 8 -cropright 8 "; - }else{#16:9 - $cropopt = " -croptop 6 -cropbottom 6 -cropleft 8 -cropright 8 "; - } - # クオリティごとに - if (($trconqty eq "")||($trconqty == 1)){ - $ffmpegencopt = " -threads 0 -s 360x202 -deinterlace -r 24.00 -vcodec libx264 -g 300 -b 330000 -level 13 -loop 1 -sc_threshold 60 -partp4x4 1 -rc_eq 'blurCplx^(1-qComp)' -refs 3 -maxrate 700000 -async 50 -f h264 $filenamebody.264"; - }elsif($trconqty == 2){ -# $ffmpegencopt = " -s 480x272 -deinterlace -r 29.97 -vcodec libx264 -g 300 -b 400000 -level 13 -loop 1 -sc_threshold 60 -partp4x4 1 -rc_eq 'blurCplx^(1-qComp)' -refs 3 -maxrate 700000 -async 50 -f h264 $filenamebody.264"; -# for ffmpeg 0.5 or later - $ffmpegencopt = " -threads 0 -s 480x272 -deinterlace -r 29.97 -vcodec libx264 -vpre default -g 300 -b 400000 -level 13 -sc_threshold 60 -rc_eq 'blurCplx^(1-qComp)' -refs 3 -maxrate 700000 -async 50 -f h264 $filenamebody.264"; - }elsif($trconqty == 3){#640x352 -# $ffmpegencopt = " -s 640x352 -deinterlace -r 29.97 -vcodec libx264 -g 100 -b 600000 -level 13 -loop 1 -sc_threshold 60 -partp4x4 1 -rc_eq 'blurCplx^(1-qComp)' -refs 3 -maxrate 700000 -async 50 -f h264 $filenamebody.264"; -# for ffmpeg 0.5 or later - $ffmpegencopt = " -threads 0 -s 640x352 -deinterlace -r 29.97 -vcodec libx264 -vpre default -g 100 -b 600000 -level 13 -sc_threshold 60 -rc_eq 'blurCplx^(1-qComp)' -refs 3 -maxrate 700000 -async 50 -f h264 $filenamebody.264"; - } - &changefilestatus($pid,$FILESTATUSTRANSCODEFFMPEG); -# &writelog("ipodtranscode ffmpeg $filenamebody.264"); -# system ("ffmpeg -y -i $trcnmpegfile $cropopt $ffmpegencopt"); -#まずTsSplitする →ワンセグをソースにしてしまわないように - if (! -e "$filenamebody.264"){ - &changefilestatus($pid,$FILESTATUSTRANSCODETSSPLITTING); - unlink("${filenamebody}_tss.m2t"); - unlink("${filenamebody}_HD.m2t"); - if (-e "$toolpath/perl/tool/tss.py"){ - &writelog("ipodtranscode tss $inputmpeg2"); - system("$toolpath/perl/tool/tss.py $inputmpeg2"); - }else{ - # TsSplit -# &writelog("ipodtranscode TsSplitter $inputmpeg2"); -# system("wine $toolpath/perl/tool/TsSplitter.exe -EIT -ECM -EMM -SD -1SEG -WAIT2 $inputmpeg2"); - } - if(-e "${filenamebody}_tss.m2t"){ - $trcnmpegfile = "${filenamebody}_tss.m2t"; - }elsif (-e "${filenamebody}_HD.m2t"){ - $trcnmpegfile = "${filenamebody}_HD.m2t"; - }else{ - &writelog("ipodtranscode ERR NOT Exist ${filenamebody}_HD.m2t"); - $trcnmpegfile = $inputmpeg2 ; - } - #Splitファイルの確認 - $trcnmpegfile = &validationsplitfile($inputmpeg2,$trcnmpegfile); - #tss.pyに失敗してたなら強制的にWINEでTsSplit.exe - if($trcnmpegfile eq $inputmpeg2){ - - # TsSplit - &writelog("ipodtranscode WINE TsSplitter.exe $inputmpeg2"); - system("wine $toolpath/perl/tool/TsSplitter.exe -EIT -ECM -EMM -SD -1SEG -WAIT2 $inputmpeg2"); - if (-e "${filenamebody}_HD.m2t"){ - $trcnmpegfile = "${filenamebody}_HD.m2t"; - #Splitファイルの確認 - $trcnmpegfile = &validationsplitfile($inputmpeg2,$trcnmpegfile); -# if($trcnmpegfile ne $inputmpeg2){ -# &changefilestatus($pid,$FILESTATUSTRANSCODEFFMPEG); -# &writelog("ipodtranscode ffmpeg retry ; WINE TsSplitter.exe $trcnmpegfile"); -# system ("ffmpeg -y -i $trcnmpegfile $cropopt $ffmpegencopt"); -# }else{ -# &writelog("ipodtranscode WINE TsSplit.exe fail"); -# } - }else{ - &writelog("ipodtranscode WINE TsSplitter.exe ;Not exist ${filenamebody}_HD.m2t"); - }#endif -e ${filenamebody}_HD.m2t - - }#endif $trcnmpegfile eq $inputmpeg2 - - - #再ffmpeg - &changefilestatus($pid,$FILESTATUSTRANSCODEFFMPEG); - &writelog("ipodtranscode ffmpeg retry $filenamebody.264"); - system ("ffmpeg -y -i $trcnmpegfile $cropopt $ffmpegencopt"); - } - #もしエラーになったらcropやめる - if (! -e "$filenamebody.264"){ - #再ffmpeg - &changefilestatus($pid,$FILESTATUSTRANSCODEFFMPEG); - &writelog("ipodtranscode ffmpeg retry no crop $filenamebody.264"); - system ("ffmpeg -y -i $trcnmpegfile $ffmpegencopt"); - } - #強制的にWINEでTsSplit.exe - if (! -e "$filenamebody.264"){ - } - #それでもエラーならsplitしてないファイルをターゲットに - if (! -e "$filenamebody.264"){ - #再ffmpeg - &changefilestatus($pid,$FILESTATUSTRANSCODEFFMPEG); - &writelog("ipodtranscode ffmpeg retry No splited originalTS file $filenamebody.264"); - system ("ffmpeg -y -i $inputmpeg2 $ffmpegencopt"); - } -} -if ($filestatus <= $FILESTATUSTRANSCODEWAVE){ - # WAVE出力 - unlink("${filenamebody}.wav"); - &changefilestatus($pid,$FILESTATUSTRANSCODEWAVE); - &writelog("ipodtranscode mplayer $filenamebody.wav"); - system ("mplayer $trcnmpegfile -vc null -vo null -ao pcm:file=$filenamebody.wav:fast"); - -} -if ($filestatus <= $FILESTATUSTRANSCODEAAC){ - # AAC変換 - unlink("${filenamebody}.aac"); - &changefilestatus($pid,$FILESTATUSTRANSCODEAAC); - if (-e "$toolpath/perl/tool/neroAacEnc"){ - if (-e "$filenamebody.wav"){ - &writelog("ipodtranscode neroAacEnc $filenamebody.wav"); - system ("$toolpath/perl/tool/neroAacEnc -br 128000 -if $filenamebody.wav -of $filenamebody.aac"); - }else{ - &writelog("ipodtranscode ERR Not Found $filenamebody.wav"); - } - }else{ - #print "DEBUG $toolpath/perl/tool/neroAacEnc\n\n"; - &writelog("ipodtranscode faac $filenamebody.wav"); - system ("faac -b 128 -o $filenamebody.aac $filenamebody.wav "); - } - -} -if ($filestatus <= $FILESTATUSTRANSCODEMP4BOX){ - -unlink("${filenamebody}.base.mp4"); - -#デジタルラジオなら -if ($inputmpeg2 =~ /aac$/i){ - if (-e "$toolpath/perl/tool/MP4Box"){ - &writelog("ipodtranscode MP4Box $filenamebody"); - system ("cd $recfolderpath ;$toolpath/perl/tool/MP4Box -add $filenamebody.aac -new $filenamebody.base.mp4"); - $exit_value = $? >> 8; - $signal_num = $? & 127; - $dumped_core = $? & 128; - &writelog("ipodtranscode DEBUG MP4Box -add $filenamebody.aac -new $filenamebody.base.mp4:$exit_value:$signal_num:$dumped_core"); - }else{ - &writelog("ipodtranscode WARN; Pls. install $toolpath/perl/tool/MP4Box"); - } -}else{ - # MP4ビルド - if (-e "$toolpath/perl/tool/MP4Box"){ - &changefilestatus($pid,$FILESTATUSTRANSCODEMP4BOX); - &writelog("ipodtranscode MP4Box $filenamebody"); - system ("cd $recfolderpath ;$toolpath/perl/tool/MP4Box -fps 29.97 -add $filenamebody.264 -new $filenamebody.base.mp4"); - $exit_value = $? >> 8; - $signal_num = $? & 127; - $dumped_core = $? & 128; - &writelog("ipodtranscode DEBUG MP4Box -fps 29.97 -add $filenamebody.264 -new $filenamebody.base.mp4:$exit_value:$signal_num:$dumped_core"); - if (-e "$filenamebody.base.mp4"){ - system ("cd $recfolderpath ;$toolpath/perl/tool/MP4Box -add $filenamebody.aac $filenamebody.base.mp4"); - $exit_value = $? >> 8; - $signal_num = $? & 127; - $dumped_core = $? & 128; - &writelog("ipodtranscode DEBUG MP4Box -add $filenamebody.aac:$exit_value:$signal_num:$dumped_core"); - }else{ - $filelist = `ls -lhtr $recfolderpath/${filenamebody}*`; - $debugenv = `env`; - &writelog("ipodtranscode ERR File not exist.$debugenv.$filelist ;$filenamebody.base.mp4;$filelist;cd $recfolderpath ;$toolpath/perl/tool/MP4Box -fps 29.97 -add $filenamebody.264 -new $filenamebody.base.mp4"); - } - }else{ - &writelog("ipodtranscode WARN; Pls. install $toolpath/perl/tool/MP4Box"); - } -unlink("$filenamebody.aac"); -}#endif #デジタルラジオなら - -#} - -#if ($filestatus <= $FILESTATUSTRANSCODEATOM){ - if (-e "$toolpath/perl/tool/MP4Box"){ - # iPodヘッダ付加 -# &changefilestatus($pid,$FILESTATUSTRANSCODEATOM); - &writelog("ipodtranscode ATOM $filenamebody"); - #system ("/usr/local/bin/ffmpeg -y -i $filenamebody.base.mp4 -vcodec copy -acodec copy -f ipod ${mp4outdir}MAQ${mp4filenamestring}.MP4"); -# system ("cd $recfolderpath ; MP4Box -ipod $filenamebody.base.mp4"); - system ("cd $recfolderpath ; $toolpath/perl/tool/MP4Box -ipod $filenamebody.base.mp4"); - $exit_value = $? >> 8; - $signal_num = $? & 127; - $dumped_core = $? & 128; - &writelog("ipodtranscode DEBUG MP4Box -ipod $filenamebody.base.mp4:$exit_value:$signal_num:$dumped_core"); - if (-e "$filenamebody.base.mp4"){ - unlink("${mp4outdir}MAQ${mp4filenamestring}.MP4"); - system("mv $filenamebody.base.mp4 ${mp4outdir}MAQ${mp4filenamestring}.MP4"); - &writelog("ipodtranscode mv $filenamebody.base.mp4 ${mp4outdir}MAQ${mp4filenamestring}.MP4"); - }else{ - &writelog("ipodtranscode ERR $filenamebody.base.mp4 Not found."); - } - # ipodtranscode mv /home/foltia/php/tv/1329-21-20080829-0017.base.mp4 /home/foltia/php/tv/1329.localized/mp4/MAQ-/home/foltia/php/tv/1329-21-20080829-0017.MP4 - }else{ - &writelog("ipodtranscode WARN; Pls. install $toolpath/perl/tool/MP4Box"); - } -} -if ($filestatus <= $FILESTATUSTRANSCODECOMPLETE){ - if (-e "${mp4outdir}MAQ${mp4filenamestring}.MP4"){ - # 中間ファイル消す - &changefilestatus($pid,$FILESTATUSTRANSCODECOMPLETE); - &updatemp4file(); - }else{ - &writelog("ipodtranscode ERR ; Fail.Giving up! MAQ${mp4filenamestring}.MP4"); - &changefilestatus($pid,999); - } - unlink("${filenamebody}_HD.m2t"); -# ConfigによってTSファイルは常にsplitした状態にするかどうか選択 -# B25失敗したときにここが走るとファイルぶっ壊れるので検証を入れる -# -# if (-e "${filenamebody}_tss.m2t"){ -# unlink("${filenamebody}.m2t"); -# unless (rename "${filenamebody}_tss.m2t", "${filenamebody}.m2t") { -# &writelog("ipodtranscode WARNING RENAME FAILED ${filenamebody}_tss.m2t ${filenamebody}.m2t"); -# }else{ -# -# } -# } - unlink("${filenamebody}_tss.m2t"); - unlink("$filenamebody.264"); - unlink("$filenamebody.wav"); - unlink("$filenamebody.base.mp4"); - -} - -}else{ #デジタルかアナログか - #print "MPEG2\n"; - # アスペクト比 - if ($aspect == 16){ - $cropopt = " -croptop 70 -cropbottom 60 -cropleft 8 -cropright 14 -aspect 16:9 "; - }else{ - $cropopt = " -croptop 8 -cropbottom 8 -cropleft 8 -cropright 14 "; - } -# クオリティごとに -if (($trconqty eq "")||($trconqty == 1)){ -#$encodeoption = "-y -i $inputmpeg2 -vcodec xvid $cropopt -s 320x240 -b 300 -bt 128 -r 14.985 -bufsize 192 -maxrate 512 -minrate 0 -deinterlace -acodec aac -ab 128 -ar 24000 -ac 2 $movietitle ${mp4outdir}M4V${mp4filenamestring}.MP4"; -$mp4file = "${mp4outdir}M4V${mp4filenamestring}.MP4"; -$encodeoption = "-y -i $inputmpeg2 vcodec libxvid $cropopt -s 320x240 -b 300 -bt 128 -r 14.985 -deinterlace -acodec libfaac -f ipod ${mp4outdir}M4V${mp4filenamestring}.MP4"; -#time ffmpeg -y -i /home/foltia/php/tv/trcntest/nanoha-As-op.mpg -vcodec libxvid -croptop 8 -cropbottom 8 -cropleft 8 -cropright 14 -s 320x240 -b 300 -bt 128 -r 14.985 -deinterlace -acodec libfaac -f ipod M4V-Nanoha-As-OP.MP4 -# 32sec -# 2.1MB -}elsif($trconqty == 2){ -#$encodeoption = "-y -i $inputmpeg2 -target ipod -profile 51 -level 30 $cropopt -s 320x240 -b 300 -r 24 -acodec aac -ar 32000 -ac 2 $movietitle ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$mp4file = "${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$encodeoption = "-y -i $inputmpeg2 -vcodec libx264 -croptop 8 $cropopt -s 320x240 -b 300 -bt 128 -r 24 -deinterlace -acodec libfaac -f ipod ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -#time ffmpeg -y -i /home/foltia/php/tv/trcntest/nanoha-As-op.mpg -vcodec libx264 -croptop 8 -cropbottom 8 -cropleft 8 -cropright 14 -s 320x240 -b 300 -bt 128 -r 24 -deinterlace -acodec libfaac -f ipod MAQ-Nanoha-As-OP.MP4 -# 2min22sec -# 6.4MB -}elsif($trconqty == 3){ -#$encodeoption = "-y -i $inputmpeg2 -target ipod -profile 51 -level 30 $cropopt -acodec aac -ab 96 -vcodec h264 -maxrate 700 -minrate 0 -deinterlace -b 300 -ar 32000 -mbd 2 -coder 1 -cmp 2 -subcmp 2 -s 320x240 -r 30000/1001 -flags loop -trellis 2 -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 $movietitle ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$mp4file = "${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$encodeoption = "-y -i $inputmpeg2 -vcodec libx264 $cropopt -s 320x240 -b 380 -bt 128 -r 29.97 -deinterlace -acodec libfaac -f ipod ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -#time ffmpeg -y -i /home/foltia/php/tv/trcntest/nanoha-As-op.mpg -vcodec libx264 -croptop 8 -cropbottom 8 -cropleft 8 -cropright 14 -s 320x240 -b 380 -bt 128 -r 29.97 -deinterlace -acodec libfaac -f ipod MAQ-Nanoha-As-OP.MP4 -# 2m53.912s -# 7MB -}elsif($trconqty == 4){ -#$encodeoption = "-y -i $inputmpeg2 -target ipod -profile 51 -level 30 $cropopt -s 480x360 -b 400 -r 24 -acodec aac -ar 32000 -ac 2 $movietitle ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$mp4file = "${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$encodeoption = "-y -i $inputmpeg2 -vcodec libx264 $cropopt -s 640x480 -b 500 -maxrate 700 -bt 128 -r 29.97 -deinterlace -acodec libfaac -f ipod ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -#time ffmpeg -y -i /home/foltia/php/tv/trcntest/nanoha-As-op.mpg -vcodec libx264 -croptop 8 -cropbottom 8 -cropleft 8 -cropright 14 -s 640x480 -b 500 -maxrate 700 -bt 128 -r 29.97 -deinterlace -acodec libfaac -f ipod MAQ-Nanoha-As-OP.MP4 -# 11m0.294s -# 20MB -}elsif($trconqty == 5){ -#$encodeoption = "-y -i $inputmpeg2 -target ipod -profile 51 -level 30 $cropopt -acodec aac -ab 96 -vcodec h264 -maxrate 700 -minrate 0 -deinterlace -b 400 -ar 32000 -mbd 2 -coder 1 -cmp 2 -subcmp 2 -s 480x360 -r 30000/1001 -flags loop -trellis 2 -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 $movietitle ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$mp4file = "${mp4outdir}MAQ${mp4filenamestring}.MP4"; -$encodeoption = "-y -i $inputmpeg2 -vcodec libx264 -croptop 8 $cropopt -s 640x480 -b 500 -maxrate 700 -bt 128 -r 29.97 -deinterlace -flags loop -trellis 2 -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -acodec libfaac -f ipod ${mp4outdir}MAQ${mp4filenamestring}.MP4"; -#time ffmpeg -y -i /home/foltia/php/tv/trcntest/nanoha-As-op.mpg -vcodec libx264 -croptop 8 -cropbottom 8 -cropleft 8 -cropright 14 -s 640x480 -b 500 -maxrate 700 -bt 128 -r 29.97 -deinterlace -flags loop -trellis 2 -partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -acodec libfaac -f ipod MAQ-Nanoha-As-OP.MP4 -# 14m14.033s -# 18MB -} - -$encodeoptionlog = $encodeoption; -Jcode::convert(\$encodeoptionlog,'euc'); - -&writelog("ipodtranscode START QTY=$trconqty $encodeoptionlog"); -#print "ffmpeg $encodeoptionlog \n"; -&changefilestatus($pid,$FILESTATUSTRANSCODEFFMPEG); -system ("ffmpeg $encodeoption "); -&writelog("ipodtranscode FFEND $inputmpeg2"); -&changefilestatus($pid,$FILESTATUSTRANSCODECOMPLETE); -#もう要らなくなった #2008/11/14 -#&writelog("ipodtranscode mp4psp -p $mp4file $movietitleeuc"); -#system("/usr/local/bin/mp4psp -p $mp4file '$movietitleeuc' "); -#&writelog("ipodtranscode mp4psp COMPLETE $mp4file "); - -&updatemp4file(); -}#endif #デジタルかアナログか - -$counttranscodefiles = &counttranscodefiles(); -############################ -#一回で終らせるように -#exit; - - -}else{#ファイルがなければ -&writelog("ipodtranscode NO $inputmpeg2 file.Skip."); -}#end if - -}# end while -#残りファイルがゼロなら -&writelog("ipodtranscode ALL COMPLETE"); -exit; - - -#----------------------------------------------------------------------- -sub mp4filenamestringbuild(){ -#ファイル名決定 -#1329-19-20080814-2337.m2t -my @mpegfilename = split(/\./,$dbparam[2]) ; -my $pspfilname = "-".$mpegfilename[0] ; -return("$pspfilname"); -}#end sub mp4filenamestringbuild - - -sub makethumbnail(){ -#サムネール -my $outputfilename = $inputmpeg2 ;#フルパス -my $thmfilename = "MAQ${mp4filenamestring}.THM"; -&writelog("ipodtranscode DEBUG thmfilename $thmfilename"); - -#system ("mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -sstep 1 -frames 3 -v 3 $outputfilename"); -# -#&writelog("ipodtranscode DEBUG mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -sstep 1 -frames 3 -v 3 $outputfilename"); -if($outputfilename =~ /.m2t$/){ -#ハイビジョンTS -system ("mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -vf framestep=300step,scale=160:90,expand=160:120 -frames 1 $outputfilename"); -&writelog("ipodtranscode DEBUG mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -vf framestep=300step,scale=160:90,expand=160:120 -frames 1 $outputfilename"); -}else{ -#アナログ -system ("mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -vf framestep=300step,scale=165:126,crop=160:120 -frames 1 $outputfilename"); -&writelog("ipodtranscode DEBUG mplayer -ss 00:01:20 -vo jpeg:outdir=$pspdirname -ao null -vf framestep=300step,scale=165:126,crop=160:120 -frames 1 $outputfilename"); -} -#if (-e "$pspdirname/$thmfilename"){ -# $timestamp = strftime("%Y%m%d-%H%M%S", localtime); -#chomp $timestamp; -# system("convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/$thmfilename".$timestamp.".THM"); -#}else{ -# system("convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/$thmfilename"); -#} -#&writelog("ipodtranscode DEBUG convert -crop 160x120+1+3 -resize 165x126\! $pspdirname/00000002.jpg $pspdirname/$thmfilename"); - -#system("rm -rf $pspdirname/0000000*.jpg "); -#&writelog("ipodtranscode DEBUG rm -rf $pspdirname/0000000*.jpg"); -system("mv $pspdirname/00000001.jpg $pspdirname/$thmfilename"); - -}#endsub makethumbnail - -sub updatemp4file(){ -my $mp4filename = "MAQ${mp4filenamestring}.MP4"; - -if (-e "${mp4outdir}MAQ${mp4filenamestring}.MP4"){ -# MP4ファイル名をPIDレコードに書き込み - $sth = $dbh->prepare($stmt{'ipodtranscode.updatemp4file.1'}); - $sth->execute($mp4filename, $pid); - &writelog("ipodtranscode UPDATEsubtitleDB $stmt{'ipodtranscode.updatemp4file.1'}"); - -# MP4ファイル名をfoltia_mp4files挿入 - $sth = $dbh->prepare($stmt{'ipodtranscode.updatemp4file.2'}); - $sth->execute($tid, $mp4filename); - &writelog("ipodtranscode UPDATEmp4DB $stmt{'ipodtranscode.updatemp4file.2'}"); - -&changefilestatus($pid,$FILESTATUSALLCOMPLETE); -}else{ -&writelog("ipodtranscode ERR MP4 NOT EXIST $pid/$mp4filename"); -} - - -}#updatemp4file - -sub counttranscodefiles(){ - $sth = $dbh->prepare($stmt{'ipodtranscode.counttranscodefiles.1'}); - $sth->execute($FILESTATUSRECEND, $FILESTATUSTRANSCODECOMPLETE); -my @titlecount= $sth->fetchrow_array; - -return ($titlecount[0]); - - -}#end sub counttranscodefiles - - -sub validationsplitfile{ -my $inputmpeg2 = $_[0]; -my $trcnmpegfile = $_[1]; - - #Split結果確認 - my $filesizeoriginal = -s $inputmpeg2 ; - my $filesizesplit = -s $trcnmpegfile; - my $validation = 0; - if ($filesizesplit > 0){ - $validation = $filesizeoriginal / $filesizesplit ; - if ($validation > 2 ){ - #print "Fail split may be fail.\n"; - &writelog("ipodtranscode ERR File split may be fail: $filesizeoriginal:$filesizesplit"); - $trcnmpegfile = $inputmpeg2 ; - unlink("${filenamebody}_tss.m2t"); - unlink("${filenamebody}_HD.m2tt"); - return ($trcnmpegfile); - }else{ - #print "Fail split may be good.\n"; - return ($trcnmpegfile); - } - }else{ - #Fail - &writelog("ipodtranscode ERR File split may be fail: $filesizeoriginal:$filesizesplit"); - $trcnmpegfile = $inputmpeg2 ; - unlink("${filenamebody}_tss.m2t"); - unlink("${filenamebody}_HD.m2tt"); - return ($trcnmpegfile); - } -}#end sub validationsplitfile - Index: trunk/install/perl/record-v4l2.pl =================================================================== --- trunk/install/perl/record-v4l2.pl (リビジョン 83) +++ (リビジョン ) @@ -1,1617 +1,0 @@ -#!/usr/bin/perl -# record-v4l2.pl created by James A. Pattie 04/10/2003 -# Copyright 2003-2004 -# Purpose: to record from the specified channel for the specified amount -# of time to the video OutputDirectory under the channel-start time name as video.mpg. - -# -# You can always get the latest version of this script at -# http://www.pcxperience.org/ -# - -# 20071016 Patched by DCC-JPL Japan / foltia project / http://www.dcc-jpl.com/soft/foltia/ - -# 20030425 - 1.4 - Added devfs support based upon patch submitted by -# Jonathan Kolb -# 20030426 - 1.5 - Imported the ptune.pl functionality -# 20030426 - 1.6 - moved -F -> -L, -F now lets you specify the frequency to tune to. -# 20030427 - 1.7 - renamed to record_ivtv.pl per Kevin's request. Added -R option. -# 20030430 - 1.8 - fixing some comparisons that needed to be strings, etc. -# 20030504 - 1.9 - Migrating to Video::ivtv for video resolution support. -# 20030505 - 1.10- Replaced open w/ sysopen but it doesn't make a difference. -# Starting to replace the Standard code w/ Video::ivtv methods. -# Added the version numbers that I require to the use statements. -# 20030507 - 1.11- Migrated to using get/setFrequency from Video::ivtv 0.03. -# 20030510 - 1.12- Migrated to using get/setInput from Video::ivtv 0.04. Moved to using -# the exported method names rather than Video::ivtv::method(). -# Converted to using enumerateStandard(). -# Fixed the condition where switching Video Standards will most likely -# not get the correct channel and so would switch back with channel = 0 -# which is invalid. In this case I store the previous frequency, do the -# channel change but signal to restore the previous frequency on cleanup. -# Converted to using enumerateInput(). -# 20030512 - 1.13- Added initial support for setting the bitrate/bitrate_peak values. -# 20030513 - 1.14- Tweaked the bitrate values to be closer to real DVD bitrates. -# Added support for the .ivtvrc config file and User Profiles. -# 20030516 - 1.15- Updated to the OO interface that Video::ivtv 0.06 now requires. -# Cleaned up a lot of the global variables into a settings hash. -# Made the -S command add any config items you specified on the command line -# that were not in the Profile being updated. This way you can add new items. -# Made the config file work from a mapping hash so that we can easily add/remove -# config items in the future. -# 20030518 - 1.16- Fixed a Frequency bug that happened when changing Video Standards and the -# Frequency came from a user specified Profile. -# 20030519 - 1.17- Adding the rest of the Codec related options to the config file / defaults. -# Switched to using Getopt::Long. You can specify all config file options at -# least by a --long version and still by the original -X command option. -# Cleaned up the option parsing code to take advantage of the mappings hash. -# 20030520 - 1.18- Fixing the handling of the Profile command line option. -# 20030524 - 1.19- Cleaned up the output for -L/--list-freqtable. Changed --list -> --list-freqtable. -# Added support to detect the v4l2 driver in use and disable the ivtv "enhancements" -# if driver != "ivtv". -# Renamed to record-v4l2.pl to reflect the ability of this program to record from any -# v4l2 device but with special support for the ivtv driver. -# 20030524 - 1.20- Improving the Ctrl-C handling (cleanup before dying). It may take a second or two -# before the program exits, but it should exit after resetting anything it changed, unless -# you had specified not to reset the card. -# Allow layering of profiles by calling -P/--profile multiple times. Each profile will -# be layered over the last. You will not be able to create/update a profile if you -# specify more than one though. -# Fixed a bug that would cause a parameter from the profile to be set n times, where n was -# the number of characters in the mapping string that consisted of the single letter | and -# the long command option name. Ex: Channel has 'c|channel' so the Channel value was being -# set 9 times instead of just the first time if it was in the profile. -# 20030525 - 1.21- Fixed devfsd detection code as it was overriding what came from the config file. -# Adding --no-record option so that we can start to implement the replacement functionality for -# ptune.pl (ie. Set all values and then exit, do not reset the card and do not capture) -# 20030607 - 1.22- Adding --directory-format and --date-format options so that the user can specify the -# naming convention to use when specifying the directory the output file should be put in. -# Tweaked some of the defaults. -# Create the config file if it doesn't exist, regardless of the --save flag being specified. -# Added method error() to output an error condition that doesn't warrant the whole usage and -# converted all relevant usage() calls to error() calls. -# Added option --debug to dynamically on the fly enable debug output. -# 20030609 - 1.23- Added option --list-channels to display the currently selected frequency tables contents. -# Changed the default output directory to '.'. -# Moved $debug -> $settings{Debug} so it can be stored in the config file. This allows you to -# turn debugging on for only certain profiles, etc. -# Restructured some of the validity tests to only happen as long as we are recording since they -# do not need to be validated when we are not recording. Mainly to do with the output stuff. -# 20030610 - 1.24- Moved the tunerNum variable into the config file: TunerNum -# Added --tuner-num option to dynamically set it. -# 20030614 - 1.25- I now require Video::ivtv 0.09 to make sure everyone is using the version that fixes the known -# reported segfault issues. -# Added freqtable "custom" support so that people using the new feature in ptune-ui.pl and have -# set their default frequency table to be "custom" will just work when they specify channel X, etc. -# I'm now sorting the command line input since otherwise I can't guarantee the order options get -# processed in, but even that is wrong. I need to use Tie::IxHash, but that isn't standard. -# 20030626 - 1.26- Updated to cover the audio -> audio_bitmask changes that Video::ivtv 0.11 implemented to cover -# the ivtv_ioctl_codec structure changes. -# Implemented config file versioning so that I know when the Audio entry needs to be updated in case it -# comes back in a future version of the ivtv_ioctl_codec structure. -# 20030628 - 1.27- Adding --list-inputs and --list-standards to display the available inputs and video standards. -# 20030713 - 1.28- Added code to make sure the codec properties are proper when switching standard to PAL/SECAM. -# Added config options SetMSPMatrix, MSPInput, MSPOutput, MSPSleep to allow the user to specify if they -# want the msp matrix updated any time the Video Standard is changed and to specify what they want programmed. -# Bumping the config file version to 2 to account for the new options. -# 20030715 - 1.29- Adding the missing msp matrix reset code in the reset section. -# Adding codec checks to make sure that they are right for NTSC. -# Made it legal to specify the channel by itself without -c/--channel. -# 20030822 - 1.30- Adding the missing codec value BitrateMode -# 20030927 - 1.31- Adding support to export the settings used as a shell or perl snippet for inclusion -# by scripts working with the recorded video files. -# Changing the default value of StreamType to 14 since that is near DVD quality. -# 20040306 - 1.32- Creating the parent directory if it doesn't exist. -# Making sure to update the InputName if the config specified a number so that input switching works 100%. -# Command line arguments now take precedence over Profile values, should have been this way always. :( -# 20040613 - 1.33- Removing the MSPMatrix related options and code. -# Adding a check for the 0.1.10 driver and not using the GOP_END ioctl if it is not that version. -# Brought it upto speed in regards to the 0.2.00rc1g driver - all known issues are now fixed. -# Added code to determine the version of the ivtv driver being used (0.1.10, 0.2.0, etc.) and -# output it in the video.settings file so we know what driver the capture was done with. - - -use strict; -use Getopt::Long qw(:config no_ignore_case bundling); -use Fcntl; -use Video::Frequencies 0.03; -use Video::ivtv 0.13; -use Config::IniFiles; - -my $version="1.33"; -my $cfgVersion = "3"; -my $cfgVersionStr = "_configVersion_"; # hopefully unique [defaults] value to let me know what version the config file is. -my $ivtvVersion = 0; # used to store the detected version of the driver. Needed for the CaptureLastGOP feature. - -my @capabilities = (); # The cards capabilities - -my %settings = ( - Channel => 4, # default to the ivtv default channel - RecordDuration => 3595, # default to 59 minutes 55 seconds (in seconds) - This lets 2 back to back cron jobs work! - InputNum => 0, # TV-Tuner 1 - InputName => "Tuner 1", - OutputDirectory => ".", - VideoDevice => "/dev/video0", - VideoWidth => "720", # 720x480-fullscreen NTSC - VideoHeight => "480", - VideoStandard => "NTSC-M", # L135 v060406.pl MMM "NTSC", # NTSC, PAL or SECAM - VideoType => "mpeg", # mpeg, yuv - BitrateMode => 0, # 0 = VBR, 1 = CBR - Bitrate => "6500000", - PeakBitrate => "8000000", # peak bitrate - Aspect => 2, - AudioBitmask => 0x00e9, - BFrames => 3, - DNRMode => 0, - DNRSpatial => 0, - DNRTemporal => 0, - DNRType => 0, - Framerate => 0, - FramesPerGOP => 15, - GOPClosure => 1, - Pulldown => 0, - StreamType => 14, # 0 = PS, 1 = TS, 2 = MPEG1, 3 = PES_AV, 5 = PES_V, 7 = PES_A, 10 = DVD, 11 = VCD, 12 = SVCD, 13 = DVD-Special 1, 14 = DVD-Special 2 - OutputFileName => "video.mpg", - FrequencyTable => "ntsc-cable", # default to NTSC_CABLE mapping. - Frequency => "", # user specified frequency. - ResetCardSettings => 1, - ConfigFileName => "$ENV{HOME}/.ivtvrc", - UpdateConfigFile => 0, - UseConfigFile => 0, - UsingIvtvDriver => 1, # default to being able to use the ivtv "enhancements". - DontRecord => 0, # default to always recording data. - DirectoryFormatString => "%I-%c-%d", # format string used to define the sub directory under OutputDirectory - DateTimeFormatString => "+%Y%m%d-%H%M", # format string used to represent the date/time if the user wants it in their DirectoryFormatString - # define the Codec related min/max values - minBitrate => 1, - maxBitrate => 14500000, - minPeakBitrate => 1150, - maxPeakBitrate => 16000000, - # output settings file settings - OutputSettings => 1, # bool 0 or 1 - OutputSettingsName => "video.settings", - OutputSettingsType => "shell", # shell or perl - # other settings - CaptureLastGOP => 1, # default to trying to Capture the Last GOP of the encoder stream. - Debug => 0, - TunerNum => 1, - v4l2DriverVersion => 0, - v4l2DriverVersionStr => "", - v4l2Driver => "", -); - -my $result=""; -my @profileNames=(); # list of user defined sections to work with in the config file. -my %profileOverloads = (); # hash of entries the Profiles overloaded so InputName <-> InputNum works properly. -my %configIni; # config hash we tie to for Config::IniFiles. -my $ivtvObj = Video::ivtv->new(); - -# map the Settings/Config file parameter to the command line variable that specifies it. -my %mappings = ( - "Channel" => "c|channel", - "RecordDuration" => "t|duration", - "InputNum" => "i|inputnum", - "InputName" => "I|inputname", - "OutputDirectory" => "D|directory", - "VideoDevice" => "d|input", - "VideoWidth" => "W|width", - "VideoHeight" => "H|height", - "VideoStandard" => "s|standard", - "VideoType" => "T|type", - "BitrateMode" => "bitrate-mode", - "Bitrate" => "b|bitrate", - "PeakBitrate" => "B|peakbitrate", - "Aspect" => "aspect", - "AudioBitmask" => "audio-bitmask", - "BFrames" => "bframes", - "DNRMode" => "dnrmode", - "DNRSpatial" => "dnrspatial", - "DNRTemporal" => "dnrtemporal", - "DNRType" => "dnrtype", - "Framerate" => "framerate", - "FramesPerGOP" => "framespergop", - "GOPClosure" => "gopclosure", - "Pulldown" => "pulldown", - "StreamType" => "streamtype", - "OutputFileName" => "o|output", - "FrequencyTable" => "f|freqtable", - "Frequency" => "F|frequency", - "ResetCardSettings" => "R|noreset", - "DirectoryFormatString" => "directory-format", - "DateTimeFormatString" => "date-format", - "Debug" => "debug", - "TunerNum" => "tuner-num", - "OutputSettings" => "output-settings", - "OutputSettingsName" => "output-settings-name", - "OutputSettingsType" => "output-settings-type", - "CaptureLastGOP" => "capture-last-gop", - ); - -my %codecMappings = ( - "Aspect" => "aspect", - "AudioBitmask" => "audio_bitmask", - "BFrames" => "bframes", - "BitrateMode" => "bitrate_mode", - "Bitrate" => "bitrate", - "PeakBitrate" => "bitrate_peak", - "DNRMode" => "dnr_mode", - "DNRSpatial" => "dnr_spatial", - "DNRTemporal" => "dnr_temporal", - "DNRType" => "dnr_type", - "Framerate" => "framerate", - "FramesPerGOP" => "framespergop", - "GOPClosure" => "gop_closure", - "Pulldown" => "pulldown", - "StreamType" => "stream_type", - ); - -# check for devfs support -if ( -e "/dev/.devfsd" ) -{ - $settings{VideoDevice} = "/dev/v4l/video0"; -} - -# check for the config file -if (-f $settings{ConfigFileName}) -{ - $settings{UseConfigFile} = 1; - - # tie to it. - tie %configIni, 'Config::IniFiles', (-file => $settings{ConfigFileName}) or die "Error: Opening config file '$settings{ConfigFileName}' failed! $!\n"; - - my $profile = "defaults"; - if (exists $configIni{$profile}) - { - my $saveFile = 0; - # check version of the config file. - if (!exists $configIni{$profile}{$cfgVersionStr}) - { - print "Updating config file to version 1...\n"; - - # first version config file! Update the Audio -> AudioBitmask entries. - $configIni{$profile}{$cfgVersionStr} = 1; - - # find all entries that have Audio and move to AudioBitmask. - foreach my $p (keys %configIni) - { - if (exists $configIni{$p}{Audio}) - { - $configIni{$p}{AudioBitmask} = $configIni{$p}{Audio}; - delete $configIni{$p}{Audio}; - } - } - - $saveFile = 1; # signal we need to save the config changes. - } - if ($configIni{$profile}{$cfgVersionStr} != $cfgVersion) - { - # we need to upgrade - if ($configIni{$profile}{$cfgVersionStr} == 1) - { - print "Updating config file to version 2...\n"; - # add the MSP Matrix related options. - $configIni{$profile}{SetMSPMatrix} = $settings{SetMSPMatrix}; - $configIni{$profile}{MSPInput} = $settings{MSPInput}; - $configIni{$profile}{MSPOutput} = $settings{MSPOutput}; - $configIni{$profile}{MSPSleep} = $settings{MSPSleep}; - $configIni{$profile}{$cfgVersionStr} = 2; - $saveFile = 1; - } - if ($configIni{$profile}{$cfgVersionStr} == 2) - { - print "Updating config file to version 3...\n"; - # remove the MSP Matrix related options from all profiles. - foreach my $p (keys %configIni) - { - foreach my $k (qw(SetMSPMatrix MSPInput MSPOutput MSPSleep)) - { - if (exists $configIni{$p}{$k}) - { - delete $configIni{$p}{$k}; - } - } - } - $configIni{$profile}{CaptureLastGOP} = 1; - $configIni{$profile}{$cfgVersionStr} = 3; - $saveFile = 1; - } - } - - if ($saveFile) - { - # now save the updated config file before we continue. - tied(%configIni)->RewriteConfig or die "Error: Writing config file '$settings{ConfigFileName}' failed! $!\n"; - } - - # update the defaults stored. - foreach my $arg (keys %mappings) - { - if (exists $configIni{$profile}{$arg}) - { - $settings{$arg} = $configIni{$profile}{$arg}; - #print "settings{$arg} = '" . $settings{$arg} . "'\n"; - } - } - } - else - { - print "Warning: config file '$settings{ConfigFileName}' exists but does not have the\n[$profile] section! Use -S to create it without specifying -P.\n\n"; - } -} -else # create the config file -{ - print "Auto Creating config file $settings{ConfigFileName}...\n"; - my $profile = "defaults"; - - # we have to create the config file and tie to it. - tie %configIni, 'Config::IniFiles', () or die "Error: Initializing config file '$settings{ConfigFileName}' failed! $!\n"; - - # now set the name to work with. - tied(%configIni)->SetFileName($settings{ConfigFileName}) or die "Error: Setting config file to '$settings{ConfigFileName}' failed! $!\n"; - - $configIni{$profile} = {}; # make sure the section exists. - - foreach my $arg (keys %mappings) - { - $configIni{$profile}{$arg} = $settings{$arg}; - print "configIni{$profile}{$arg} = '" . $settings{$arg} . "'\n" if $settings{Debug}; - } - - # set the config file version - $configIni{$profile}{$cfgVersionStr} = $cfgVersion; - - # write the config file out. - tied(%configIni)->RewriteConfig or die "Error: Writing config file '$settings{ConfigFileName}' failed! $!\n"; -} - -# build up the "custom" frequency table -my %customMap = (); -foreach my $profileName (keys %configIni) -{ - next if $profileName =~ /^(defaults)$/; - - if (exists $configIni{$profileName}{Frequency}) - { - $customMap{$profileName} = $configIni{$profileName}{Frequency}; - } -} -$CHANLIST{custom} = \%customMap; - -# enumerations -my @standards; -my %name2std; -my @inputs; -my %name2input; -my @codecInfo; # stores the Codec Info -my @newCodecInfo; # the version we mess with. -# Current settings (Input, Channel, Standard) -my $curinput; -my $curinputName; -my $std; -my $curstd = "???"; -my $curStandard = 0; # numeric representation. -my $curChannel = 0; -my $curFrequency = 0; - -my $tuner; -my $settingsFH; # File Handle for output settings. -my $err; -my $v4l2input; - -my $tmpDirectoryStr = formatDirectoryString(); -my $versionStr = "record-v4l2.pl $version for use with http://ivtv.sf.net/"; -my $usageStr = <<"END_OF_USAGE"; -$versionStr - -Usage: record-v4l2.pl [--channel CHANNEL] [--duration TIME] - [--directory DIRECTORY] [--output OUTPUT] - [--directory-format FORMAT] [--date-format FORMAT] - [--input VIDEO_DEV][--width WIDTH --height HEIGHT] - [--standard STANDARD] [--type TYPE] - [--inputnum INPUT#] [--inputname INPUT NAME] - [--freqtable FREQENCY MAP] [--frequency FREQUENCY] - [--bitrate-mode MODE] - [--bitrate BITRATE] [--peakbitrate PEAK_BITRATE] - [--profile PROFILE] [--list-freqtable] [--list-channels] - [--no-record] [--noreset] [--save] [--help] [--version] - [--aspect ASPECT] [--audio-bitmask AUDIO-BITMASK] [--bframes BFRAMES] - [--dnrmode DNRMODE] [--dnrspatial DNRSPATIAL] - [--dnrtemporal DNRTEMPORAL] [--dnrtype DNRTYPE] - [--framerate FRAMERATE] [--framespergop FRAMESPERGOP] - [--gopclosure GOPCLOSURE] [--capture-last-gop GOP_END] - [--pulldown PULLDOWN] [--streamtype STREAMTYPE] [--debug] - [--tuner-num TUNERNUM] [--output-settings BOOL] - [--output-settings-name FNAME] [--output-settings-type TYPE] - [--list-inputs] [--list-standards] [CHANNEL] - - -c/--channel CHANNEL: channel number to switch to - NOTE: You can also specify the channel by itself. - Ex. record-v4l2.pl 73 - would change to channel 73 using the default settings - or the settings from your ~/.ivtvrc config file. - -t/--duration TIME: number of seconds to record - -D/--directory DIRECTORY: Base directory to record into - --directory-format FORMAT: format string that specifies the - sub-directory to create under the base directory that - the output file will be created in. This can be empty - to indicate no sub-directory should be created. - - Available tokens are: - %d - date formatted by --date-format - %I - input name recorded from - Any white space in the name is converted to - underscores (_). Ex. 'Tuner 0' => 'Tuner_0' - - %c - channel or "freq-#" frequency - - --date-format FORMAT: format string that specifies the - date format string to generate and substitute for - %d in the --directory-format string. - - Available tokens: see the date commands man page. - The string must start with a + (plus). - - -o/--output OUTPUT: name of file to create - -d/--input VIDEO_DEV: video device to capture from - -W/--width WIDTH: width of screen (720 for NTSC fullscreen) - -H/--height HEIGHT: height of screen (480 for NTSC fullscreen) - -s/--standard STANDARD: NTSC, PAL or SECAM - video standard to record in - -T/--type TYPE: mpeg or yuv output - -i/--inputnum INPUT#: - The index number of the input you want to use (0 -> n-1) - -I/--inputname INPUT NAME: The name of the input you want to use. - -f/--freqtable FREQUENCY MAP: Specify the frequency mapping to use. - -F/--frequency FREQUENCY: Specify the frequency to tune to. - ex. 517250 = NTSC Cable 73 (SCiFi) - --tuner-num TUNERNUM: Specify the tuner to use. - -L/--list-freqtable: - list all available frequency mappings that Video::Frequencies knows - --list-channels: lists all channels and their frequencies for the - specified frequency table being used. - --list-inputs: lists all inputs the v4l2 driver reports. - --list-standards: lists all Video Standards the v4l2 driver supports. - -R/--noreset: Do not Reset anything that was changed - (standard, channel, resolution, etc.) - --no-record: Do not create any directories, capture data or reset the card - back to original settings. This is the ptune.pl mode. - -h/--help: display this help - -v/--version: display the version of this program - --debug: turns on debug output - --output-settings BOOL: Turns on or off the creation of the settings - file that contains perl or shell variables that - represent the settings used to record the video file. - This feature is ignored if --no-record specified. - --output-settings-name FNAME: The name of the file to write the settings to. - It must end in .settings. - --output-settings-type TYPE: Either 'shell' or 'perl'. - If 'shell', then all variables output are prefixed with REC_ - and are upper cased. Ex: StreamType => REC_STREAMTYPE="14" - If 'perl', then all variables output are created in the - %settings hash. Ex: StreamType => $settings{StreamType} = "14"; - - Codec related options: - --bitrate-mode MODE: 0 = VBR, 1 = CBR - -b/--bitrate BITRATE: Specify the Bitrate to capture at in Mbps - -B/--peakbitrate PEAK_BITRATE: Specify the Peak Bitrate to capture at in Mbps - --aspect ASPECT: Specify the aspect ratio - --audio-bitmask AUDIO-BITMASK: Specify the audio bitmask value - --bframes BFRAMES: Specify the number of B frames value - --dnrmode DNRMODE: Specify the dnr_mode value - --dnrspatial DNRSPATIAL: Specify the dnr_spatial value - --dnrtemporal DNRTEMPORAL: Specify the dnr_temporal value - --dnrtype DNRTYPE: Specify the dnr_type value - --framerate FRAMERATE: Specify the framerate value. 0 = 30fps, 1 = 25fps - --framespergop FRAMESPERGOP: Specify the GOP size - --gopclosure GOPCLOSURE: Specify if you want open/closed GOP's. - --capture-last-gop GOP_END: Specify if you want the encoder stream to try and - capture the last GOP, thus generating a 100% valid mpeg2 file. - 1 = yes (default), 0 = no. - --pulldown PULLDOWN: 1 = Inverse telecine on, 0 = off - --streamtype STREAMTYPE: Specify the stream_type value - Valid Values are: - 0 - PS - 1 - TS - 2 - MPEG1 - 3 - PES_AV - 5 - PES_V - 7 - PES_A - 10 - DVD - 11 - VCD - 12 - SVCD - 13 - DVD-Special 1 - 14 - DVD-Special 2 - - Config file related options: - -P/--profile PROFILE: Override defaults and command line values with the - config entries in the section labeled [PROFILE] from the - config file $settings{ConfigFileName}. - Examples: -P NTSC-DVD, -P PAL-DVD, --profile MY-SETTINGS - - You can specify this option multiple times and each successive - profile will overlay the defaults and any previous profiles. - You will not be able to create/update a profile if you do - specify multiple profiles. - -S/--save: save the current values as the defaults in - $settings{ConfigFileName}. - If -P/--profile PROFILE is specified, then those values that exist in - the specified profile will be updated. If the profile doesn't exist, - then it will be created, but will have all possible config items - defined in it. It will be your responsibility to hand check the - config file and remove any config items you do not want set for - that profile. - Any options specified on the command line will override options - defined in the config file. - -Notes: - If you specify both -i/--inputnum and -I/--inputname then - -i/--inputnum will take precedence. - - If you specify both -c/--channel and -F/--frequency then - -F/--frequency will take precedence. - - If you use a Profile, it has the ability to override all command line - arguments, so check your Profile first if things seem to be ignored. - -Defaults: - --duration $settings{RecordDuration} --input $settings{VideoDevice} --width $settings{VideoWidth} --height $settings{VideoHeight} --standard $settings{VideoStandard} - --type $settings{VideoType} --directory $settings{OutputDirectory} --output $settings{OutputFileName} - --directory-format "$settings{DirectoryFormatString}" --date-format "$settings{DateTimeFormatString}" - --inputnum $settings{InputNum} --inputname '$settings{InputName}' --freqtable $settings{FrequencyTable} --capture-last-gop $settings{CaptureLastGOP} - --bitrate $settings{Bitrate} --peakbitrate $settings{PeakBitrate} --aspect $settings{Aspect} --audio-bitmask $settings{AudioBitmask} --bframes $settings{BFrames} - --dnrmode $settings{DNRMode} --dnrspatial $settings{DNRSpatial} --dnrtemporal $settings{DNRTemporal} --dnrtype $settings{DNRType} - --framerate $settings{Framerate} --framespergop $settings{FramesPerGOP} --gopclosure $settings{GOPClosure} --pulldown $settings{Pulldown} --streamtype $settings{StreamType} - --tuner-num $settings{TunerNum} --output-settings $settings{OutputSettings} --output-settings-name $settings{OutputSettingsName} --output-settings-type $settings{OutputSettingsType} - - config file = '$settings{ConfigFileName}' - - If Channel = $settings{Channel}, this would create: - $tmpDirectoryStr$settings{OutputFileName} - - Note: This script relies on Perl Modules: Video::Frequencies, Video::ivtv, - Config::IniFiles and Getopt::Long. -END_OF_USAGE - -# handle user input here -my %opts; -#getopts('c:t:o:hd:W:H:s:T:D:vi:I:f:F:LRb:B:P:S', \%opts); -GetOptions(\%opts, "channel|c=s", "duration|t=i", "output|o=s", "help|h", "input|d=s", "width|W=i", "height|H=i", "standard|s=s", - "type|T=s", "directory|D=s", "version|v", "inputnum|i=i", "inputname|I=s", "freqtable|f=s", "frequency|F=i", "list-freqtable|L", - "noreset|R", "bitrate|b=i", "peakbitrate|B=i", "profile|P=s@", "save|S", "aspect=i", "audio-bitmask=s", "bframes=i", "dnrmode=i", "dnrspatial=i", - "dnrtemporal=i", "dnrtype=i", "framerate=i", "framespergop=i", "gopclosure=i", "pulldown=i", "capture-last-gop=i", - "streamtype=i", "no-record", "directory-format=s", "date-format=s", "debug", "list-channels", - "tuner-num=i", "list-inputs", "list-standards", "bitrate-mode=i", "output-settings=i", "output-settings-name=s", "output-settings-type=s"); -if (scalar keys %opts == 0 && @ARGV == 0) -{ - usage(0, ""); -} -foreach my $option (sort keys %opts) -{ - my $found = 0; - foreach my $mapName (keys %mappings) - { - if ($option =~ /^($mappings{$mapName})$/) - { - $settings{$mapName} = $opts{$option}; - $found = 1; - print "$mapName = '$opts{$option}'\n" if $settings{Debug}; - } - } - if (!$found) - { - # handle the non-settings cases. - if ($option =~ /^(L|list-freqtable)$/) - { - my $errStr = "\nAvailable Frequency Mappings:\n"; - foreach my $name (sort keys %CHANLIST) - { - $errStr .= "$name\n"; - } - print "$versionStr\n$errStr"; - exit 0; - } - elsif ($option eq "list-channels") - { - my $errStr = "\nAvailable Channels for $settings{FrequencyTable}:\n"; - foreach my $name (sort { $a <=> $b } keys %{$CHANLIST{$settings{FrequencyTable}}}) - { - $errStr .= "$name\t= $CHANLIST{$settings{FrequencyTable}}->{$name}\n"; - } - print "$versionStr\n$errStr"; - exit 0; - } - elsif ($option =~ /^(no-record)$/) - { - $settings{DontRecord} = 1; - } - elsif ($option =~ /^(S|save)$/) - { - $settings{UpdateConfigFile} = 1; - } - elsif ($option =~ /^(P|profile)$/) - { - @profileNames = @{$opts{$option}}; - } - elsif ($option =~ /^(v|version)$/) - { - print "$versionStr\n"; - exit 0; - } - elsif ($option =~ /^(h|help)$/) - { - usage(0, ""); - } - elsif ($option =~ /^(list-inputs|list-standards)$/) - { - # do nothing for now since they will be handled later. - } - else - { - usage(1, "-$option is an unknown option!"); - } - } -} - -if (@profileNames) -{ - # loop over all profiles the user specified. - foreach my $profileName (@profileNames) - { - print "profile = '$profileName'\n" if $settings{Debug}; - # for now the profile can not be "defaults". - if ($profileName eq "defaults") - { - error(1, "Profile = '$profileName' is invalid!"); - } - if (exists $configIni{$profileName}) - { - # update defaults that exist in this profile as long as the entry wasn't specified on the command line. - my $profile = $profileName; - - foreach my $arg (keys %mappings) - { - # handle the long/short command option versions - my $cmdSpecified = 0; - foreach my $option (split(/\|/, $mappings{$arg})) - { - if (exists $opts{$option}) - { - $cmdSpecified = 1; - last; - } - } - #print "arg = '$arg', option = '$option'\n" if $settings{Debug}; - if (exists $configIni{$profile}{$arg} && !$cmdSpecified) - { - $profileOverloads{$arg} = $settings{$arg}; # preserve the old value. - $settings{$arg} = $configIni{$profile}{$arg}; - print "settings{$arg} = '" . $settings{$arg} . "'\n" if $settings{Debug}; - } - } - } - else - { - if ($settings{UpdateConfigFile} && @profileNames == 1) - { - print "Warning: Profile = '$profileName' will be created.\n" if ($settings{Debug}); - } - else - { - error(1, "Profile = '$profileName' does not exist! You must specify -S/--save to create it."); - } - } - } -} - -# verify input - -if (@ARGV) -{ - if (exists $opts{c} || exists $opts{channel}) - { - print "Warning: ignoring channel argument and using '$ARGV[0]' instead.\n"; - } - $settings{Channel} = $ARGV[0]; -} - -my $directoryName; -if (!$settings{DontRecord}) -{ - print "RecordDuration = $settings{RecordDuration}\n" if $settings{Debug}; - - if ($settings{VideoType} !~ /^(mpeg|yuv)$/) - { - error(1, "Video Type = '$settings{VideoType}' is invalid!"); - } - if ($settings{VideoType} eq "yuv") - { - # see if we need to change our defaults. - if (!exists $opts{o} && !exists $opts{output}) - { - $settings{OutputFileName} = "video.yuv"; - } - if (!exists $opts{d} && !exists $opts{input}) - { - if ( -e "/dev/.devfsd" ) - { - $settings{VideoDevice} = "/dev/v4l/yuv0"; - } - else - { - $settings{VideoDevice} = "/dev/yuv0"; - } - } - } - - if ( ! -d "$settings{OutputDirectory}") - { - $result = `mkdir -p $settings{OutputDirectory}`; - } - # make directory - $directoryName = formatDirectoryString(); - $result=`mkdir -p $directoryName`; -} - -# verify the output-settings options -if ($settings{OutputSettings} !~ /^[01]$/) -{ - error(1, "OutputSettings = '$settings{OutputSettings}' is invalid!"); -} -if ($settings{OutputSettings} && $settings{DontRecord}) -{ - $settings{OutputSettings} = 0; # turn off feature since we are not recording. -} -if ($settings{OutputSettings}) -{ - if ($settings{OutputSettingsName} !~ /^(.+\.settings)$/) - { - error(1, "OutputSettingsName = '$settings{OutputSettingsName}' is invalid! It must end in .settings."); - } - if ($settings{OutputSettingsType} !~ /^(shell|perl)$/) - { - error(1, "OutputSettingsType = '$settings{OutputSettingsType}' is invalid! It must be either 'shell' or 'perl'."); - } - sysopen($settingsFH, "$directoryName/$settings{OutputSettingsName}", O_CREAT | O_WRONLY) or die "Error creating file '$settings{OutputSettingsName}': $!\n"; - outputSettingSetup(); -} - -if ( ! -c "$settings{VideoDevice}") -{ - error(1, "Video Dev = '$settings{VideoDevice}' is invalid! $!"); -} - -# now that the video device has been semi validated, we can use it to lookup -# the inputs, standards, etc. and use that for validating some of the following -# pieces of user input. -sysopen($tuner, $settings{VideoDevice}, O_RDWR) or die "Error unable to open '$settings{VideoDevice}': $!"; -my $tunerFD = fileno($tuner); - -outputSetting("VideoDevice"); - -# get the current capabilities. -@capabilities = $ivtvObj->getCapabilities($tunerFD); -if (@capabilities != keys %{$ivtvObj->{capIndexes}}) -{ - error(1, "getCapabilities() failed!"); -} -# calculate the driver version info. -my $driverVersionHex = sprintf("%08x", $capabilities[$ivtvObj->{capIndexes}{version}]); -$driverVersionHex =~ /^(\d{4})(\d{2})(\d{2})$/; -my $driverVersionMajor = int($1); -my $driverVersionMinor = int($2); -my $driverVersionPatch = int($3); -my $driverVersionStr = $driverVersionMajor . "." . $driverVersionMinor . "." . $driverVersionPatch; - -$settings{v4l2DriverVersion} = $capabilities[$ivtvObj->{capIndexes}{version}]; -$settings{v4l2DriverVersionStr} = $driverVersionStr; -$settings{v4l2Driver} = $capabilities[$ivtvObj->{capIndexes}{driver}]; -outputSetting("v4l2Driver"); -outputSetting("v4l2DriverVersion"); -outputSetting("v4l2DriverVersionStr"); - -if ($settings{Debug}) -{ - print "V4l2 Capabilities: driver='$capabilities[$ivtvObj->{capIndexes}{driver}]', version='$capabilities[$ivtvObj->{capIndexes}{version}]', '$driverVersionStr'\n"; -} -if ($capabilities[$ivtvObj->{capIndexes}{driver}] ne "ivtv") -{ - $settings{UsingIvtvDriver} = 0; # we can't use the ivtv "enhancements". - print "Warning: V4l2 driver = '$capabilities[$ivtvObj->{capIndexes}{driver}]' does not support the ivtv \"enhancements\"!\n"; - print " All codec and ivtv specific options will be ignored.\n\n"; -} -elsif ($capabilities[$ivtvObj->{capIndexes}{version}] <= 265) -{ - $settings{CaptureLastGOP} = 0; # we can't use the ivtv GOP_END feature. - print "Warning: ivtv driver is not new enough to use the GOP_END feature!\n"; -} -$ivtvVersion = $capabilities[$ivtvObj->{capIndexes}{version}]; - -my $i; - -# get the current video standard -$std = $ivtvObj->getStandard($tunerFD); -if ($std > 0) -{ - printf("Standard: 0x%08x\n",$std) if ($settings{Debug}); -} -else -{ - die "Error: getStandard() failed!\n"; -} - -# get the current input -$curinput = $ivtvObj->getInput($tunerFD); -if ($curinput < 0) -{ - die "Error: getInput() failed!\n"; -} -printf("Input: 0x%08x\n",$curinput) if ($settings{Debug}); - -# flags to indicate when we should stop reading from the card. -my $done=0; -my $stopGOP=0; # indicates if we are asking for the Last GOP -my $endStream=0; # indicates if we are in the final read state. -# Standards -for ($i=0; !$done; ++$i) -{ - my($index,$std_id,$name,$frameperiod_n,$frameperiod_d,$framelines) = $ivtvObj->enumerateStandard($tunerFD, $i); - if ($index == -1) - { - $done = 1; - } - else - { - printf("%d 0x%08x %s %d/%d %d\n",$index,$std_id,$name,$frameperiod_n,$frameperiod_d,$framelines) if ($settings{Debug}); - push @standards, [($name,$std_id)]; - $name2std{$name} = $std_id; - if( (($std_id & $std) == $std)) - { - $curstd = $name; - $curStandard = $std; - } - } -} - -if (exists $opts{'list-standards'}) -{ - print "$versionStr\n"; - print "Available Video Standards:\n"; - foreach my $standard (@standards) - { - print "$standard->[0]\n"; - } - exit 0; -} - -$done=0; -# Inputs -for ($i=0; !$done; ++$i) -{ - my($index,$name,$type,$audioset,$tuner,$std,$status) = $ivtvObj->enumerateInput($tunerFD, $i); - if ($index == -1) - { - $done = 1; - } - else - { - push @inputs, $name; - $name2input{$name} = $index; - } -} -$curinputName = $inputs[$curinput]; - -if (exists $opts{'list-inputs'}) -{ - print "$versionStr\n"; - print "Available Inputs:\n"; - my $counter = 0; - foreach my $input (@inputs) - { - print "$counter: $input\n"; - $counter++; - } - exit 0; -} - -if ($settings{UsingIvtvDriver}) -{ - # get the current Codec Info - @codecInfo = $ivtvObj->getCodecInfo($tunerFD); - if (@codecInfo != keys %{$ivtvObj->{codecIndexes}}) - { - error(1, "getCodecInfo() failed!"); - } - @newCodecInfo = $ivtvObj->getCodecInfo($tunerFD); - if (@newCodecInfo != keys %{$ivtvObj->{codecIndexes}}) - { - error(1, "getCodecInfo() failed!"); - } -} - -# finish validating the user input. - -if (!$settings{DontRecord}) -{ - if ($settings{RecordDuration} !~ /^(\d+)$/) - { - error(1, "Time = '$settings{RecordDuration}' is invalid!"); - } - - outputSetting("RecordDuration"); - outputSetting("OutputDirectory"); - - # assume for now we are only generating mpeg files. -# if (($settings{VideoType} eq "mpeg" && $settings{OutputFileName} !~ /^.+\.mpg$/) || ($settings{VideoType} eq "yuv" && $settings{OutputFileName} !~ /^.+\.yuv$/)) -# { -# error(1, "Output = '$settings{OutputFileName}' is invalid!"); -# } - - outputSetting("VideoType"); - outputSetting("OutputFileName"); - - if ($settings{DateTimeFormatString} !~ /^(\+((\%.)|.)+)$/) - { - usage(1, "Date Format String = '$settings{DateTimeFormatString}' is invalid!"); - } - - outputSetting("DateTimeFormatString"); -} - -if ($settings{VideoWidth} !~ /^(\d+)$/) -{ - error(1, "Width = '$settings{VideoWidth}' is invalid!"); -} - -outputSetting("VideoWidth"); - -if ($settings{VideoHeight} !~ /^(\d+)$/) -{ - error(1, "Height = '$settings{VideoHeight}' is invalid!"); -} - -outputSetting("VideoHeight"); - -if (!exists $name2std{$settings{VideoStandard}}) -{ - my $validStandards = join(", ", keys(%name2std)); - error(1, "Video Standard = '$settings{VideoStandard}' is invalid!\nValid Standards are: $validStandards"); -} - -outputSetting("VideoStandard"); - -if (exists $opts{i} || exists $opts{inputnum} || ($settings{InputNum} != $name2input{$settings{InputName}} && exists $profileOverloads{InputNum})) -{ - if ($settings{InputNum} < 0 || $settings{InputNum} >= scalar(@inputs)) - { - error(1, "Video Input = '$settings{InputNum}' is invalid!\nValid Inputs are from 0 - " . int(scalar(@inputs) - 1)); - } - $settings{InputName} = $inputs[$settings{InputNum}]; -} - -if ((exists $opts{I} || exists $opts{inputname} || $settings{InputNum} != $name2input{$settings{InputName}}) && !(exists $opts{i} || exists $opts{inputnum})) -{ - if (!exists $name2input{$settings{InputName}}) - { - my $validInputs = join(", ", @inputs); - error(1, "Video Input Name = '$settings{InputName}' is invalid!\nValid Input Names are: $validInputs"); - } - $settings{InputNum} = $name2input{$settings{InputName}}; -} - -outputSetting("InputName"); -outputSetting("InputNum"); - -if (!exists $CHANLIST{$settings{FrequencyTable}}) -{ - error(1, "Frequency Table = '$settings{FrequencyTable}' is invalid!"); -} - -outputSetting("FrequencyTable"); - -# only validate the channel if the input is a tuner. -if ($inputs[$settings{InputNum}] =~ /Tuner/) -{ - if ($settings{TunerNum} !~ /^(\d)$/) - { - error(1, "TunerNum = '$settings{TunerNum}' is invalid!"); - } - if (exists $opts{F} || exists $opts{frequency} || $settings{Frequency}) # the user may have specified a Frequency in their config file - { - if ($settings{Frequency} !~ /^(\d+)$/) - { - error(1, "Frequency = '$settings{Frequency}' is invalid!"); - } - $settings{Channel} = "freq-$settings{Frequency}"; # make sure we output the channel part. - } - # now verify that the channel exists in the frequency table! - else - { - if (!$settings{Channel}) - { - error(1, "channel = '$settings{Channel}' is invalid!"); - } -## start new MMM # first verify the freqency table is appropriate for the standard (NTSC, PAL, SECAM), - # unless they specified the frequency to tune to. - if ($settings{FrequencyTable} !~ /^(custom|$settings{VideoStandard})/i) - { - error(1, "You specified Video Standard '$settings{VideoStandard}' which is incompatible with Frequency Table '$settings{FrequencyTable}'!"); - } ## end new MMM - if (!exists $CHANLIST{$settings{FrequencyTable}}->{$settings{Channel}}) - { - error(1, "Channel = '$settings{Channel}' does not exist in Frequency Table '$settings{FrequencyTable}'!"); - } - } - - outputSetting("Channel"); - outputSetting("Frequency"); - - # get the current channel/frequency value. - my $Frequency; - if(($Frequency = $ivtvObj->getFrequency($tunerFD, $settings{TunerNum})) > 0) - { - my $freq = ($Frequency * 1000) / 16; - print "freq = $freq\n" if ($settings{Debug}); - # find the associated channel. - if ((!exists $opts{F} && !exists $opts{frequency} && !$settings{Frequency}) && ($curstd eq $settings{VideoStandard}) ) - { - foreach my $chan (keys %{$CHANLIST{$settings{FrequencyTable}}}) - { - if ($CHANLIST{$settings{FrequencyTable}}->{$chan} == $freq) - { - $curChannel = $chan; - } - } - print "curChannel = $curChannel\n" if ($settings{Debug}); - } - else - { - $curFrequency = $freq; - } - } - elsif ($Frequency < 0) - { - die "Error: getFrequency() failed!\n"; - } -} -else -{ - # set the channel = "" so we know to ignore it. - $settings{Channel} = ""; -} - -if ($settings{UsingIvtvDriver}) -{ - # validate the Codec related stuff. - if ($settings{BitrateMode} !~ /^(0|1)$/) - { - error(1, "BitrateMode = '$settings{BitrateMode}' is invalid!"); - } - if ($settings{Bitrate} < $settings{minBitrate} || $settings{Bitrate} > $settings{maxBitrate}) - { - error(1, "Bitrate = '$settings{Bitrate}' is invalid!"); - } - if ($settings{PeakBitrate} < $settings{Bitrate}) - { - error(1, "PeakBitrate can not be less than Bitrate!"); - } - elsif ($settings{PeakBitrate} == $settings{Bitrate} && !$settings{BitrateMode} == 1) - { - error(1, "PeakBitrate can not be equal to Bitrate in VBR Mode!"); - } - elsif ($settings{PeakBitrate} < $settings{minPeakBitrate} || $settings{PeakBitrate} > $settings{maxPeakBitrate}) - { - error(1, "PeakBitrate = '$settings{PeakBitrate}' is invalid!"); - } - - if ($settings{VideoStandard} !~ /^(NTSC)/) - { - my $warn = 0; - if ($settings{Framerate} == 0) - { - $settings{Framerate} = 1; - $warn = 1; - } - if ($settings{FramesPerGOP} == 15) - { - $settings{FramesPerGOP} = 12; - $warn = 1; - } - if ($warn) - { - print "Warning: Setting Framerate/FramesPerGOP to PAL settings for Video Standard '$settings{VideoStandard}'!\n\nYou should either specify on the command line or in the ~/.ivtvrc config file.\n"; - } - } - elsif ($settings{VideoStandard} =~ /^(NTSC)/) - { - my $warn = 0; - if ($settings{Framerate} == 1) - { - $settings{Framerate} = 0; - $warn = 1; - } - if ($settings{FramesPerGOP} == 12) - { - $settings{FramesPerGOP} = 15; - $warn = 1; - } - if ($warn) - { - print "Warning: Setting Framerate/FramesPerGOP to NTSC settings for Video Standard '$settings{VideoStandard}'!\n\nYou should either specify on the command line or in the ~/.ivtvrc config file.\n"; - } - } - - if ($settings{StreamType} < 0 || $settings{StreamType} > 14) - { - error(1, "StreamType = '$settings{StreamType}' is invalid!"); - } - - if ($settings{CaptureLastGOP} < 0 || $settings{CaptureLastGOP} > 1) - { - error(1, "CaptureLastGOP = '$settings{CaptureLastGOP}' is invalid!"); - } - - outputSetting("BitrateMode"); - outputSetting("Bitrate"); - outputSetting("PeakBitrate"); - outputSetting("SetMSPMatrix"); - outputSetting("MSPInput"); - outputSetting("MSPOutput"); - outputSetting("Framerate"); - outputSetting("FramesPerGOP"); - outputSetting("Aspect"); - outputSetting("AudioBitmask"); - outputSetting("BFrames"); - outputSetting("DNRMode"); - outputSetting("DNRSpatial"); - outputSetting("DNRTemporal"); - outputSetting("DNRType"); - outputSetting("GOPClosure"); - outputSetting("Pulldown"); - outputSetting("StreamType"); - outputSetting("CaptureLastGOP"); -} - -# update the config file if the user wants us to. -if ($settings{UpdateConfigFile}) -{ - my $profile; - if (@profileNames > 1) - { - print "Warning: Not updating config file as you have more than 1 profile specified!\n"; - } - elsif (@profileNames == 1) - { - $profile = $profileNames[0]; - } - else - { - $profile = "defaults"; - } - if ($profile) - { - my $createProfile = (exists $configIni{$profile} ? 0 : 1); - print "Creating Profile = '$profile': $createProfile\n" if ($settings{Debug}); - - if (!$settings{UseConfigFile}) - { - # we have to create the config file and tie to it. - tie %configIni, 'Config::IniFiles', () or die "Error: Initializing config file '$settings{ConfigFileName}' failed! $!\n"; - - # now set the name to work with. - tied(%configIni)->SetFileName($settings{ConfigFileName}) or die "Error: Setting config file to '$settings{ConfigFileName}' failed! $!\n"; - - $configIni{$profile} = {}; # make sure the section exists. - } - - foreach my $arg (keys %mappings) - { - foreach my $option (split(/\|/, $mappings{$arg})) # handle the long/short command option versions - { - if (exists $configIni{$profile}{$arg} || $createProfile || exists $opts{$option}) - { - $configIni{$profile}{$arg} = $settings{$arg}; - print "configIni{$profile}{$arg} = '" . $settings{$arg} . "'\n" if $settings{Debug}; - last; - } - } - } - - # write the config file out. - tied(%configIni)->RewriteConfig or die "Error: Writing config file '$settings{ConfigFileName}' failed! $!\n"; - } -} - -# this hash keeps track of those values I have to set back. -my %changedSettings = ( - resolution => 0, - standard => 0, - VideoType => 0, - InputNum => 0, - Channel => 0, - Frequency => 0, - codec => 0, - ); - -# change the channel -if ($inputs[$settings{InputNum}] =~ /Tuner/) -{ - if (exists $opts{F} || exists $opts{frequency} || $settings{Frequency}) - { - if ($settings{Frequency} != $curFrequency) - { - $changedSettings{Frequency} = 1; - tuneFrequency($settings{Frequency}); - } - } - else - { - if ($curstd ne $settings{VideoStandard}) - { - # we have to set the channel regardless. - # but we want to tune back to the previous frequency. - $changedSettings{Frequency} = 1; - changeChannel($settings{Channel}); - } - elsif ($settings{Channel} ne $curChannel) - { - # otherwise we just changeChannel and restore the previous channel. - $changedSettings{Channel} = 1; - changeChannel($settings{Channel}); - } - } -} - -# set the video standard -if ($settings{VideoStandard} ne $curstd) -{ - $changedSettings{standard} = 1; - change_standard(); -} - -# set the input -if ($settings{InputNum} != $curinput || $settings{InputName} ne $curinputName) -{ - $changedSettings{InputNum} = 1; - if (!(exists $opts{i} || exists $opts{inputnum} || exists $opts{I} || exists $opts{inputname} || exists $profileOverloads{InputNum} || exists $profileOverloads{InputName})) # our defaults are different than the current values! - { - print "Warning: Changing input from '$curinputName' to'$settings{InputName}'.\n"; - } - change_input(); -} - -# set the capture type - -# store the current width,height so we can restore afterwards -my ($oldWidth, $oldHeight) = $ivtvObj->getResolution($tunerFD); -print "oldWidth = '$oldWidth', oldHeight = '$oldHeight'\n" if ($settings{Debug}); - -if ($settings{VideoWidth} != $oldWidth || $settings{VideoHeight} != $oldHeight) -{ - $changedSettings{resolution} = 1; -} - -# specify the width,height to capture -if ($changedSettings{resolution}) -{ - $result = $ivtvObj->setResolution($tunerFD, $settings{VideoWidth}, $settings{VideoHeight}); - if (not defined $result) - { - die "Error calling setResolution!\n"; - } - if (!$result) - { - die "Error in setResolution ioctl call!\n"; - } -} - -if ($settings{UsingIvtvDriver}) -{ - # set the GOP_END flag if the user requested it. - if ($ivtvVersion > 265) # > 0.1.9 - { - $result = $ivtvObj->setEndGOP($tunerFD, $settings{CaptureLastGOP}); - if (!$result) - { -## L1312 macmil_co_jp MMM die "Error calling setEndGOP($settings{CaptureLastGOP})!\n"; - } - } - - # specify the codec options to capture mpeg's at. - foreach my $codecName (keys %codecMappings) - { - my $codecIndex = $ivtvObj->{codecIndexes}{$codecMappings{$codecName}}; - if ($codecInfo[$codecIndex] != $settings{$codecName}) - { - $changedSettings{codec} = 1; - $newCodecInfo[$codecIndex] = $settings{$codecName}; - print "new $codecName = '$settings{$codecName}', old $codecName = '$codecInfo[$codecIndex]'\n" if $settings{Debug}; - } - } -} - -if ($changedSettings{codec}) -{ - $result = $ivtvObj->setCodecInfo($tunerFD, @newCodecInfo); - if (!$result) - { -## L1334 macmil_co_jp MMM die "Error calling setCodecInfo()!\n"; - } -} - -if (!$settings{DontRecord}) -{ - close($settingsFH) if ($settings{OutputSettings}); - - # capture the video/audio to video.mpg - captureVideo(directoryName => $directoryName, RecordDuration => $settings{RecordDuration}, - OutputFileName => $settings{OutputFileName}, tuner => $tuner); -} - -if ($settings{ResetCardSettings} && !$settings{DontRecord}) -{ - # close and re-open the device since it appears to not like taking new settings if we ended capturing. - close($tuner); - sysopen($tuner, $settings{VideoDevice}, O_RDWR) or die "Error unable to open '$settings{VideoDevice}': $!"; - $tunerFD = fileno($tuner); - - # restore Codec values - if ($changedSettings{codec}) - { - $result = $ivtvObj->setCodecInfo($tunerFD, @codecInfo); - if (!$result) - { -## L1360 macmil_co_jp MMM die "Error calling setCodecInfo()!\n"; - } - } - - # restore the previous input setting - if ($changedSettings{InputNum}) - { - # reset back to the old input name - $settings{InputName} = $curinputName; - change_input(); - } - - # restore the previous video standard - if ($changedSettings{standard}) - { - $settings{VideoStandard} = $curstd; - change_standard(); - } - - # restore the previous width,height settings - if ($changedSettings{resolution}) - { - $result = $ivtvObj->setResolution($tunerFD, $oldWidth, $oldHeight); - if (not defined $result) - { - die "Error calling setResolution!\n"; - } - if (!$result) - { - die "Error in setResolution ioctl call! result = '$result', oldWidth = '$oldWidth', oldHeight = '$oldHeight'\n"; - } - } - - # restore the previous channel - if ($changedSettings{Channel} && $curChannel > 0) - { - changeChannel($curChannel); - } - if ($changedSettings{Frequency} && $curFrequency > 0) - { - tuneFrequency($curFrequency); - } -} - -# close the tuner device -close($tuner); - -exit 0; - -# usage(returnValue, ErrorString) -# returnValue = 1 or 0 -# ErrorString = message you want to tell the user, but only if returnValue = 1. -sub usage -{ - my $errorCode = shift; - my $error = shift; - - print $usageStr; - print "\nError: $error\n" if ($errorCode == 1); - print "$error\n" if ($errorCode == 2); - - exit $errorCode; -} - -# error(returnValue, ErrorString) -# returnValue = 1 or 0 -# ErrorString = message you want to tell the user. -sub error -{ - my $errorCode = shift; - my $error = shift; - - print "$versionStr"; - print "\nError: $error\n"; - - exit $errorCode; -} - -# changes the input to $settings{InputNum} as long as it isn't = $curinput -sub change_input { - my $preinput = $name2input{$settings{InputName}}; - if($preinput != $curinput) - { - $curinput = $preinput; - print "input now $settings{InputName}, #$preinput\n" if ($settings{Debug}); - my $result = $ivtvObj->setInput($tunerFD, $preinput); - if (!$result) - { - die "Error: setInput($preinput) failed!\n"; - } - } -} - -# changes the video standard to $settings{VideoStandard} as long as it isn't = $curstd -sub change_standard { - my $standard = $name2std{$settings{VideoStandard}}; - if($standard != $curStandard) - { - $curStandard = $standard; - print "standard now $settings{VideoStandard}, #$standard\n" if ($settings{Debug}); -## L1460 v060406.pl MMM my $result = $ivtvObj->setStandard($tunerFD, $standard); - if (!$result) - { -## L1463 v060406.pl MMM die "Error: setStandard($standard) failed!\n"; - } - } -} - -# changes the channel -# takes the channel to change -sub changeChannel -{ - my $ch = shift; - my $freq = $CHANLIST{$settings{FrequencyTable}}->{$ch}; - my $driverf = ($freq * 16)/1000; - - print "Ch.$ch: $freq $driverf\n" if ($settings{Debug}); - - if (!$ivtvObj->setFrequency($tunerFD, $settings{TunerNum}, $driverf)) - { - die "Error: changeChannel($ch) failed!\n"; - } -} - -# tunes to the specified frequency -# takes the frequency to tune to -sub tuneFrequency -{ - my $freq = shift; - my $driverf = ($freq * 16)/1000; - - print "freq: $freq $driverf\n" if ($settings{Debug}); - - if (!$ivtvObj->setFrequency($tunerFD, $settings{TunerNum}, $driverf)) - { - die "Error: tuneFrequency($freq) failed!\n"; - } -} - -my $done = 0; - -sub catch_alarm { - if ($settings{CaptureLastGOP}) - { - $stopGOP = 1; # signal we need to stop the stream and capture the last GOP. - } - else - { - $done = 1; # signal we are done. - } -} - -# does the actual video capturing work. -# takes directoryName, RecordDuration, OutputFileName, tuner -sub captureVideo -{ - my %args = ( @_ ); - my $directoryName = $args{directoryName}; - my $RecordDuration = $args{RecordDuration}; - my $OutputFileName = $args{OutputFileName}; - my $tuner = $args{tuner}; - my $fname = "$directoryName/$OutputFileName"; - - # setup global variables, signal handlers, etc. - - $SIG{ALRM} = \&catch_alarm; - $SIG{INT} = \&catch_alarm; # handle Ctrl-C - - # open the file for writing. - - sysopen(OUTPUT, "$fname", O_CREAT | O_WRONLY | O_LARGEFILE) or die "Error creating file '$fname': $!\n"; - - alarm($RecordDuration); - my $buf = ""; - while (!$done) - { - if ($stopGOP) - { - $stopGOP = 0; - $ivtvObj->stopEncoding($tuner); - $endStream = 1; - $done = 1; # signal we are done after this loop. - } - # read from the device and write to the file. (16384) 32768 - my $bytes = read($tuner, $buf, 16384); - if (!$bytes && $endStream) - { - last; - } - print OUTPUT $buf; - } - - # close the file - close(OUTPUT); -} - -# returns the formatted directory string -sub formatDirectoryString -{ - my $temp = $settings{DirectoryFormatString}; - my $result = $settings{OutputDirectory}; - my %lookupTable = ( - "d" => `/bin/date "$settings{DateTimeFormatString}"`, - "I" => $settings{InputName}, - "c" => $settings{Channel}, - ); - - # fixup the InputName value - $lookupTable{I} =~ s/\s/_/g; - # cleanup the trailing slash on the date - chomp $lookupTable{d}; - - foreach my $option ("d", "I", "c") - { - $temp =~ s/\%$option/$lookupTable{$option}/g; - } - - $result .= "/" . ($temp ? "$temp/" : ""); - - return $result; -} - -sub outputSettingSetup -{ - my $date = `/bin/date`; chomp $date; - - if ($settings{OutputSettingsType} eq "shell") - { - print $settingsFH "# Settings for Recording made on $date.\n"; - } - elsif ($settings{OutputSettingsType} eq "perl") - { - print $settingsFH "# Settings for Recording made on $date.\n"; - print $settingsFH "my %settings = ();\n"; - } -} - -# outputs the specified setting and it's value to the -# settings file represented by $settingsFH in the -# specified language. -sub outputSetting -{ - my $setting = shift; - my $value = $settings{$setting}; - - return if (!$settings{OutputSettings}); - - if ($settings{OutputSettingsType} eq "shell") - { - print $settingsFH "REC_" . uc($setting) . "=\"$value\"\n"; - } - elsif ($settings{OutputSettingsType} eq "perl") - { - print $settingsFH "\$settings{$setting} = \"$value\";\n"; - } -}