Ubuntu20.04でFFmpegを使ってmp4をHLSに変換する

# 前提
社内向けに撮影した動画を変換する必要があり、今まではAWSのElastic Transcoderを使用していたのだが、利用料金がかかるし、変換対象の動画ファイルが増えてくると１つ１つGUIで操作しながらやっていくのがなかなかにしんどいし地味に時間が掛かる。
どうにかできないか調べていたらffmpegコマンドを使用した動画変換方法を見つけたので検証がてら行ってみた。

# FFmpegとは
動画と音声を記録・変換・再生するためのフリーソフトウェアである。（Wikipediaより）

# やりたいこと
mp4形式の動画ファイルをHLS形式に変換したい

# 環境
WindowsのWSL2を使ってUbuntu20.04をインストールし、コマンドでFFmpegを操作することにする。
なお、Ubuntuのインストール手順は割愛する。

- Windows 11
- WSL2
- Ubuntu 20.04

# FFmpegインストール
苦戦した方もいるようだが私は以下コマンドですんなりインストール出来た。
```bash
sudo apt-get update
sudo apt install ffmpeg
```

# mp4形式からHLS形式に変換する
このようなコマンドで``input.mp4``が、インデックスファイル``output.m3u8``、セグメントファイル``output-NNN.ts``にそれぞれ分割される。

```bash
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``には連番が入る）


実際にコマンドを実行すると、このような結果になる。

```bash
$ 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発叩くだけで目的の動画ファイルが出来上がる。