part2 FFMpegでお手軽VFRエンコード。同一フレームを間引いてVFR化してみた。(nvenc,opencl使用)

日記 > PC

[VFRの技術検証です。すべての動画にVFR化を薦めるものではございませんm(__)m]

いろいろご意見をいただいて、エンコードは1度で済ませた方が良いという事で!(笑)

■ FFMpeg :「mpdecimate」part2

◆[ffmpeg_mpd.bat]mpdecimateバッチファイル例(i7-6700 + RTX2060-OC環境です)
スッキリしたけど、今までHWエンコードと言えばNVEncC任せだっただけに何だかさみしい(^◇^;

[ffmpeg.exeにパスは通してあるものとします]

@echo off
set BEFORE=%~1
set FILENAME=%~n1
set EXTENSION=%~x1
set AFTER=d:\%FILENAME%_mpd%EXTENSION%
set LOGFILE=%FILENAME%_mpd.log

rem mp4 audio-copy(unsharpの範囲は奇数指定):前回のNVEcnCの内容を組み込んだ感じ。

ffmpeg -hwaccel cuda -i "%BEFORE%" -c:v hevc_nvenc -preset:v p7 -profile:v main10 -vsync vfr -vf mpdecimate,unsharp=lx=5:ly=5:la=0.8:cx=5:cy=5:ca=0:opencl=1 -rc:v constqp -rc-lookahead 32 -spatial-aq 0 -temporal-aq 0 -weighted_pred 0 -init_qpI 20 -init_qpP 22 -init_qpB 24 -b_ref_mode 1 -dpb_size 4 -multipass 2 -g 300 -bf 4 -pix_fmt p010le -codec:a copy "%AFTER%" 2>"%LOGFILE%"

※圧縮qpやGOP長、オプションなどは環境などに合わせて好みでどうぞ。ログファイルの書き出しを行うと上書き確認の[y/n]の表示も画面に出ないので注意してください
m(__)m
opencl=1は有効になっていないかもしれないという話もあったり無かったり。使う人は自分の環境に合わせて動作確認を。
エンコード設定はエンコード環境とソースに合わせて調整しましょう!


以下前回と同じ。

→ファイル数が多いときはPowerShell使いましょ。
◆(call_mpd.ps1)mpdecimateバッチファイルを指定フォルダ(例では ./Source_mp4)内のファイルの数だけ連続で呼び出すPowerShell
[右クリックからPoweShellで実行を選ぶ]

# loop encode.bat
 Write-Host '◆ 指定フォルダのEncodeを開始します';

# 処理対象のフォルダ
 $targetFolder = '.\Source_mp4\';
 $encodeBatFile = '.\ffmpeg_mpd.bat';

function DispNowDateTime{
  $now = Get-Date -format "yyyy/MM/dd HH:mm";
  Write-Host ("`r`n [ " + $now + ' ]');
}

# ----処理開始時間の表示
 DispNowDateTime;

# $targetFolder内のファイル・フォルダのリストを取得する。
 $itemList = Get-ChildItem $targetFolder -File | Sort-Object Name;

#全件数の表示
 $num = ($itemList | Measure-Object).Count
  Write-Host (' ( ' + $num + ' 件) -- 指定フォルダ内のファイル数') ;

#カウント設定
 $enccount = 1;

 foreach($item in $itemList)
 {
    if($item.PSIsContainer)
    {
        # フォルダの場合の処理
        Write-Host ($item.Name + 'はフォルダです。');
    }
    else
    {
        # ファイルの場合の処理
        Write-Host ('( ' + [String]$enccount++ + '/ ' + $num + ') エンコードを開始してProcessの終了を待ちます');
        Write-Host '['$item.Name']';


        $DIRFILE = '"' + $item.FullName + '"';

        #特定のProcessが終了するのを待つ
		$batobj = Start-Process $encodeBatFile ${DIRFILE} -PassThru;
		Wait-Process -Id ($batobj.id);
		Write-Host ("id=$($batobj.id)のProcessが終了しました");

		# ----処理終了時間の表示
		DispNowDateTime;

    }
 }

 Write-Host ' [ Fin ]';

pause