VFRなmp4の作り方(2)
24fpsと30fpsが混合したmp4を作る自分的手順(自動化編)
mp4boxを利用すると、nhmlというmkvのtimecodeファイルと同じようなものを扱うことが出来る。
このnhmlファイルを上手く使って、面倒な分割作業なしにVFRなmp4を作る手順を考えてみた。
DGDecode_mpeg2source("vfr.d2v") tfm(d2v="vfr.d2v") tdecimate(mode=3,hybrid=2,vfrDec=1,mkvOut="vfr-timecode.txt",tcfv1=false)
mp4box -nhml 1 vfr.mp4
- nhmlファイル内のタイムスタンプをtimecodeファイルにあわせて修正。
(とあるツール) vfr-timecode.txt vfr_track1.nhml > vfr_track1_tc.nhml
- 修正済のnhmlファイルと音声ファイルから、mp4boxを使ってmp4を合成。
mp4box -add vfr_track1_tc.nhml -add vfr.aac -new vfr.mp4
とあるツール*1 *2(とりあえず動けばいいやスクリプト)
#!/usr/bin/perl # url - http://d.hatena.ne.jp/zmi/ $SEARCH_MAX = 6; $tc = $ARGV[0]; $nhml = $ARGV[1]; open TC, $tc or die; open NHML, $nhml or die; # parse timecode file while(<TC>){ next if /^\#/; next unless /^([.\d]+)/; push tc, int($1 * 1000 + 0.5); } close TC; $tcCount = @tc; # parse nhml file while(<NHML>){ next unless /<NHNTSample DTS="(\d+)".*?\/>/; push dtsList, $1; } seek(NHML, 0, 0); # convert nhml $frame = 0; while(<NHML>){ if(/<NHNTStream.*?>/){ s/timeScale="\d+"/timeScale="1000000"/; print; next; } (print, next) unless /<NHNTSample DTS="(\d+)" dataLength="(\d+)" CTSOffset="(\d+)"( isRAP="yes") \/>/ or /<NHNTSample DTS="(\d+)" dataLength="(\d+)" CTSOffset="(\d+)" \/>/ or /<NHNTSample DTS="(\d+)" dataLength="(\d+)" \/>/; next unless $frame < $tcCount; $dts = $1; $dataLength = $2; $ctsOffset = ($3 or 0); $isRap = $4; # convert timecode to dts/cts $cts = $dts + $ctsOffset; for($cnt = $frame; $cnt < ($frame + $SEARCH_MAX); $cnt++){ if(abs($dtsList[$cnt] - $cts) <= 1){ $newCts = $tc[$cnt]; last; } } $newDts = $tc[$frame]; if(($cnt == $frame + $SEARCH_MAX) or ($cnt >= $tcCount)){ $newCtsOffset = ($tc[$frame] - $tc[$frame -1]) * int(($ctsOffset / ($dtsList[$frame] - $dtsList[$frame -1])) + 0.5); }else{ $newCtsOffset = $newCts - $newDts; } print "<NHNTSample DTS=\"$newDts\" dataLength=\"$dataLength\" CTSOffset=\"$newCtsOffset\"$isRap />\n"; $frame++; } close NHML;