← ブログに戻る

HLS / m3u8 ストリームの一部だけをダウンロードする方法(全体ではなく)

m3u8/HLS ストリームから特定の時間範囲を抽出 — ffmpeg シーク、セグメント計算、ブラウザ内クリップ方法。

3時間の HLS VOD があり、47~52分を取得したいとします。マニフェスト全体をダウンロードして(数百のセグメント、ギガバイトのデータ)、その後ビデオエディタで5分間トリミングするのは、効率が悪いです。HLS は小さく独立して取得可能なチャンク(セグメント)で構成されているため、時間ウィンドウの外側のデータをダウンロードする技術的な理由はありません。必要なのは、どのセグメントがその時間範囲に重なっているかを計算することだけです。

このポストは技術的な内容です。HLS と m3u8 について基本的な知識があることを前提としています。知らない場合は、まず m3u8 / HLS ストリームをダウンロードする方法 で完全なプロトコル解説を読み、その後戻ってきてください。ここでの目的はより具体的です:メディアプレイリストと [start, end] 時間範囲が与えられたとき、必要なバイト数だけを取得することです。

3つの方法を紹介します — マニフェスト URL に対する ffmpeg シーク、範囲対応 CLI ダウンローダー、重なるセグメントのみを取得するブラウザ内クリップ拡張 — さらに、それらすべてを可能にするセグメント計算の仕組みについて説明します。

なぜセクションダウンロードが可能なのか

HLS メディアプレイリストの本質は、セグメントとその期間の順序付きリストです。実際のものを単純化すると、次のようになります:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD

#EXTINF:6.000,
segment000.ts
#EXTINF:6.000,
segment001.ts
#EXTINF:6.000,
segment002.ts
#EXTINF:6.000,
segment003.ts
...
#EXTINF:4.200,
segment842.ts
#EXT-X-ENDLIST

重要な行は #EXTINF です。これは後に続くセグメントの正確な期間を宣言します。プレイヤーがセグメントを順に連結するため、セグメント n の開始時刻は、その前の全 #EXTINF 期間の合計 です。セグメント 0 は [0, 6) をカバー、セグメント 1 は [6, 12) をカバー、セグメント 2 は [12, 18) をカバーします。

この性質がセクションダウンロードを実現可能にします。ウィンドウ [T_start, T_end) を取得するには、プレイリスト全体は必要なく、時間幅がそのウィンドウと重なる連続したセグメント実行だけが必要です。最初の重なるセグメントの前のすべてのデータと最後のセグメントの後のすべてのデータは、スキップできる無駄です。

この事実から直ちに2つの結論が導き出されます:

  1. 任意のフレームで無料でカットすることはできません。 セグメントはキーフレーム境界で始まります(適切に形成されたストリームでは、各セグメントは新しい IDR フレームで開始)。コピーのみで再エンコードなしの抽出が必要な場合、最も安いカットポイントはセグメント境界です。より細かい精度を求めるには、境界セグメントを再エンコードする必要があります。
  2. 計算は #EXTINF 値にのみ依存します。セグメントファイル名、バイトオフセット、または CDN が隠す何かには依存しません。メディアプレイリストを読むことができれば、セグメント範囲を自分で計算できます。

時間範囲をセグメントインデックスにマッピングする:実例

セグメントが一様に 6 秒で、10:00 から 15:00 — つまり [600s, 900s) を取得したいとします。

  • 最初に重なるセグメントインデックス:floor(600 / 6) = 100。セグメント 100 は [600, 606) をカバーします。
  • 最後に重なるセグメントインデックス:ceil(900 / 6) - 1 = 149。セグメント 149 は [894, 900) をカバーします。

つまり、セグメント 100~149(両端含む) が必要です — 843 個すべてではなく、50 個のセグメント、300 秒です。これらを正確に連結すると、10:00 で正確に始まり(600 はセグメント境界だから)15:00 で正確に終わるきれいな 5 分間のクリップが得られます。

実際のプレイリストは完全に一様な期間を持つことはめったにありません — 最後のセグメントは短く、広告挿入ポイントがタイミングをリセットし、ライブエンコーダは漂流します。そのため、堅牢なアプローチは 定数で割らず、累積 することです:

