見出し画像

EDCB+HandBrake でTSからMP4へ自動コンバートバッチ

どうも、はぐです。
久々の投稿は、PCでのTV環境についてです。
最近、TV環境いじっていなくて、今はいろいろどうなってるんだろうなぁ、と思って調べてみたら、つくし島だよりさんが、TVtestや、EDCBの最新をコンパイルして配布してくれているのを知りました。
で、わたしもあやかってバージョンアップして、ついでにいつかやろうと思っていた移動&自動コンバートバッチの作成に着手しました。
なにしろ、予約キーワードでの録画が多く、みんな同じフォルダに保存されてしまうため、整理が面倒だったからです。

簡単に書いていきます。
詳しくはバッチ内のコメントとか読んでください。


何をしているのか概要

・自動予約のキーワードのフォルダを作り、録画したtsファイルをそこに移動。
・同じドライブにtempフォルダを作り、そこに移動。
・日本語ファイル名から日付時刻を使った名前に変更してからtsからMP4に変換。
・変換ファイルを元の名前にもどして、さらに元のフォルダに戻す。
・必要ならtsファイルは削除。

日本語ファイル名でも変換できるんですが、HandBrake内部のライブラリがUNICODE対応みたいで、shift-jisのファイル名をぶちこむと、文字化けしていてログを見ているととても嫌だからです。どこかでおかしいことになっているかもしれないので、rename処理してから変換することにしました。

あと、もし移動だけで変換はしないのであれば、ts_move.bat内のCONV_TSを0にすれば変換せずに終了です。

よく考えたら、tempに移動しなくてもできたけど、100以上もあるフォルダで変換作業とかやると、ファイルをぱっと見つけられなかったので、移動しました。
あと、自分は見たい番組にsystem属性つけてファイラーで見やすくしていたので、今回のbatもsystem属性のものはそのまま属性付きでコピーや変換するようにしてます。
フォルダも、自分で作ったフォルダなのか、予約キーワードから作られたフォルダなのかわかるようにsystem属性つけてます。

【注意】
HandBrakeコンバート中にCtrl+cで終了した場合、バッチ終了しますか?と聞いてきますが、Yを押すと、tempフォルダに日付にrenmaeしたtsファイルが残されます。
そのフォルダに有るorg_filename.txtの最終行を見て、元の名前に戻してください。
Nを押せば、元の名前に戻して、元のフォルダに戻して、バッチ終了させるようにはしてあるので、Nを押したほうがいいです。

EDCB側設定

ts_move.bat を、EDCBと同じフォルダに保存。バッチなので、shift-jisで保存しないと、文字化けします。ファイル置いておくので、ダウンロードしたほうが楽。
ファイル先頭あたりの設定は自分の環境に変えてください。
(行頭REMはコメントアウトです。AviUtilのやつは前の名残でのこしてあるだけ。)

@echo off
REM TSファイルを、予約キーワードのフォルダをつくり、そこに移動 & MP4に変換

setlocal enabledelayedexpansion

REM TSからMP4に変換するなら1を指定
set CONV_TS=1
REM TSファイルを、どのフォルダに移動したか、履歴を残しておくファイルを指定。
set MOVE_HISTRY_FILE="D:\tv_conv.txt"

REM tsからMP4に変換するbat指定
set TS_TO_MP4_BAT="C:\Tools\Moves\HandBrake\encode_handbrake.bat"
REM set TS_TO_MP4_BAT="C:\Tools\Moves\AviUtil\encode_aviutl.bat"

echo FilePath : $FilePath$
echo FolderPath : $FolderPath$
echo FileName : $FileName$
echo AddKey : $AddKey$

if "$AddKey$" == "" (
    
    echo 予約キーワードがありません。移動しません。
    REM mp4に変換
    if %CONV_TS% equ 1 (
        call %TS_TO_MP4_BAT% "$FilePath$"
    )
) else (

    REM EPG自動予約で登録されたキーワードのフォルダ名
    set mv_folder="$FolderPath$\$AddKey$"

    echo 移動先:!mv_folder!

    mkdir !mv_folder!
    move "$FilePath$" !mv_folder!

    REM ファイラーでわかりやすいようにフォルダにsystem属性追加
    attrib +S !mv_folder!
    
    REM mp4に変換
    echo [%date% %time%] : $FolderPath$\$AddKey$\$FileName$.ts>> %MOVE_HISTRY_FILE%
    if %CONV_TS% equ 1 (
        call %TS_TO_MP4_BAT% "$FolderPath$\$AddKey$\$FileName$.ts"
    )
)

endlocal

