【ffmpeg】解像度を選んで動画(HLS配信)を保存するには?(mapオプション)

ffmpeg コマンド

最近のストリーミング(HLS配信)では、画質や解像度を選択できるようになっていることがほとんどですよね。

YouTubeの画質オプション
Youtubeも画質を選べるようになっています

ffmpegでストリームを選択して動画をダウンロードし保存する方法をまとめておきます。

スポンサーリンク

そもそも解像度を選べるストリーミングの仕組みは?

はじめに解像度を選択できる仕組みを軽く理解しておきましょう。

解像度を選択して再生できるようになっているストリーミング(HLS配信)では、各解像度の動画が異なるストリームとして用意されています。プレイリスト(m3u8)の内容を確認すると、解像度ごとに別個のストリームが用意されていることがわかります。

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=300000,NAME="1080p",RESOLUTION=1920x1080
xxxx=.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=150000,NAME="720p",RESOLUTION=1280x720
xxyy==.m3u8

ユーザーが解像度を選択すると、該当するチャンクリストがダウンロードされ、指定された解像度の動画が再生される仕組みになっています。

スポンサーリンク
スポンサーリンク

mapオプションを使えば、ダウンロードする動画の解像度を選べる!

このように解像度を選べる方式のHLS配信は、ffmpegのmapオプションを使うと任意の解像度の動画をダウンロードできます。

https://trac.ffmpeg.org/wiki/Map

mapオプションはストリームを選択するためのオプションです。複数のストリームが用意されているソースから任意のストリームを抽出することができます。HLS配信についてもmapオプションを使うことにより、任意の解像度の動画を抽出することが可能です。

ちなみにDVDの多重音声もストリームにより実現されているので、多重音声のソースから任意の言語の音声を取り出すのに使ったりすることもできます。ほかにも動画と音声データをくっつけたり、いろいろと活用できるオプションです。

サンプル

実際にやってみます。まずはmapオプションをつけずにffmpegを実行し、ストリーム情報を確認してみましょう。

m3u8を-iオプションに指定してffmpegを実行すると、以下のようにストリーム情報が出力されます。

$ ffmpeg -i "xxx.m3u8" -c -copy out.ts
Program 0
    Metadata:
      variant_bitrate : 3000000
    Stream #0:0: Data: timed_id3 (ID3  / 0x20334449)
    Metadata:
      variant_bitrate : 3000000
    Stream #0:1: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Metadata:
      variant_bitrate : 3000000
    Stream #0:2: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp
    Metadata:
      variant_bitrate : 3000000
Program 1
    Metadata:
      variant_bitrate : 1500000
    Stream #0:3: Data: timed_id3 (ID3  / 0x20334449)
    Metadata:
      variant_bitrate : 1500000
    Stream #0:4: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Metadata:
      variant_bitrate : 1500000
    Stream #0:5: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp
    Metadata:
      variant_bitrate : 1500000

もちろん情報の確認だけならffprobeでもOKです。ffprobeでストリーム情報を確認したいときは、次のコマンドとなります。

スポンサーリンク
$ ffprobe "xxx.m3u8" -hide_banner -show_streams

出力されているProgramの番号をmapオプションに指定することで、任意のストリームを取り出すことができます。

例えば、上の例で1280×720の動画を抽出し、ローカルに保存したい場合はProgram 1をmapすることになるので、以下のようなコマンドになります。

ffmpeg -i "https://....m3u8" -map 0:p:1 -c copy "output.ts"

0:p:につづけて、Programの番号を指定します。すると、該当するProgramのストリームがファイルに保存されます。

”timed_id3 codec not currently supported”と表示されるとき

timed_id3のストリームが含まれているとき-c copyと併用するとエラーとなることがあります。

この場合はmapオプションにストリーム番号を直接指定します。

ffmpeg -i "https://....m3u8" -map 0:4 -map 0:5 -c copy "output.t

Program1のストリーム情報を見ると、映像が#0:4 音声が#0:5となっていることがわかるため、mapオプションに0:4と0:5を指定します。こうすることで正常に任意のストリームを保存することができます。

まとめ

ストリームを選択して、HLS配信されている動画をダウンロードする方法をメモしておきました。

mapオプションについては、公式ドキュメントにさらに詳しい使い方が載っていますので、参考にしてみてください。

https://trac.ffmpeg.org/wiki/Map

コメント

タイトルとURLをコピーしました