# 疑似コード:時間範囲 -> セグメントインデックス範囲
t = 0.0
first = last = None
for i, dur in enumerate(extinf_durations):
    seg_start, seg_end = t, t + dur
    if seg_end > T_start and first is None:
        first = i                      # ウィンドウに到達する最初のセグメント
    if seg_start < T_end:
        last = i                       # セグメントがまだ重なっている間、進み続ける
    t = seg_end
# segments[first .. last] (両端含む) を取得

このループは、以下のすべてのツールが内部的に行うことと全く同じです。メソッド間の違いは、周辺の配管 — 認証、キー取得、オーディオ/ビデオペアリング、URL 署名 — をどのくらい処理するかです。

方法 1:m3u8 URL に対する ffmpeg シーク

ffmpeg は HLS をネイティブに理解するため、最も直接的なセクションダウンロードは、マニフェスト URL とシーク、期間を渡すことです:

ffmpeg -ss 00:10:00 -t 00:05:00 -i "https://example.com/video/720p/playlist.m3u8" -c copy clip.mp4

-ss は開始(10:00 にシーク)、-t は取得する期間(5 分)、-c copy はパケットをそのまま通す(再エンコードなし)です。-c copy では、ffmpeg はキーフレーム境界でのみカットでき、実際のクリップは 10:00 以降のキーフレーム(通常は例の開始時のセグメント 100)で開始します。これはまさに高速でロスレスな取得に求めるものです。

-ss を -i の前に vs 後に

-ss-i の相対的な位置は、ここで最も重要な詳細で、速度と精度をトレードオフします:

  • -ss-i の前に(入力シーク) — ffmpeg はデコーディング前にデマルチプレクサレベルでシークします。HLS の場合、これはダウンロードする必要がないセグメント全体をスキップできることを意味します。高速、ネットワーク効率的、セクションを取得するための正しいデフォルトです。精度は最寄りのキーフレームまでです。
  • -ss-i の後に(出力シーク) — ffmpeg は最初から読み、デコードし、タイムスタンプに到達するまでフレームを破棄します。フレーム精度ですが、開始ポイントまでのすべて(多くの場合デコードも)を取得する必要があります。3 時間の VOD の 10:00 で始まるクリップの場合、これは遅く目的を損なします。

高速セクションダウンロードでは、-ss-i の前に保ちます。出力ポイントでフレーム精度が必要な場合、通常の方法はターゲットのすぐ前に入力シーク(高速)してから小さな残りを出力シーク(精度)することです。つまり、ヘッドを再エンコードします:

# ~9:58 に高速入力シーク、その後 10:00 にフレーム精度トリミング、境界のみ再エンコード
ffmpeg -ss 00:09:58 -i "https://example.com/video/720p/playlist.m3u8" \
  -ss 00:00:02 -t 00:05:00 -c:v libx264 -c:a aac clip.mp4

-c copy の速度が失われますが、再エンコードするセグメントだけで、クリップ全体ではありません。

正直な制限

マニフェストに対する ffmpeg は、ストリームが到達可能で署名されていない場合、正しいツールです。署名がない場合、すぐに複雑になります:

  • 期限切れの署名付き URL。 多くの CDN はマニフェスト(時にはすべてのセグメント)に 60~300秒 で期限切れになるトークンで署名します。DevTools から URL をコピーして ffmpeg が長いクリップを処理している間にトークンが期限切れになると、403 でダウンロード途中に失敗します。5 分間のコピーではしばしば問題ありません。より長いもの、またはタイミングをミスしたものでは、実際の問題です。

  • AES-128 暗号化。 プレイリストが #EXT-X-KEY:METHOD=AES-128,URI="key.bin" を含む場合、ffmpeg は自動的にキーを取得して適用します — キー URL が持つリクエストコンテキストで到達可能である限り。キーエンドポイントがクッキーやヘッダが必要で、あなたの bare ffmpeg 呼び出しが送らない場合、復号化は失敗します。

  • 個別のオーディオとビデオマニフェスト。 最新の HLS は通常、オーディオとビデオを別のメディアプレイリストに分割します。ビデオマニフェストのみをシークすると、サイレントクリップが得られます。両方を入力として渡し、両方をシークする必要があります:

    ffmpeg \
      -ss 00:10:00 -t 00:05:00 -i "https://example.com/video/720p/playlist.m3u8" \
      -ss 00:10:00 -i "https://example.com/audio/en/playlist.m3u8" \
      -c copy -bsf:a aac_adtstoasc clip.mp4

    (HLS ダウンロードでサイレントクリップ障害モードについては、HLS Download: Audio and Video Are Separate を参照してください。)

  • Referer / カスタムヘッダー。 オリジンでゲートウェイしている CDN はヘッダを明示的に渡す必要があります。例:-headers "Referer: https://example.com/watch"。間違うと、すべてのセグメントリクエストが 403 になります。