EDCBで、設定-動作設定タブ-全般タブの右下の録画プリセットボタンを押す。
上記のts_move.batを、録画実行batに指定。
これで、次回の新規予約からはこのbatが実行されるはず。

ちなみにいまある予約のやつは1個1個、手作業でこのbatを追加しないといけません。
私はめんどうなので、settingフォルダにあるReserve.txtを直接書き換えて再起動させました。
また、今までの自動予約キーワードの設定も、このbatは指定されていないので、手作業で追加するか、EpgAutoAdd.txtを直接書き換えるかしないとなりません。
詳しい人は直接のほうが楽だけど、ファイルを壊したら面倒なので手作業をオススメします。

HandBrakeの設定

HandBrakeのGUI版と、CLI版を入手してインストール。

CLI版はこっち。
CLI版はzipを解凍して、任意のフォルダに入れておく。
GUI版の方で、自分が使うMP4変換プリセットを新規に作っておく。
別に既存のプリセットで良ければわざわざプリセットを新規に作らなくてもOK。

次に変換bat。
いろいろな人のbatを参考にさせてもらったので、いろんな技が混ざってます。
このbatは、ファイルを複数指定してもOKだし、batにドラッグアンドドロップしてもたぶん大丈夫だと思う。
このbatを、HandBrakeCLIのフォルダに入れておく。
ファイル先頭あたりの設定は自分の環境に変えてください。
私はnVidiaのカード使ってるので、NVEnc使ったプリセット作って、それを指定してます。

@echo off
REM ========= HandBrakeCLI を使った自動エンコードスクリプト =========
REM 使い方 encode_handbrake.bat "ファイル名1" "ファイル名2" ....

rem 遅延変数を無効化すると、たまに!!が入ったファイル名があると、遅延変数と解釈されてファイル名が異なる場合があるのでやめた
REM setlocal enabledelayedexpansion
setlocal

REM バッチのパラメーター置換詳細がのっている
REM https://qiita.com/tomotagwork/items/5b9e08f28d5925d96b5f

rem HandBrakeGUI版で、プリセットを保存しておいて、そのプリセット名。
set HANDBRAKE_GUI_PRESET_NAME="TStoMP4_NVEnc"

rem set FPS=30

rem ファイルの一時待避所
set TEMP_FOLDER_NAME=temp
rem tempフォルダで、tsファイルをrenameしたときに、どうrenameしたかテキスト保存。もし、途中で止まってもあとで元の名前に直す用。
set CONVERT_INFO_SAVEFILENAME=org_filename.txt
rem 上記のファイルを処理が終わったら消すか 0:消さない 1:消す
set Delete_Tmp_Output_Name=0


rem %~dp0 batのフォルダ
cd /d %~dp0

REM HandBrakeCLIの場所とAUCの場所を指定する。デフォルトはバッチファイルと同じ場所。
set HandBrakeCLI_DIR=%~dp0
set HandBrakeCLI="%HandBrakeCLI_DIR%HandBrakeCLI.exe"

set PROFILE_NO=0

set COUNT=0
set OLD_INPUT_FILE=""

:start

echo ========================================================================================
echo ========================================================================================
echo ========================================================================================

set /a COUNT+=1
IF "%~1" == "" GOTO END

set ORIGINAL_FOLDER=%~dp1
IF NOT EXIST "%ORIGINAL_FOLDER%" (
    echo ORIGINAL_FOLDER : %ORIGINAL_FOLDER% の指定がおかしい??
    echo フォルダが存在ません。終了します。
    GOTO END
)


rem tsファイルのフルパス
set INPUT_FILE=%1
rem tsファイルのファイル名部分のみ(拡張子なし)
set ORIGINAL_FILENAME=%~n1
rem tsファイルのファイル名+拡張子
set ORIGINAL_FILENAME_ALL="%~nx1"

set ORIGINAL_FILE_EXT_temp=%~x1
rem 上記のORIGINAL_FILE_EXT_tempはドットも含まれるので抜いたものをsetしておく
set ORIGINAL_FILE_EXT=%ORIGINAL_FILE_EXT_temp:~1%
rem 最終的に出力するmp4のファイル名+拡張子
set OUTPUT_FILENAME_ALL="%ORIGINAL_FILENAME%.mp4"
rem 最終的に出力するmp4のパス+ファイル名+拡張子
set OUTPUT_FILEPATH_AND_NAME_ALL="%ORIGINAL_FOLDER:"=%%OUTPUT_FILENAME_ALL:"=%"

rem 表示
echo 動画ファイルフォルダ : %ORIGINAL_FOLDER%
echo 入力ファイル %INPUT_FILE:"=%
echo 出力ファイル %OUTPUT_FILEPATH_AND_NAME_ALL:"=%

