†ぽんこつビデオ工房†

無損失原盤の作成2

作成開始日 2022.12.25
最終更新日 2022.12.25

無損失原盤の処理方法の基本原理は既に【別項】で述べた。しかし、この方法は手作業による工程が多く非常に面倒臭い。そこで、少し効率化する方法を考案した。基本的には、Avidemuxの編集点ファイル(pyプロジェクトファイル)を参照して各パートを切り出し、微調整を加えた後に結合すると言う方法。厄介なのは、avidemuxとffmpegの相性の悪さ。両方のツールを併用せざるを得ないのだが、普通に使用すると、無視できない誤差が発生してしまう。そこで…

30分番組は、たいてい番組本体が24分、番組中CMが3分、番組後CMが3分くらいの按分。無編集で原盤として保存しても良いのだが、番組本体だけ取り出せればサイズが8割に減る。これは保存の際にけっこう大きな差になる。

番組後CMを削除するだけならば処理は単純で、サイズも9割になる。しかも、番組中CMは必ずしも不要とは限らない。考慮に値する。ただし、ffmpegでお尻のCMを切って、avidemux_cliで素通し変換を掛けるとファイルが壊れるので…⇒【こっち】

@編集したい動画ファイル(.VRO)をavidmux_cliで素通しAVI変換する。下記のようなバッチAVCL.BATを作成して、「avcl *.vro[Enter]」とすれば簡単。
@REM ***** AVCL.BAT -- AviDemux Command Line *****
@for %%f in (%1) Do @(
"C:\Program Files\Avidemux 2.6 - 64bits\avidemux_cli" ^
--load %%f --video-codec COPY --audio-codec COPY --nogui --save %%~nf.avi
)

A素通しavi変換したファイルをAvidemux 2.6.8で読み込んで編集(CMカット)する。

B編集が済んだら、ツールバーにある[Save Project]アイコンをクリックして、プロジェクトファイル(.py)を保存する。ここでは、動画ファイル名を「05.avi」とすれば、プロジェクトファイル名は「05.py」のようにする。

Cカレントディレクトリに「genban」というサブディレクトリを作成しておく。

D次のようなPerlスクリプトを実行する。この処理が今回のキモで、ffmpegとAvidemuxの誤差を吸収するために、切り出し位置の末尾に0.07秒の補正を加えている。これによって、編集点に僅かな食い込みが生じるが、補正をしないとCMの残滓(1フレーム)が残ってしまうことがある。ちなみに、この処理によって、24分4パート構成番組で合計0.3秒ほどの欠損が発生する。現状では、ここは目をつぶるしかない。

なお、先頭位置も直近のIフレーム位置に丸められるため、0〜0.6秒くらいのCM残滓が付くが、これは後述の方法で除去する。

#pick2.pl
#無損失原盤用の切り出しプログラム
#切り出し範囲の末尾位置には0.07秒の補正を加えている

my @py=glob('*.py');

my $fname;
my $st;
my $p,$q,$r;
my $top,$bot;
my $fbat;

open my $fbat, '>', 'build.bat';

foreach(@py){

  $st=$_;
  print "$st \n";
  $p=index($st,'.');
  $fname=substr($st,0,$p);

  open my $fp  , '<', $fname.'.py';

  print $fbat "del _?.avi \n";

  $n=0;
  while ($st = readline $fp){
    chomp $st;
    if (index($st,'addSegment')>=0) {
      $n=$n+1;
      print "$n : $st \n";

      $p=index($st,' ');
      $q=rindex($st,' ');
      $r=index($st,')');

      $top=substr($st,$p+1,$q-$p-2)/1000000;
      $bot=substr($st,$q+1,$r-$q)/1000000-0.07;	#0.07は補正値(2フレーム分)
      print $fbat "ffmpeg -ss $top -i $fname.avi -t $bot -c copy genban\\".$fname.chr($n+96)."-.avi \n";
    }
  };
  #print $fbat "ffmpeg -f concat -i $fname.lst -c copy ";
  #print $fbat " -aspect 4:3 ";
  #print $fbat " -aspect 16:9 ";
  #print $fbat "genban\\$fname.avi \n";
  #print $fbat "del _?.avi \n";

  close $fp;
  close $flist;
};

print $fbat "echo  \n";
close $fbat;

E上記のスクリプトを実行すると、カレントディレクトリに「build.bat」というバッチファイルが作成されるので、これを実行する(引数は不要)。

F先程作成した「genban」ディレクトリに、「05a-.avi」「05b-.avi」…などのファイルが作成されるので、一つずつAvidemuxで開いて、先頭のCM残滓位置を確認し、ファイル名を変更する。たとえば、0.367秒位置から本編が始まっている場合は「05a-367.avi」などのように、開始位置をファイル名に反映させる。

Gファイル名をすべて変更したら、カレントディレクトリを「genban」に移動して、次のようなバッチを実行する。これで、CMを奇麗にカットしたmp4/h.264ファイルが作成される。素通しaviを切り出した元ファイルは、ファイル名のディレクトリの中に移動される(先程の「05a-367.avi」など)。

@rem ***** build2.bat *****
@echo off
setlocal enabledelayedexpansion

set mm=9999

for %%g in (*.avi) do (
  set fname=%%g
  set nn=!fname:~0,2!

  @REM ***** 話数判別 *****
  if not "!nn!"=="!mm!" (
    echo ***** !nn! *****
    @del nn.lst 2> nul
    for %%f in (!nn!*.avi) do (
      set finp=%%f
      @REM ***** ファイル名の本体部分とオフセットの切り出し *****
      for /f "usebackq tokens=1-3 delims=-." %%a in ('!finp!') do (
        set body=%%a
        if not "%%c" == "" (set ss=%%b) else (set ss=0)
      )
      set fout=!body!.mp4
      echo ===== out : !fout! !ss!
      echo file !fout! >> nn.lst

      @REM ***** 部分ファイルの個別変換 *****
      if "!ss!" == "0" (echo ***** offset missing ***** & exit /b)
      ffmpeg -ss 0.!ss! -i !finp! !opt! !fout!
    )
    @REM ***** 部分ファイルの1話バインド *****
    set out=!nn!.mp4
    ffmpeg -f concat -i nn.lst -c copy !out!

    @REM ***** 原盤ファイルをディレクトリにまとめる *****
    set gdir=!nn!
    md !gdir!
    echo ===== make dir : !gdir! =====
    move !nn!*.avi !gdir!
  )
  set mm=!nn!
)

endlocal
echo 
exit /b

@del nn.lst 2> nul

for %%f in (*.avi) do (
set finp=%%f
echo ***** inp : !finp!
for /f "usebackq tokens=1-3 delims=-." %%a in ('!finp!') do (
set body=%%a
if not "%%c" == "" (set ss=%%b) else (set ss=0)
)
set fout=!body!.mp4
echo ***** out : !fout! !ss!
echo file !fout! >> nn.lst

if "!ss!" == "0" (echo *** offset missing *** & exit /b) ^
else (echo @@@@@ ffmpeg -ss 0.!ss! -i !finp! !opt! !fout!
ffmpeg -ss 0.!ss! -i !finp! !opt! !fout!)
)

set out=!finp:~0,2!.mp4

ffmpeg -f concat -i nn.lst -c copy !out!

set gdir=!finp:~0,2!
md !gdir!
echo *** make dir : !gdir! ***
move *.avi !gdir!

echo 
exit /b
endlocal


【ぽんこつビデオ工房目次】 【ホーム】