これらはスクリプティングの取引妨害ではありません — ffmpeg は URL、ヘッダ、キーが既に整っていて、繰り返し可能で自動化可能なカットが必要な場合、無敗です。ストリームがログイン後ろまたは回転する署名の後ろにある場合、ブラウザが無料で生成したリクエストコンテキストを手動で再構築しているため、本当に複雑です。

方法 2:範囲対応 CLI ダウンローダー(N_m3u8DL-RE、yt-dlp)

ffmpeg シークフラグではなくセグメント/時間スペースで作業したい場合、専用 HLS ダウンローダーはプレイリストのサブセットを選択できます。

N_m3u8DL-RE は範囲選択を直接公開します。--custom-range フラグは時間またはセグメント範囲を受け入れ、それらのセグメントのみをダウンロードします — これはまさに「重なる実行を取得」操作で、あなたのために行われます:

# 時間範囲
N_m3u8DL-RE "https://example.com/master.m3u8" --custom-range "00:10:00-00:15:00" --save-name clip

# またはセグメントインデックス別
N_m3u8DL-RE "https://example.com/master.m3u8" --custom-range "100-149" --save-name clip

また、マスタープレイリストを解決し、オーディオとビデオトラックをペアリングし、AES-128 キーを適用します。これは ffmpeg の大部分の痛みを取り除きます。トレードオフは、インストールする別のバイナリであり、カット精度はセグメント粒度です — 全セグメントが得られるため、クリップは各端で最寄りのセグメント境界にスナップします。

yt-dlp はより広いツールですが、範囲サポートはより狭く、正直に述べる価値があります。--download-sections フラグは、実際のエクストラクタを持つサイト(特に YouTube チャプター/タイムスタンプ範囲経由)で好調です:

yt-dlp --download-sections "*00:10:00-00:15:00" -f "bv*+ba/b" "https://www.example.com/watch?v=..."

ただし、生の .m3u8 URL の場合、--download-sections はしばしば完全なストリームをダウンロードして ffmpeg で後トリミングにフォールバックします。yt-dlp のジェネリック HLS ハンドリングは、常にネイティブセグメント範囲取得を行うわけではないからです。つまり、ディスク保存トリミング労力は節約できますが、必ずしも帯域幅は節約できません。実際に何を取得したかを確認してから、ウィンドウのみを取得したと仮定してください。

両方のツールは bare ffmpeg と同じ盲点を共有します:公開、署名なし ストリームで清潔に動作します。認証ウォール或いは短期有効期限署名マニフェストにそれらを指すと、DevTools から手動でクッキー、ヘッダ、新しく署名された URL をコピーしている状態に戻ります。

方法 3:OFA でブラウザでクリップ(CLI なし、セッション継承)

上記のすべての方法は、1 つの根本問題を共有します:マニフェストとセグメントは特定の認証されたブラウザセッションに提供され、コマンドラインツールはそのセッションではありません。リクエストコンテキストを逆算する必要があります — クッキー、Referer、署名付きクエリ文字列、キーエンドポイントの認証 — そして 1 分で期限切れになるトークンとレースします。

その回避法は、ページ 内側 でクリップを行うことです。セッションはすでに存在しています。Video Downloader One-for-AllClip & Trim Download(v1.1.38、2026年6月に追加)はまさにこれを行います:

  1. ページを開き、プレイヤーがストリームを通常どおりロードするようにします。
  2. OFA のクリップビューを開く — 検出された HLS/DASH ストリームの シーク可能プレビュー が得られます。
  3. イン/アウトポイントを正確な範囲(例:10:00 → 15:00)にドラッグします。
  4. ダウンロード。OFA は選択した範囲と重なるセグメント のみを取得 — この記事の上部からの累積選択ロジックを実行 — 単一の MP4 にマックスします。