rem ループして戻ってきて、同じファイルだったら抜ける
IF %INPUT_FILE% == %OLD_INPUT_FILE% (
    set /a COUNT-=1
    GOTO END
)

set OLD_INPUT_FILE=%INPUT_FILE%

rem システム属性がついているとmoveできないのではずしておく
echo %~a1 | C:\Windows\System32\find.exe "s" > nul
if %errorlevel%==0 (
    echo システム属性がついています。
    set IS_SYSTEMFILE=1
    attrib -s %1
) else (
    set IS_SYSTEMFILE=0
)

rem 日本語ファイル名がHandBrake内部のライブラリで文字化けを起こしてしまうので、英語名に変更して、変換後にリネーム
rem tsのあるフォルダも日本語で文字化けするから、tempに移動させてから処理
set TEMP_FOLDER="%~d1\%TEMP_FOLDER_NAME%\"
echo 作業フォルダ : %TEMP_FOLDER%
IF NOT EXIST %TEMP_FOLDER% (
    mkdir %TEMP_FOLDER%
) else (
    echo 作業フォルダはすでに作成されています。
)
echo move : %INPUT_FILE% to %TEMP_FOLDER%
move %INPUT_FILE% %TEMP_FOLDER%
set TEMP_ORIGINAL_INPUT_FILEPATH_AND_NAME_ALL= "%TEMP_FOLDER:"=%%ORIGINAL_FILENAME_ALL:"=%"

set time2=%time: =0%
set time_str=%time2:~0,2%%time2:~3,2%%time2:~6,2%
rem 日本語を抜かすため、日付+時刻を一時ファイル名にする。
set TEMP_RENAME_FILENAME=%date:/=%_%time_str%
set TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL="%TEMP_FOLDER:"=%%TEMP_RENAME_FILENAME%.%ORIGINAL_FILE_EXT%"
set TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL="%TEMP_FOLDER:"=%%TEMP_RENAME_FILENAME%.mp4"

echo TEMP_ORIGINAL_INPUT_FILEPATH_AND_NAME_ALL : %TEMP_ORIGINAL_INPUT_FILEPATH_AND_NAME_ALL%
echo TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL : %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL%
echo TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL : %TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL%

rem 元ファイル名保存
echo %INPUT_FILE% "%TEMP_RENAME_FILENAME%.%ORIGINAL_FILE_EXT%">>%TEMP_FOLDER:"=%%CONVERT_INFO_SAVEFILENAME%

IF NOT EXIST %TEMP_ORIGINAL_INPUT_FILEPATH_AND_NAME_ALL% (
    echo tempにtsファイルがありません。
    GOTO ERROR_PROC
)

echo ファイル名を変更します。
echo rename処理 %TEMP_ORIGINAL_INPUT_FILEPATH_AND_NAME_ALL% to %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL%
rename %TEMP_ORIGINAL_INPUT_FILEPATH_AND_NAME_ALL% %TEMP_RENAME_FILENAME%%~x1

echo HandBrakeCLIを起動し、エンコードを開始します ( %COUNT%回目 )

REM "%HandBrakeCLI%" --preset-import-file preset.json --preset %HANDBRAKE_GUI_PRESET_NAME% -i %INPUT_FILE% -o %OUTPUT_FILEPATH_AND_NAME_ALL% -f mp4
"%HandBrakeCLI%" --preset-import-gui --preset %HANDBRAKE_GUI_PRESET_NAME% -i %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL% -o %TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL% -f mp4
REM "%HandBrakeCLI%" -i %INPUT_FILE% -o %OUTPUT_FILEPATH_AND_NAME_ALL% -f mp4 -e nvenc_h264 -q 23.5 --crop 0:0:0:0 -w 1440 -l 1080 --cfr -r %FPS% --multi-pass

echo error_level = %errorlevel%

rem rem HandBrakeCLIの戻り値 CTrl+cで終了:-1073741510   encode成功 : 0
IF %errorlevel% neq 0 GOTO ERROR_PROC
IF EXIST %TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL% (
    GOTO OUTPUT_FILE_EXIST
) ELSE (
    GOTO OUTPUT_FILE_NOT_EXIST
)

:ERROR_PROC
echo -------------------------------------------------------------------------------
echo HandBrakeCLIが異常終了しています。TSファイルを元の位置に戻してバッチ終了します。
echo -------------------------------------------------------------------------------
echo rename処理 %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL% to %ORIGINAL_FILENAME%.%ORIGINAL_FILE_EXT%
rename %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL% %ORIGINAL_FILENAME_ALL%
echo 元のフォルダに移動 to %ORIGINAL_FOLDER%
move "%TEMP_FOLDER:"=%%ORIGINAL_FILENAME_ALL:"=%" "%ORIGINAL_FOLDER%"
if %Delete_Tmp_Output_Name%==1 (
    del "%TEMP_FOLDER:"=%%CONVERT_INFO_SAVEFILENAME%"
)
del %TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL%

