どうも、じゃぶじゃぶ(@jbjbgame)です。
前回、FFmpegとWindowsバッチを組み合わせて、動画の一括エンコードバッチのプロトタイプを作成しました。
今回は作成したバッチに改良を加えて、FFmpegのオプションを指定可能にした完成版のバッチを作りたい思います。
完成版バッチの作成
指定可能オプション
指定可能なオプションとして、画像圧縮に必要なものに絞って以下の5つにしました。
| オプション | 概要 | 例 |
| -i [ファイル名] | 圧縮するファイル名を指定 | - i C:\sample\input.mp4 |
| -b:v [ビットレート数(kbps)] | 映像のビットレート数を指定 | -b:v 1200k |
| -r [フレームレート数(fps)] | 動画のフレームレートを指定 | -r 120 |
| -s [サイズ(横ピクセルx縦ピクセル)] ※縦と横の間はx(小文字エックス) |
動画のサイズを指定 | -s 1980x1080 |
| -vcodec [コーディック] | コーディックの指定 | -vcodec libx264 または -vcodec libx265 |
さらに、圧縮対象の画像の種類(拡張子)も選択できるようにして、MP4形式以外の動画も圧縮できるようにいしたいと思います。
オプションの指定方法としては、対話式を使ってバッチ実行時にオプションを1つずつ指定する感じにします。
ソースコード
( ;^ー^)>
かなり自己満足なものになっていますが、最終的な完成版は以下の感じになりました。
ffmpeg-batch-encoding2.bat
@echo off
rem ***************************************
rem 処理名:動画一括圧縮処理 (FFmpeg)
rem 作成日:2020/08/09
rem 更新日:2020/08/09
rem 作成者: じゃぶじゃぶ
rem
rem ***************************************
rem ------------------------------
rem ffmpegの出力オプションの初期値を設定 (※変更可)
rem オプションを指定しない場合は、イコール後に空欄を設定
rem ------------------------------
rem 圧縮する対象があるフォルダを指定(デフォルト:C:\sample\)
set INPUT_FOLDER=
rem コーディックを指定(例:libx264)
set CODEC=
rem ビットレートを指定(例:640k)
set BIT_RATE=
rem フレームレートを指定(例:120)
set FRAME_RATE=
rem サイズを指定(例:1280x720)
set SIZE=
rem 圧縮率を指定(例:10)
set COMPRESSION_RATE=
rem 圧縮対象の拡張子(例:mp4)
set EXTENSION=mp4
rem =========================================
rem ------------------------------
rem ↓↓↓↓ 以下 動画圧縮のメイン処理↓↓↓
rem ※変更厳禁!!
rem ------------------------------
rem ----対話式による出力パラメータの指定 ----
set /p PARAM="圧縮する対象フォルダは?(デフォルト:%INPUT_FOLDER%) :"
if not ""%PARAM%"" == """" (
set INPUT_FOLDER=%PARAM%
set PARAM=
)
set /p PARAM="コーディックをは?(例:libx264、またはlibx265 デフォルト:%CODEC%) :"
if not ""%PARAM%"" == """" (
set CODEC=%PARAM%
set PARAM=
)
set /p PARAM="ビットレートは?(例:640k デフォルト:%BIT_RATE%) :"
if not ""%PARAM%"" == """" (
set BIT_RATE=%PARAM%
set PARAM=
)
set /p PARAM="フレームレートは?(例:120 デフォルト:%FRAME_RATE%) :"
if not ""%PARAM%"" == """" (
set FRAME_RATE=%PARAM%
set PARAM=
)
set /p PARAM="サイズは?(例:1280x720 デフォルト:%SIZE%):"
if not ""%PARAM%"" == """" (
set SIZE=%PARAM%
set PARAM=
)
set /p PARAM="圧縮対象の拡張子は?(例:mp4 デフォルト:%EXTENSION%):"
if not ""%PARAM%"" == """" (
set EXTENSION=%PARAM%
set PARAM=
)
rem ---- 出力オプションの作成 ----
rem チェックフラグ
set CHEK_FLAG=T
rem 出力オプションの解析
set OUTPUT_OPTIONS=
rem 出力先オプションの有無確認
set CURRENT_DIRECTORY=%CD%
set baka=%CD%
if ""%INPUT_FOLDER%"" == """" (
rem カレントディレクトリを設定
set INPUT_FOLDER=%CD%
) else (
rem ディレクトリの有無確認
IF NOT EXIST "%INPUT_FOLDER%" (
set CHEK_FLAG=F
echo 圧縮対象のフォルダが存在しませんでした。(%INPUT_FOLDER%)
)
)
rem コーディックオプションの有無確認
if not ""%CODEC%"" == """" (
echo %CODEC% | find "libx26" >NUL
if NOT ERRORLEVEL 1 (
set OUTPUT_OPTIONS=%OUTPUT_OPTIONS% -vcodec %CODEC%
) ELSE (
set CHEK_FLAG=F
echo ”libx264、またはlibx265”で指定してください
)
)
rem ビットレートオプションの有無確認
if not ""%BIT_RATE%"" == """" (
echo %BIT_RATE% | find "k" >NUL
if NOT ERRORLEVEL 1 (
set OUTPUT_OPTIONS=%OUTPUT_OPTIONS% -b:v %BIT_RATE%
) ELSE (
set CHEK_FLAG=F
echo ”kb/s”で指定してください(例:1200k)
)
)
rem フレームレートオプションの有無確認
if not ""%FRAME_RATE%"" == """" (
set OUTPUT_OPTIONS=%OUTPUT_OPTIONS% -r %FRAME_RATE%
)
rem サイズオプションの有無確認
if not ""%SIZE%"" == """" (
echo %SIZE% | find "x" >NUL
if NOT ERRORLEVEL 1 (
set OUTPUT_OPTIONS=%OUTPUT_OPTIONS% -s %SIZE%
) ELSE (
set CHEK_FLAG=F
echo ”横ピクセルx縦ピクセル”で指定してください(例:1280x720)
)
)
rem 圧縮率オプションの有無確認
if not ""%COMPRESSION_RATE%"" == """" (
set OUTPUT_OPTIONS=%OUTPUT_OPTIONS% -crf %COMPRESSION_RATE%
)
rem 拡張子オプションの有無確認
if ""%EXTENSION%"" == """" (
set CHEK_FLAG=F
echo 圧縮する対象の拡張子を指定してください。
)
rem ----圧縮対象のフォルダから動画ファイルを抽出 ----
rem 出力先のフォルダの存在チェック
set OUTPUT_FOLDER=%INPUT_FOLDER%\comp\
set OUTPUT_FILE=%INPUT_FOLDER%\*.%EXTENSION%
if %CHEK_FLAG%==T (
if not exist "%OUTPUT_FOLDER%" (
echo 出力先フォルダが存在しなかったため作成(%OUTPUT_FOLDER%)
rem 出力先フォルダが存在しない場合は作成する
mkdir %OUTPUT_FOLDER%
)
setlocal enabledelayedexpansion
rem 出力先のファイル一覧を取得
for /f "usebackq" %%i in (`dir %OUTPUT_FILE% /B`) do (
for /f "usebackq tokens=1 delims=." %%x in (`echo %%i`) do (
rem ffmpegによる圧縮処理を実行
rem 実行するコマンドをコンソールに出力
rem 時間のスペースを0に置換
set tmptime=!time: =0!
echo ffmpeg -i %INPUT_FOLDER%\%%i %OUTPUT_OPTIONS% %OUTPUT_FOLDER%%%x_mini_!date:~0,4!!date:~5,2!!date:~8,2!!tmptime:~0,2!!tmptime:~3,2!!tmptime:~6,2!.%EXTENSION%
echo ....
ffmpeg -i %INPUT_FOLDER%\%%i %OUTPUT_OPTIONS% %OUTPUT_FOLDER%%%x_mini_!date:~0,4!!date:~5,2!!date:~8,2!!tmptime:~0,2!!tmptime:~3,2!!tmptime:~6,2!.%EXTENSION%
echo %%iの動画圧縮処理が完了しました。(時刻:!date! !time!)
echo ----------
)
)
endlocal
echo 圧縮処理が全て正常に完了しました。
) else (
echo オプションの指定に不備があったため、処理を中断しました。
)
rem ---- 初期化 ----
call :setting
pause >nul
rem -----------------------------
rem 環境変数の初期化処理
rem -----------------------------
:setting
rem 初期化処理
set INPUT_FOLDER=
set CODEC=
set BIT_RATE=
set FRAME_RATE=
set SIZE=
set COMPRESSION_RATE=
set EXTENSION=
set OUTPUT_OPTIONS=
set OUTPUT_FOLDER=
set OUTPUT_FILE=
set CHEK_FLAG=
set PARAM=
set CURRENT_DIRECTORY=
exit /b 1
バッチの使い方
基本的なバッチの作成方法や基本動作は前回の暫定版と同じなので、以下の記事を参考にしてください。
今回作成したバッチファイルを「D:\ffmpeg\bat」に配置し、圧縮対象の動画も同じファルダ内に配置して動作させてみます。

オプションを指定して実行
機能の違いとして、バッチをダブルクリックして実行した後に各種オプションを指定するところがあります。オプションは一つずつ順番に指定する仕様です。
作業フォルダを指定

圧縮する動画が配置してある作業フォルダを入力してください。上図のように「D:\ffmpeg」と入力してEnterキーを押すと、「D:\ffmpeg」内にある動画ファイルが圧縮対象になります。
何も指定しないでEnterキーを押すと、デフォルト値が対象になります。
コーディックの指定

コーディックを指定します。「libx264」か「libx265」のみ指定可能です。プログラム的には「libx26」が含まれていないと入力エラーにある仕様にしていますが、、、。
何も指定しないでEnterキーを押すと、デフォルト値が対象になります。
ビットレートの指定

ビットレートを指定します。入力値はkbps単位で指定してください。「k」という文字が無いと入力エラーになる仕組みにしています。
何も指定しないでEnterキーを押すと、デフォルト値が対象になります。
フレームレートの指定

フレームレートを指定します。入力値は数字で入力するようにしてください。
何も指定しないでEnterキーを押すと、デフォルト値が対象になります。
サイズの指定

動画サイズを指定します。入力形式は[横ピクセル]x[縦ピクセル]です。入力値に「x」がないと入力エラーになります。
何も指定しないでEnterキーを押すと、デフォルト値が対象になります。
圧縮する動画形式の指定

圧縮対象の動画形式を指定します。仕様の詳細としては、入力した文字(mp4など)の拡張子のファイルを検索するつくりになっています。
デフォルト値の設定

バッチファイルをテキストエディタで開いてみてください。15~28行目に各オプションのデフォルト値を設定できます。空欄にして、且つバッチ実行時にオプションを何も指定しないと、出力オプション無しでffmpegを実行します。
使用例
1.出力オプション無し
バッチファイルのデフォルト設定
rem ------------------------------ rem ffmpegの出力オプションの初期値を設定 (※変更可) rem オプションを指定しない場合は、イコール後に空欄を設定 rem ------------------------------ rem 圧縮する対象があるフォルダを指定(デフォルト:C:\sample\) set INPUT_FOLDER= rem コーディックを指定(例:libx264) set CODEC= rem ビットレートを指定(例:640k) set BIT_RATE= rem フレームレートを指定(例:120) set FRAME_RATE= rem サイズを指定(例:1280x720) set SIZE= rem 圧縮率を指定(例:10) set COMPRESSION_RATE= rem 圧縮対象の拡張子(例:mp4) set EXTENSION=mp4
実行時のパラメータ

FFmpegのコマンド
ffmpeg -i D:\ffmpeg\bat\2020071608414486.mp4 D:\ffmpeg\bat\comp\2020071608414486_mini_20200828023314.mp4
バッチファイルの設定をすべてブランク(空白)に設定した上で、バッチ実行時のパラメーターも何も指定しないと、出力オプション無しでFFmepgを実行するつくりになっています。
2.デフォルト設定あり
バッチファイルのデフォルト設定
rem ------------------------------ rem ffmpegの出力オプションの初期値を設定 (※変更可) rem オプションを指定しない場合は、イコール後に空欄を設定 rem ------------------------------ rem 圧縮する対象があるフォルダを指定(デフォルト:C:\sample\) set INPUT_FOLDER=D:\sample\ffmpeg rem コーディックを指定(例:libx264) set CODEC=libx264 rem ビットレートを指定(例:640k) set BIT_RATE=640k rem フレームレートを指定(例:120) set FRAME_RATE=120 rem サイズを指定(例:1280x720) set SIZE=1280x720 rem 圧縮率を指定(例:10) set COMPRESSION_RATE= rem 圧縮対象の拡張子(例:mp4) set EXTENSION=mp4
実行時のパラメータ

FFmpegのコマンド
ffmpeg -i D:\sample\ffmpeg\2020071608414486.mp4 -vcodec libx264 -b:v 640k -r 120 -s 1280x720 D:\sample\ffmpeg\comp\2020071608414486_mini_20200828024226.mp4
バッチファイルのデフォルト設定を以下のように設定しています。
- 圧縮する対象があるフォルダ⇒D:\sample\ffmpeg
- コーディック⇒libx264
- ビットレート⇒640k
- フレームレート⇒120
- サイズ⇒1280x720
- 圧縮率を指定⇒無し
- 圧縮対象の拡張子⇒mp4
バッチ実行にパラメーターを何も指定しいないので、バッチファイルに書かれた設定が適用されてFFmpegを実行しています。
3.実行時にパラメーターを指定
バッチファイルのデフォルト設定
rem ------------------------------ rem ffmpegの出力オプションの初期値を設定 (※変更可) rem オプションを指定しない場合は、イコール後に空欄を設定 rem ------------------------------ rem 圧縮する対象があるフォルダを指定(デフォルト:C:\sample\) set INPUT_FOLDER=D:\sample\ffmpeg rem コーディックを指定(例:libx264) set CODEC=libx264 rem ビットレートを指定(例:640k) set BIT_RATE=640k rem フレームレートを指定(例:120) set FRAME_RATE=120 rem サイズを指定(例:1280x720) set SIZE=1280x720 rem 圧縮率を指定(例:10) set COMPRESSION_RATE= rem 圧縮対象の拡張子(例:mp4) set EXTENSION=mp4
実行時のパラメータ

FFmpegのコマンド
ffmpeg -i D:\ffmpeg\bat\2020071608414486.mp4 -vcodec libx265 -b:v 1080k -r 60 -s 1280x720 D:\ffmpeg\bat\comp\2020071608414486_mini_20200828025114.mp4
バッチファイルの設定は例2と同じ設定になっていますが、バッチ実行にパラメータを指定することでそのパラメータが適用されてFFmpegが実行されています。
つまり、仕様をまとめると
- 実行時のパラメータが優先して適用される
- 実行パラメータが無い場合はバッチファイルのデフォルト設定が適用される
- 実行パラメータとバッチファイルの設定の両方が無い場合は出力オプション無しで実行
上記のような動きをします。
※注意!
今回制作したバッチは入力値をもとに、最終的にFFmpegのコマンドを作成して実行しているだけなので、予期せぬところでスペースが入るとエラーになります。
例えばファイル名にスペースが入るパターンです。
・動画ファイル␣01.mp4 (動画ファイルと01の間にスペースがある)
このファイル名でバッチを実行すると、
・ffmpeg -i D:\sample\ffmpeg動画ファイル␣01.mp4 動画ファイル␣01-mini-yyyymmdd.mp4
上記のようなコマンドになり「D:\sample\ffmpeg動画ファイル」というファイル名で動画を探しに行ってしまい、結果対象ファイルが存在しないためエラーで終了します。
まとめ
今回、やっと動画一括エンコードバッチを完成させることができました。
何回かに分けて投稿してきたffmpegシリーズも、今回で一旦終了です。
Windowsバッチを始めて触りましたが、仕様が全く分からない状態から初めて、いまでは大分使いこなせるところまで理解することができました!
今後も必要に応じて、面白そうなバッチのアイディアが思いついたら、積極的にWindowsバッチを使っていきたいと思います。
