#!/usr/bin/perl -w # ・foltia anime lockerが録画したディレクトリ($SOURCEDIR)内の動画(*.ts,*.MP4)を # ・ファイル名を変更 .... 不要なフィールドを削除, 文字数削減 # ・選択 ................ MP4は常時、TSはMP4が無い場合のみ対象 # しながら、カレントディレクトリにコピーする # ・コピー履歴情報($COPYHIST)を使って、過去コピーしたものは、コピー先が削除されて # も再度コピーしない # ※このファイルはUTF-8保存 use strict; use warnings; use encoding 'utf8'; my $SOURCEDIR = "/home/foltia/php/DLNAroot/01-全録画/"; # コピー元ディレクトリ # SAMBA経由だと \\FOLTIA\JP-file-style\01-全録画 my $COPYHIST = "./__copyhistry.txt"; # コピー履歴格納ファイル my $MAXHIST = 10000; # コピー履歴保存最大数 my $IGNORE = "./__ignorefiles.txt"; # ファイル名パターンが想定外でコピー処理できなかったファイル my $TSLOG = "./__tsselect.txt"; # TS情報 my $MAXCOPY = 20; # 最大コピーファイル数 ※次回のcron起動までに処理が終わっている必要がある my $MP4DELAY = 420; # TSファイル評価遅延時間(min) =MP4生成にかかる時間 420 my $OVERWRITE = 0; # コピー先が同一ファイル名の時、上書き(1),連番で追加(0) # ※ファイル名衝突で欠落するのを防ぐ為に、当面は 0で運用する my $TITLELEN = 40; # タイトル文字数 my $RUNCOPY = 1; # 実際にコピーする(1), デバッグ用に空ファイルを仮作成する(0) my $DBG = 0; my %foltiafile; # $foltiafile{サーバー上のpath}{"NAME"} 録画対象の相違を識別するのに必要な情報を格納(デバッグ時の重複の確認用で、実機能には使わない) # {"SNAME"} 保存するファイル名のヘッダ ※MP4,tsの識別情報は含めてはいけない # {"EXT" } 保存するファイル名の拡張子 { # foltia録画一覧を取得 # /home/foltia/php/DLNAroot {01-全録画\,02-***\,03-EPG録画\,04-キーワード録画\,05-NAS\} # 01-全録画/2015/06/ALL # <キーワード予約> # 0625-0100_キーワード録画_455_クローズアップ現代「“地中海難民”?EU揺るがす人道危機?」 欧州を目指す密航船が次々と転覆し多数の犠牲者を出している地中海。押し寄_SD_-438.MP4 # 0625-0100_キーワード録画_455_クローズアップ現代「“地中海難民”?EU揺るがす人道危機?」 欧州を目指す密航船が次々と転覆し多数の犠牲者を出している地中海。押し寄_TS_-438.ts # # 0628-1130_EPG録画_11_京の菓子ごよみ芸術的ともいえる京菓子にスポットをあて、京菓子の意匠、創り上げる職人の技、そして京菓子の美味しさに迫ります。_TS_-508.ts # <アニメ予約> ※ $id1にあたる情報は$titleに含まれている/アニメはアニメ予約がお勧め # 0628-1700_アルスラーン戦記_13_王子二人_TS_329411.ts # TSファイルとMP4ファイルの生成にタイムラグがあるので, TSファイル取得(7時間前),MP4ファイル取得(5分前)に差をつけている # 経験上PRIMERGY TX100 S1で、MP4生成は平均3時間、時折1日以上のラグがある。 # 気にしない #printf( "(find $SOURCEDIR -mmin +$MP4DELAY -name \\\*.ts -print ; find $SOURCEDIR -mmin +5 -name \\\*.MP4 -print)|" ); open( my $IN, "(find $SOURCEDIR -mmin +$MP4DELAY -name \\\*.ts -print ; find $SOURCEDIR -mmin +5 -name \\\*.MP4 -print)|" ) || die( "cannot make pipe $!" ); open( my $OUT,">" . $IGNORE ) || die( "cannote write open $!" ); while (<$IN>) { my $inp = $_; chomp $inp; if (!(-e $inp)) { next; } # シンボリックのみ存在して実態が削除されているケースがある #printf( "<<<<<%s>>>>>\n", $inp ); #printf( " %s\n", (-e $inp) ? "exists" : "deleted" ); if ( $inp =~ /\d+\/\d+\/ALL/ ) { # "ALL"のみを対象にする( "AAC","MP4-HD", "MP4-SD", "MPEG2" ディレクトリは無視する ) if ( $DBG ) { printf( "============\n<%s>\n", $inp ); } my ( $date1, $date2, $rtype, $id1, $title, $dtype, $id2, $ext ); if ( ( $date1, $date2, $rtype, $id1, $title, $dtype, $id2, $ext ) = ( $inp =~ /(\d+\/\d+)\/ALL\/(\d+-\d+)_(\S+)_(\d+)_(.+)_([A-Z]+)_-(\d+)\.(\S+)$/ ) ) { # キーワード予約,EPG予約 $foltiafile{$inp}{"NAME" } = join( "_", ( $date1, $date2, $title ) ); $foltiafile{$inp}{"SNAME"} = join( "_", ( substr( $title, 0, $TITLELEN ) ) ); $foltiafile{$inp}{"SNAME"} =~ s/ / /g; $foltiafile{$inp}{"SNAME"} =~ s/\s+/ /g; $foltiafile{$inp}{"EXT" } = $ext; if ( $DBG ) { printf( " => KWD,EPG <%s>\n", $foltiafile{$inp}{"SNAME"} ); } } elsif ( ( $date1, $date2, $title, $dtype, $id2, $ext ) = ( $inp =~ /(\d+\/\d+)\/ALL\/(\d+-\d+)_(.+)_([A-Z]+)_(\d+)\.(\S+)$/ ) ) { # アニメ予約 $foltiafile{$inp}{"NAME" } = join( "_", ( $title ) ); $foltiafile{$inp}{"SNAME"} = join( "_", ( substr( $title, 0, $TITLELEN ) ) ); $foltiafile{$inp}{"SNAME"} =~ s/ / /g; $foltiafile{$inp}{"SNAME"} =~ s/\s+/ /g; $foltiafile{$inp}{"EXT" } = $ext; if ( $DBG ) { printf( " => ANIME <%s>\n", $foltiafile{$inp}{"SNAME"} ); } } else { if ( ( $inp =~ /\.ts/ ) || ( $inp =~ /\.MP4/ ) ) { if ( $DBG ) { printf( " Cannot recognize pattern <%s>\n", $inp ); } printf( $OUT "%s\n", $inp ); } } } } close($IN); close($OUT); } my %savedfile; { # コピー済一覧を取得 if ( open( my $IN, $COPYHIST ) ) { while (<$IN>) { my $inp = $_; chomp $inp; $savedfile{$inp} = 1; } close($IN); } } { # コピー my $copycnt = 0; foreach my $fpath ( sort keys %foltiafile ) { my $docopy = 0; if ( $DBG ) { printf( "======================\n" ); } if ( $DBG ) { printf( " fpath:<%s>\n", $fpath ); } if ( $DBG ) { printf( " name :<%s>\n", $foltiafile{$fpath}{"NAME"} ); } if ( $DBG ) { printf( " sname:<%s>\n", $foltiafile{$fpath}{"SNAME"} ); } if ( $DBG ) { printf( " ext :<%s>\n", $foltiafile{$fpath}{"EXT"} ); } my $saveflg = 0; if ( $foltiafile{$fpath}{"EXT"} eq "MP4" ) { $saveflg = 1; } elsif ( $foltiafile{$fpath}{"EXT"} eq "ts" ) { my $found = 1; foreach my $fpath2 ( sort keys %foltiafile ) { if ( ( $foltiafile{$fpath2}{"SNAME"} eq $foltiafile{$fpath}{"SNAME"} ) && ( $foltiafile{$fpath2}{"EXT"} eq "MP4" ) ) { $found = 0; last; } } if ( $found == 1 ) { $saveflg = 1; } } if ( ( $saveflg == 1 ) && (!defined($savedfile{$fpath})) ) { my $savename = sprintf( "%s.%s", $foltiafile{$fpath}{"SNAME"}, $foltiafile{$fpath}{"EXT"} ); if ( (!$OVERWRITE) && ( -f $savename ) ) { for ( my $i=1; $i<100; $i++ ) { $savename = sprintf( "%s_%03d.%s", $foltiafile{$fpath}{"SNAME"}, $i, $foltiafile{$fpath}{"EXT"} ); if ( -f $savename ) { # } else { last; } } } if ( $DBG ) { printf( " ==> will saved as :%s\n", $savename ); } $savedfile{$fpath} = 1; if ( $RUNCOPY ) { if (!$DBG) { printf( "%02d/%02d>> %s\n", $copycnt, $MAXCOPY, $savename ); } #if (!$DBG) { printf( " From: [%s] To: [%s]\n", $fpath, $savename ); } use File::Copy; my( $atime, $mtime ) = ( stat( $fpath ) )[8, 9]; copy( $fpath, $savename ); utime( $atime, $mtime, $savename ); chmod( 0666, $savename ) or die( "chmod error ; $!" ); } else { # デバッグ用/空ファイルを作成する open( my $OUT, ">" . $savename ); close( $OUT ); } $copycnt++; } if ( $copycnt > $MAXCOPY ) { printf( ">> **** reach to max copy count. some files are not copied\n" ); last; } } } { # 保存履歴をセーブ open( my $OUT, ">" . $COPYHIST ) || die( "Cannot write $!" ); binmode( $OUT, ":utf8"); my $i = 0; foreach my $fpath ( reverse sort keys %savedfile ) { printf( $OUT "%s\n", $fpath); if ( $i++ > $MAXHIST ) { last; } } close($OUT); }