set OLD_INPUT_FILE=%INPUT_FILE%
echo %~0 バッチ抜けます
rem ここでendlocal入れとかないと、exit /b でerrorlevelが反映されない。
endlocal
exit /b 1

:OUTPUT_FILE_EXIST
ECHO 出力ファイルが見つかりました。元ファイルを削除します。
echo del : %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL%
del /a %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL%
echo rename処理 %TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL% to %ORIGINAL_FILENAME%.mp4
rename %TEMP_RENAME_OUTPUT_FILEPATH_AND_NAME_ALL:"=% "%ORIGINAL_FILENAME%.mp4"
echo 元のフォルダに移動 to %ORIGINAL_FOLDER%
move "%TEMP_FOLDER:"=%%ORIGINAL_FILENAME%.mp4" "%ORIGINAL_FOLDER%"
set OLD_INPUT_FILE=%INPUT_FILE%
if %Delete_Tmp_Output_Name%==1 (
    del "%TEMP_FOLDER:"=%%CONVERT_INFO_SAVEFILENAME%"
)
if %IS_SYSTEMFILE%==1 (
    echo システム属性付きです。出力ファイルもシステム属性にします。
    attrib +s %OUTPUT_FILEPATH_AND_NAME_ALL%
) else (
    echo システム属性なし
)
GOTO shiftprosess

:OUTPUT_FILE_NOT_EXIST
ECHO 出力ファイルが見つかりません。
echo rename処理 %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL% to %ORIGINAL_FILENAME_ALL%
rename %TEMP_RENAME_INPUT_FILEPATH_AND_NAME_ALL% %ORIGINAL_FILENAME_ALL%
echo 元のフォルダに移動 to %ORIGINAL_FOLDER%
move "%TEMP_FOLDER:"=%%ORIGINAL_FILENAME_ALL:"=%" "%ORIGINAL_FOLDER%"
if %Delete_Tmp_Output_Name%==1 (del "%TEMP_FOLDER:"=%%CONVERT_INFO_SAVEFILENAME%")
GOTO shiftprosess

:shiftprosess
echo 次のファイルへ移ります。
rem shiftで引数をずらす
SHIFT
GOTO start

:END
rem echo 全 %COUNT% ファイルのエンコードを終了しました
echo 全ファイルのエンコードを終了しました
endlocal
exit /b 0

まとめ

これで、自動予約録画されるたびに、自動で変換してくれます。
スマホや車のナビに移動させるのも楽ちん。

最初、AviUtilでやろうとしてました。
TSファイルを開くときに開き終わるまで待機するプログラムをWin32コンソールで作ってまでやってみたんだけど、音ズレの問題が面倒で、調べたらHandBrakeがあったわけです。だいぶ前にインストールしてあった。
こっちの方が最初からCLI版もあるし、プリセットもGUIで簡単に変えられるから、めちゃ楽。オススメ。
それにしてもbatって今更ながら勉強したけど、デバッグがとてもめんどい。

おまけ

今まで録り溜めたTSファイルも一括で変換したかったので、それ用のbatも作成しました。
今もこれで変換中。
大量にあるので、いつ終わるのかわからない・・・

使い方は、このバッチはHandBrakeCLIと同じフォルダに置いて、

enc_all.bat "G:\TV\"

これで G:\TV\ 内のTSは全てMP4に変換されます。
上でsetしているHandbrakeCLIのフォルダ名は書き換えてください。

@echo off
setlocal enabledelayedexpansion
rem 使い方 enc_all.bat "G:\TV\"

set HANDBRAKE_CLI= "C:\Tools\Moves\HandBrake\encode_handbrake.bat"

IF not EXIST %1 (
echo フォルダが見つかりません。%1
goto end_proc
)

set "folder=%1"

for /r "%folder%" %%f in (*.ts) do (
  echo %%f
  call %HANDBRAKE_CLI% "%%f"
  
  echo error_level = !errorlevel!
    
  if !errorlevel! neq 0 (
    echo === 全ファイルエンコード 終了します ===
    goto end_proc
  )
)

:end_proc
endlocal

では、よいTVライフを!
私は録り溜めてるだけで全然見れてません!!

サポートしていただけると励みになります。 頂いたサポートは有益な他の方のnote購入代に当てさせて頂き、回していきたいと思います。