MP4からM3U8チュートリアル:FFmpeg HLSスライスとAES-128暗号化
MP4をHLSストリームに変換したい?ウェブ用にビデオを最適化したい?コンテンツを暗号化で保護したい?FFmpegを使えばこれらすべてが可能です。このチュートリアルでは、HLSスライスから暗号化、配信までをカバーします。
HLSの基礎
HLS(HTTP Live Streaming)はAppleが開発したストリーミングプロトコルです:
- HTTPベース:標準HTTPサーバーで配信可能
- アダプティブビットレート:ネットワーク状況に応じて品質を自動切り替え
- セグメント化:ビデオを小さなTSセグメントに分割
- M3U8プレイリスト:セグメントの索引
HLSの動作原理
- ビデオエンコード:H.264ビデオ + AACオーディオ
- セグメント分割:2-10秒のTSセグメントに分割
- M3U8生成:セグメントURLのリスト
- クライアント再生: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.m3u8AES-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.m3u8FFmpegでマスター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使用 |
| レイテンシが高い | 通常のHLS | LL-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