動画ファイルを右クリックメニューからH.265エンコードできるようにする
題名のとおりですが、Windows上で動画ファイルをH.265エンコードするバッチファイルを作って、shell:sendtoに登録するだけのお話です。
実際やることは上の1行だけなので、大した話ではないのですが、コマンドラインオプションの順番を間違えただけで「Unknown decoder 'libx265'」というエラーが出て混乱したりするため、備忘録として残しておこうかな、と思いました。
ffmpegのダウンロード
コマンドラインで動画エンコードする必要があるため、下記ページからffmpegをDLします。
https://www.gyan.dev/ffmpeg/builds/#release-builds
Full版にはすべてのコーデックが含まれていますが、使いたいのはH.265だけなので、DLするのはEssentials版(ffmpeg-release-essentials.7z)でOK。
バッチファイルの作成
テキトーなテキストエディタ(メモ帳でも可)で下記のようなバッチファイルを書き、h265.batのような名前で保存します。
@echo off cd /d %~dp1 ffmpeg -i %1 -c:a copy -c:v libx265 -crf 28 -tag:v hvc1 "%~n1_h265.mp4" pause
1行目の cd /d %~dp1 では、バッチファイルの引数に渡されたファイルがあるディレクトリへ移動しています。
例えば、h265.bat D:\Video\test.mp4 みたいな感じで実行されたとしたら、カレントドライブをDドライブへ、カレントディレクトリを \Video へ移動して、そこで作業するって意味ですね。
もちろんわざわざ引数にファイル名を手打ちしなくとも、バッチファイルに動画ファイルをドラック&ドロップするだけでも良いし、冒頭で述べたとおり、shell:sendtoにバッチファイルを置き、右クリックメニューから動画ファイルを送るようにしても同じ動作になります。
2行目はffmpegの実行コマンド。DLしたffmpegは適当なディレクトリへ展開(解凍)して、パスを通しても良いし、フルパスで書いても良いです。
(例えば C:\Apps\ffmpeg へ解凍したのなら、C:\Apps\ffmpeg\bin\ffmpeg ~ほにゃらら~ でも可)
-i | 変換元の動画ファイル |
-c:a copy | 音声はエンコードせずそのままコピーするという意味 |
-c:v libx265 | 動画エンコードにH.265(HEVC)を使う |
-crf 28 | CRF (Constant Rate Factor:品質) を28に設定 |
-tag:v hvc1 | hvc1というタグを付ける(これがないとiOS11以降で再生できないらしい) |
CRFについてはどこまで妥協するかにも依りますが、28くらいがH264とほとんど見分けがつかないギリギリのラインではないか、と言われています。ずっと綺麗に保存しておきたい大事な動画などの場合はもっと低い16あたりを指定する人もいます。(数値が低いほど高品質でファイルサイズが大きくなる)
尚、出力する動画ファイル名は元のファイル名の後ろに _h265 を付けるようにしています。test.mp4を渡したとしたら、test_h265.mp4というファイルが出来上がるわけです。
Unknown decoder 'libx265'が出る場合は引数の順番が違うかも
冒頭でもチラっと書きましたが、ffmpegのコマンドラインオプションの順番を間違えると「Unknown decoder 'libx265'」というエラーが出る場合があります。そしてこのエラーメッセージでググると「H.265コーデックがないからソースからコンパイルしてうんたらかんたら」なんて記事がひっかかる場合もありますが、んなこたぁ~ないので、コンパイルなんてわかんねーよぉぉ~とビビる必要はありません。
先述したURLからDLした場合はEssential版だろうがFull版だろうが、ちゃんとlibx265は含まれています。
しかし、ffmpegの実行時に、上で書いたバッチファイルを独自に見やすくしようとして、例えば、↓こんなふうに書いてしまった場合。
ffmpeg -c:a copy -c:v libx265 -crf 28 -tag:v hvc1 -i %1 "%~n1_h265.mp4"
これだと「Unknown decoder 'libx265'」というエラーが出ます。-iオプションは後ろに書いたほうが処理が早くなる、なんて記事もあるので、こういう書き方してしまいがちですが、コーデックの指定は-iオプションの後じゃないとダメっぽいですね。しっかり検証したわけではありませんが、最初の例のとおり、
ffmpeg -i %1 -c:a copy -c:v libx265 -crf 28 -tag:v hvc1 "%~n1_h265.mp4"
この順番なら問題ないので、「Unknown decoder 'libx265'」が表示された場合にはコマンドラインオプションの順番を確認してみましょう。
バッチファイルをshell:sendtoへ登録
エクスプローラーのアドレスバーに「shell:sendto」と入力するか、%APPDATA%\Microsoft\Windows\SendToを開くか、どちらでも良いのですが…
要は C:\Users\[ユーザー名]\AppData\Roaming\Microsoft\Windows\SendTo ディレクトリを開いて、そこに先ほど作ったバッチファイル(h265.bat)を置きます。
バッチファイル本体を置くのが気持ち悪ければ、ショートカットでも良いです。
すると、下記のとおり、右クリックメニューの[送る]宛先にh265(もしくはh265.bat)が追加されるハズ。
これで、動画ファイルを右クリックして、[送る]メニューからh265を選ぶだけでH.265へエンコードできるようになりました。
実際のH.265変換例
変換例に用いるのは1080p/60fpsの8分27秒のゲーム動画。
HITMANというゲームをプレイして、OBS Studioで録画したものです。ファイルサイズは約376MB。
これを先ほどのh265.batで変換すると、だいたいこんなような画面が出るはずです。
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'hitman_27クラブ_サイレントアサシン.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf59.16.100 Duration: 00:08:27.76, start: 0.000000, bitrate: 6218 kb/s Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 5950 kb/s, 59.94 fps, 59.94 tbr, 60k tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 255 kb/s (default) Metadata: handler_name : SoundHandler vendor_id : [0][0][0][0] Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> hevc (libx265)) Stream #0:1 -> #0:1 (copy) Press [q] to stop, [?] for help x265 [info]: HEVC encoder version 3.5+37-07b011400 x265 [info]: build info [Windows][GCC 11.2.0][64 bit] 8bit+10bit+12bit x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 x265 [info]: Main profile, Level-4.1 (Main tier) x265 [info]: Thread pool created using 12 threads x265 [info]: Slices : 1 x265 [info]: frame threads / pool features : 3 / wpp(17 rows) x265 [info]: Coding QT: max CU size, min CU size : 64 / 8 x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra x265 [info]: ME / range / subpel / merge : hex / 57 / 2 / 3 x265 [info]: Keyframe min / max / scenecut / bias : 25 / 250 / 40 / 5.00 x265 [info]: Lookahead / bframes / badapt : 20 / 4 / 2 x265 [info]: b-pyramid / weightp / weightb : 1 / 1 / 0 x265 [info]: References / ref-limit cu / depth : 3 / off / on x265 [info]: AQ: mode / str / qg-size / cu-tree : 2 / 1.0 / 32 / 1 x265 [info]: Rate Control / qCompress : CRF-28.0 / 0.60 x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip mode=1 signhide tmvp x265 [info]: tools: b-intra strong-intra-smoothing lslices=6 deblock sao Output #0, mp4, to 'hitman_27クラブ_サイレントアサシン_h265.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf59.25.100 Stream #0:0(und): Video: hevc (hvc1 / 0x31637668), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 59.94 fps, 60k tbn (default) Metadata: handler_name : VideoHandler vendor_id : [0][0][0][0] encoder : Lavc59.34.100 libx265 Side data: cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 255 kb/s (default) Metadata: handler_name : SoundHandler vendor_id : [0][0][0][0] frame=30434 fps= 45 q=39.0 Lsize= 170082kB time=00:08:27.75 bitrate=2744.1kbits/s speed=0.758x video:153448kB audio:15819kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: 0.481707% x265 [info]: frame I: 126, Avg QP:28.53 kb/s: 23786.34 x265 [info]: frame P: 10219, Avg QP:31.32 kb/s: 5718.29 x265 [info]: frame B: 20089, Avg QP:37.70 kb/s: 689.78 x265 [info]: Weighted P-Frames: Y:7.9% UV:4.5% x265 [info]: consecutive B-frames: 15.7% 24.6% 12.2% 44.8% 2.8% encoded 30434 frames in 669.93s (45.43 fps), 2473.85 kb/s, Avg QP:35.52 続行するには何かキーを押してください . . .
元の動画ファイルはH.264で、30434フレーム。H.265への変換には669.93秒かかりました。約11分。元が8分27秒の動画ですから、再生時間よりも少し長いくらいのエンコード時間がかかっていますね。
ちなみに実行したPCははIntel第10世代のCore i5 10400を搭載した自作PC。ビデオカードも搭載していますが、ハードウェアエンコードは使っていません。 (ソフトウェアエンコードのほうが綺麗なため)
ファイルサイズは約376MBから約166MBへ、元と比べて約44%のサイズになりました。半分以下です。
まとめ
H.265エンコードするためのバッチファイルを作って、shell:sendtoに登録するだけの話のわりには長くなってしまいましたが、ffmpegのオプションの順番など、ハマるとわけもわからずエラーが出て困る場面もあるかと思ったので、備忘録代わりに記事にしてみました。
H.265のエンコードにはマシンパワーをかなり使い、時間もかかりますが、CPU性能は年々上がっていますし、多少品質を妥協できるなら、Intel QSVを使ったり、グラボのハードウェアエンコード機能を使うことで劇的に(10倍以上)高速化することも可能です。
そんなわけで、近い将来、H.264の動画はすべてH.265(HEVC)になると思うのですが、そのわりにいまいち使い勝手の良いツールがないような気も。UI付きだとHandBrakeあたりが手軽っちゃ手軽なのかなぁ。個人的にはUIで操作するのって手間がかかるので、バッチファイルでポチっとできる今回のような仕組みのほうが好みですけども。
いずれにせよ、右クリックメニューからポチっと一発でH.265変換できるようになって以来、ゲームプレイの動画等、すぐにコンパクトにできるようになったので、とても使い勝手が良くなりました。
この記事が動画ファイルを溜め込んでいる方の参考になれば幸いです。