Chrome/Edge 拡張機能としてタブ 内側 で実行されるため、次のようなことができます:

  • プレイヤーの認証を継承 — クッキー、署名付き URL、Referer は、ページが既に送信したもの。ログインゲートと短期有効期限ストリームは、何もコピーせずに機能します。
  • AES-128 を透過的に処理。ページ独自のリクエストコンテキストでキーを取得します。
  • 個別のオーディオとビデオマニフェストを自動的にペアリング。クリップは音声付き — bsf:a aac_adtstoasc 呪文を覚える必要はありません。
  • ウィンドウのみを取得。全 VOD ではなく。つまり、3 時間ストリームからの 5 分クリップはおおよそ 5 分分のデータをダウンロードします。

Clip & Trim は Free と Paid の両プラン で利用可能です。カット精度は境界でセグメント粒度です(N_m3u8DL-RE と同じ制約 — コピーのみ抽出はキーフレームがすでにある場所でのみカット可能)。一般的な 2~6 秒セグメントでは、設定したマークの数秒以内に到達します。正確フレームイン/アウトが必要な場合、ここでわずかに大きいクリップを取って、方法 1 の出力シーク ffmpeg パターンで最終フレーム精度トリミングをローカルで行ってください。

基盤となる HLS エンジンの製品詳細は HLS downloader ページ に、ライブ(非 VOD)ウィンドウの取得はマニフェストが固定リストではなくスライディングウィンドウである場合は live stream recorder を参照してください。

これは並列ガイド ビデオの一部をダウンロードする方法 が一般的なケースで推奨するパスであり、同じアプローチは長いストリームから単一ハイライトが必要な場合に適用されます — Twitch VOD をダウンロードする方法 をそれぞれのシナリオについて参照してください。

どの方法を、いつ

メソッドCLI が必要認証/クッキー処理AES-128 処理フレーム精度範囲のみを取得
ffmpeg -ss/-tはい手動(ヘッダ/クッキー手作業)はい(キー URL が到達可能な場合)デフォルトはキーフレーム;再エンコードでフレーム精度はい(入力シークで)
N_m3u8DL-RE --custom-rangeはい手動はいセグメント粒度はい
yt-dlp --download-sectionsはい部分的(エクストラクタ依存)はい異なる;多くの場合完全取得後トリミングエクストラクタがネイティブ範囲を実行する場合のみ
OFA Clip & Trimいいえはい(ページセッション継承)はい(透過的)セグメント粒度はい

正直な概要:

  • ffmpegスクリプティングと自動化 に最適なツールです。公開またはセルフサーブストリーム上 — 繰り返し可能、構成可能、GUI なし、すべてのフラグを制御します。認証ウォールと戦うか 60 秒トークンを持つ場合、最悪のツールです。
  • N_m3u8DL-RE は ffmpeg シークフラグの複雑さなしで明示的な範囲選択が必要で、ストリームがロックダウンされていないとき、最高の CLI 中間グラウンドです。
  • OFA Clip & Trim はストリーム ログインが必要またはすぐに期限切れになる署名付き URL を配布 するか、単にターミナルに触れたくない場合、最良のツールです — 最初から認証ブラウザセッションを離れることはありません。

権利と DRM に関するノート

保存する権利がある内容のみをダウンロード — あなた独自のアップロード、ライセンスして使用可能な素材、またはソースの利用規約が許可している内容。そして、スコープについて明確にするため:この記事全体は クリア(または AES-128 暗号化)HLS についてです。これはキーがプレイヤーに配信されるため復号可能です。Widevine、PlayReady、または FairPlay で保護されたストリームは別のもの — コンテンツキーはハードウェアバック CDM を離れることはなく、ブラウザ内拡張またはCLI はそれを抽出できず、OFA は対応していません。それらが表示される場合、ここでセクションダウンロード技術は適用されません。

まとめ

セクションダウンロードが可能なのは、HLS プレイリストが時間付きセグメントのリストだから:#EXTINF 期間を合計し、[start, end] ウィンドウと重なる連続実行を見つけ、その実行のみを取得します。ffmpeg、N_m3u8DL-RE、yt-dlp はこの計算を内部で行い、オープンストリームで優れています — スクリプティングとバッチ作業を選択します。ストリームがログインの後ろまたはその URL が数秒で期限切れになる場合、摩擦は数学ではなく、ブラウザのセッションを再現することです — これはまさに Video Downloader One-for-All でページ内クリップを行う理由です。すべての認証ウォールに対して最小抵抗のパスです。