get_stream_map

epgrecでCS放送を録画する場合には録画モードを"Minimum TS"にしておかないとトランスポンダ単位で複数のチャンネルが保存されてしまうので、TSファイルをmp4にエンコードする際に期待したのとは異なる番組がエンコードされてしまったり、エンコードに失敗してしまうケースがある。

具体的にはffmpegで映像・音声チャンネルをそれぞれ選択する必要があり、地上波やBSでは映像が0:0が音声が0:1となるStreamIDをCS放送波に合わせて変更する事になる。

というわけで、一旦ffmpegを通してProgramIDに合わせた映像・音声のStreamIDを拾うスクリプトを作ってみた。

~/bin/get_stream_map.pl

#!/usr/bin/perl
use strict;
#ARGV[0] Target TS File
my $cmd = "/usr/local/bin/ffmpeg";
my $ffpreset = "/var/www/html/epgrec/libx264-hq-ts.ffpreset";
my $str;
my @lines;
my $br;            #Audio BitRate
my ($vstr,$astr);  #StreamID
my ($prg_target, $prg_crnt); #ProgramID
# 20131225_2030_CS2_CS298_ふたりはプリキュア_#26.ts':
if ($ARGV[0] =~ /^.*\/?2[0-9]*_[0-9]*_CS[0-9]_CS([0-9]*)_.*$/){
    $prg_target = $1;
}
# 20140101_2100_31_GRhd_相棒_season12_元日スペシャル.ts
# 20140117_0800_236_BShd_【字】スイートプリキュア♪_#20.ts
if ($ARGV[0] =~ /^.*\/?2[0-9]*_[0-9]*_([0-9]*)_(GR|BS)(hd|sd)_.*$/){
    $prg_target = $1;
}
# print "Program $prg_target\n";
$str = `$cmd -i $ARGV[0] 2>&1`;
@lines = split(/\n/,$str);
foreach(@lines){
    chomp;
# print "$_ \n";
    #Get Program ID
    if($_ =~ /^ +Program ([0-9]+) *$/){
        $prg_crnt = $1;
    }
    #Check Program ID
    if($prg_crnt != $prg_target){
        next;
    }
# print "$_ \n";
    #Get Video StreamID
    if($_ =~ /\#([0-9:]+)\[.+Video: mpeg2video/ && $vstr eq ""){
        $vstr = "-map $1";
    }
    #Get Audio StreamID
    elsif($_ =~ /\#([0-9:]+)\[.+Audio: .+, ([0-9]+) kb\/s/){
        if($2 > $br){
            $astr = "-map $1";
            $br = $2;
        }
    }
}
if($vstr eq "" && $astr eq ""){
    $vstr = "-map 0:0";
    $astr = "-map 0:1";
}
print "$vstr $astr\n";
1;

パタメータの形式はFFmpeg 1.1.2対応で、ファイル名から正しいProgramIDが拾えない地上波等でStreamIDがうまく拾えなかった場合は、デフォルトの"-map 0:0 -map 0:1"を返す。

参照

衛星デジタル放送 情報ページ http://www5e.biglobe.ne.jp/~kazu_f/digital-sat/

録画予約システムepgrec http://www.mda.or.jp/epgrec/

MediaTomb - Free UPnP MediaServer http://mediatomb.cc/

FFmpeg http://www.ffmpeg.org/