Skip to content

MP4からM3U8チュートリアル:FFmpeg HLSスライスとAES-128暗号化

MP4をHLSストリームに変換したい?ウェブ用にビデオを最適化したい?コンテンツを暗号化で保護したい?FFmpegを使えばこれらすべてが可能です。このチュートリアルでは、HLSスライスから暗号化、配信までをカバーします。

HLSの基礎

HLS(HTTP Live Streaming)はAppleが開発したストリーミングプロトコルです:

  • HTTPベース:標準HTTPサーバーで配信可能
  • アダプティブビットレート:ネットワーク状況に応じて品質を自動切り替え
  • セグメント化:ビデオを小さなTSセグメントに分割
  • M3U8プレイリスト:セグメントの索引

HLSの動作原理

  1. ビデオエンコード:H.264ビデオ + AACオーディオ
  2. セグメント分割:2-10秒のTSセグメントに分割
  3. M3U8生成:セグメントURLのリスト
  4. クライアント再生:M3U8を解析、セグメントを順次ダウンロード

HLSの仕組みについて詳しくは、M3U8ファイル完全ガイド をご覧ください。

基本的なHLSスライス

インストール

bash
# macOS
brew install ffmpeg

# Ubuntu/Debian
sudo apt install ffmpeg

基本コマンド

bash
# MP4をHLSに変換(ストリームコピー、品質ロスなし)
ffmpeg -i input.mp4 -c copy -f hls -hls_time 6 -hls_playlist_type vod -hls_segment_filename "segment_%03d.ts" playlist.m3u8

パラメータ解説:

  • -i input.mp4:入力ファイル
  • -c copy:ストリームを直接コピー(再エンコードなし)
  • -f hls:HLSフォーマット出力
  • -hls_time 6:各セグメント6秒
  • -hls_playlist_type vod:VOD用プレイリスト
  • -hls_segment_filename "segment_%03d.ts":セグメント命名パターン
  • playlist.m3u8:出力M3U8ファイル

再エンコードが必要な場合

bash
# H.264に再エンコード
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac -b:a 128k -f hls -hls_time 6 -hls_segment_filename "segment_%03d.ts" playlist.m3u8

AES-128暗号化

暗号化キーの生成

bash
# 16バイトの暗号化キーを生成
openssl rand 16 > enc.key

# 16バイトのIVを生成
openssl rand -hex 16

キー情報ファイルの作成

text
# key_info.txt
Key URI: https://example.com/enc.key
Path to key: enc.key
IV: 0x1234567890abcdef1234567890abcdef
  • Key URI:視聴者がアクセスするキーURL
  • Path to key:ローカルキーファイルパス
  • IV:初期化ベクトル(16進数、オプション)

暗号化HLSの生成

bash
ffmpeg -i input.mp4 -c copy -f hls -hls_time 6 -hls_key_info_file key_info.txt -hls_segment_filename "segment_%03d.ts" playlist.m3u8

生成されるM3U8:

text
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI="https://example.com/enc.key",IV=0x1234567890abcdef1234567890abcdef
#EXTINF:6.000000,
segment_000.ts
#EXTINF:6.000000,
segment_001.ts
...
#EXT-X-ENDLIST

アダプティブビットレート(ABR)

複数品質の生成

bash
# 360p
ffmpeg -i input.mp4 -c:v libx264 -b:v 800k -s 640x360 -c:a aac -b:a 128k -f hls -hls_time 6 -hls_segment_filename "360p/segment_%03d.ts" 360p.m3u8

# 720p
ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -s 1280x720 -c:a aac -b:a 128k -f hls -hls_time 6 -hls_segment_filename "720p/segment_%03d.ts" 720p.m3u8

# 1080p
ffmpeg -i input.mp4 -c:v libx264 -b:v 4000k -s 1920x1080 -c:a aac -b:a 128k -f hls -hls_time 6 -hls_segment_filename "1080p/segment_%03d.ts" 1080p.m3u8

マスターM3U8の作成

text
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4000000,RESOLUTION=1920x1080
1080p.m3u8

FFmpegでマスターM3U8を自動生成

bash
ffmpeg -i input.mp4 \
  -c:v libx264 -b:v:0 800k -s:v:0 640x360 \
  -b:v:1 2000k -s:v:1 1280x720 \
  -b:v:2 4000k -s:v:2 1920x1080 \
  -c:a aac -b:a 128k \
  -f hls -hls_time 6 \
  -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" \
  -master_pl_name master.m3u8 \
  -hls_segment_filename "v%v/segment_%03d.ts" \
  "v%v.m3u8"

ライブストリーミング用HLS

bash
# ライブストリーミング用HLS
ffmpeg -i input.mp4 -c:v libx264 -preset veryfast -c:a aac -f hls -hls_time 2 -hls_list_size 3 -hls_flags delete_segments+append_list -hls_segment_filename "live_%03d.ts" live.m3u8

パラメータ:

  • -hls_time 2:2秒セグメント(低遅延)
  • -hls_list_size 3:M3U8に最新3セグメントのみ保持
  • -hls_flags delete_segments+append_list:古いセグメントを削除、新しいセグメントを追加

Nginx配信設定

nginx
server {
    listen 80;
    server_name example.com;
    
    location /hls/ {
        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
        root /var/www;
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control no-cache;
    }
    
    location /key/ {
        # キーアクセス制限(オプション)
        # allow 192.168.0.0/16;
        # deny all;
        root /var/www;
    }
}

よくある問題

問題原因解決策
セグメントが長すぎる-hls_timeが大きい2-6秒に設定
M3U8が更新されないVODモード使用eventまたはライブモード使用
古いセグメントが残るdelete_segmentsフラグなし-hls_flags delete_segments追加
暗号化キーアクセス失敗CORS問題NginxにCORSヘッダー追加
Safariで再生できないCODEC互換性H.264 + AAC使用
レイテンシが高い通常のHLSLL-HLSまたはDASH使用

まとめ

HLSスライスの基本:

bash
# 基本コマンド
ffmpeg -i input.mp4 -c copy -f hls -hls_time 6 -hls_segment_filename "segment_%03d.ts" playlist.m3u8

# 暗号化付き
ffmpeg -i input.mp4 -c copy -f hls -hls_time 6 -hls_key_info_file key_info.txt -hls_segment_filename "segment_%03d.ts" playlist.m3u8

クイックリファレンス:

  • 基本スライス: -f hls -hls_time 6
  • 暗号化: -hls_key_info_file key_info.txt
  • ライブ: -hls_flags delete_segments+append_list
  • ABR: -var_stream_map + -master_pl_name

参考文献

最終更新: