前提
社内向けに撮影した動画を変換する必要があり、今まではAWSのElastic Transcoderを使用していたのだが、利用料金がかかるし、変換対象の動画ファイルが増えてくると1つ1つGUIで操作しながらやっていくのがなかなかにしんどいし地味に時間が掛かる。
どうにかできないか調べていたらffmpegコマンドを使用した動画変換方法を見つけたので検証がてら行ってみた。
FFmpegとは
動画と音声を記録・変換・再生するためのフリーソフトウェアである。(Wikipediaより)
やりたいこと
mp4形式の動画ファイルをHLS形式に変換したい
環境
WindowsのWSL2を使ってUbuntu20.04をインストールし、コマンドでFFmpegを操作することにする。
なお、Ubuntuのインストール手順は割愛する。
- Windows 11
- WSL2
- Ubuntu 20.04
FFmpegインストール
苦戦した方もいるようだが私は以下コマンドですんなりインストール出来た。
sudo apt-get update
sudo apt install ffmpeg
mp4形式からHLS形式に変換する
このようなコマンドでinput.mp4
が、インデックスファイルoutput.m3u8
、セグメントファイルoutput-NNN.ts
にそれぞれ分割される。
ffmpeg -i input.mp4 -c:v copy -c:a copy -f hls -hls_time 10 -hls_playlist_type vod -hls_segment_filename "output-%3d.ts" output.m3u8
意識すべきオプションは以下。
-i
:入力ファイル名
-hls_time
:1セグメントファイルの秒数
-hls_segment_filename
:セグメントファイル名(%3d
には連番が入る)
実際にコマンドを実行すると、このような結果になる。
$ ffmpeg -i input.mp4 -c:v copy -c:a copy -f hls -hls_time 10 -hls_playlist_type vod -hls_segment_filename "output-%3d.ts" output.m3u8
ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
configuration: --prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41
creation_time : 2023-04-14T03:38:01.000000Z
Duration: 00:07:52.49, start: 0.000000, bitrate: 2092 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 1931 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc (default)
Metadata:
creation_time : 2023-04-14T03:38:01.000000Z
handler_name : ?Mainconcept Video Media Handler
encoder : AVC Coding
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 157 kb/s (default)
Metadata:
creation_time : 2023-04-14T03:38:01.000000Z
handler_name : #Mainconcept MP4 Sound Media Handler
[hls @ 0x55e966ff81c0] Opening 'output-000.ts' for writing
Output #0, hls, to 'output.m3u8':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42mp41
encoder : Lavf58.29.100
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 1931 kb/s, 25 fps, 25 tbr, 90k tbn, 25 tbc (default)
Metadata:
creation_time : 2023-04-14T03:38:01.000000Z
handler_name : ?Mainconcept Video Media Handler
encoder : AVC Coding
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 157 kb/s (default)
Metadata:
creation_time : 2023-04-14T03:38:01.000000Z
handler_name : #Mainconcept MP4 Sound Media Handler
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[hls @ 0x55e966ff81c0] Opening 'output-001.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-002.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-003.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-004.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-005.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-006.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-007.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-008.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-009.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-010.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-011.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-012.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-013.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-014.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-015.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-016.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-017.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-018.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-019.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-020.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-021.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-022.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-023.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-024.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-025.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-026.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-027.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-028.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-029.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-030.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-031.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-032.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-033.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-034.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-035.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-036.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-037.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-038.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-039.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-040.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-041.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-042.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-043.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-044.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-045.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-046.ts' for writing
[hls @ 0x55e966ff81c0] Opening 'output-047.ts' for writing
frame=11811 fps=0.0 q=-1.0 Lsize=N/A time=00:07:52.42 bitrate=N/A speed=2.53e+03x
video:111382kB audio:9076kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
$ ls
input.mp4 output-003.ts output-007.ts output-011.ts output-015.ts output-019.ts output-023.ts output-027.ts output-031.ts output-035.ts output-039.ts output-043.ts output-047.ts
output-000.ts output-004.ts output-008.ts output-012.ts output-016.ts output-020.ts output-024.ts output-028.ts output-032.ts output-036.ts output-040.ts output-044.ts output.m3u8
output-001.ts output-005.ts output-009.ts output-013.ts output-017.ts output-021.ts output-025.ts output-029.ts output-033.ts output-037.ts output-041.ts output-045.ts
output-002.ts output-006.ts output-010.ts output-014.ts output-018.ts output-022.ts output-026.ts output-030.ts output-034.ts output-038.ts output-042.ts output-046.ts
まとめ
FFmpegでmp4をHLS形式に変換する方法を紹介した。
今回紹介したコマンドを、変換対象のファイル数分繰り返すようなシェルスクリプトを組めば、コマンドを1発叩くだけで目的の動画ファイルが出来上がる。