M3U8ダウンロードに失敗する場合の対処法

M3U8・HLSの検出、CORS、期限切れURL、Referer、DRM、セグメント不備など、ダウンロード失敗の原因と対処法を解説します。

M3U8 のダウンロードに失敗するのは、たいてい「プレイリストが検出されない」「オンラインツールがクロスオリジン制限に引っかかる」「元の動画ページでしか得られないアクセス情報をストリーム側が要求している」のどれかです。この記事では HLS の実際のダウンロードフローに沿ってステップごとに切り分け、どこで・なぜ失敗して・どう直すのかを説明します。


まず HLS のダウンロードパイプラインを理解する

HLS は「1 つの URL から 1 ファイルを引っ張る」だけの話ではありません。パイプラインであり、どこか 1 段でも壊れると最終的には「ダウンロード失敗」か「ファイルが壊れた」になります。この流れを頭に入れておくと、切り分けの方向性がはっきりします:

① M3U8 検出      ② マニフェスト解析  ③ セグメント取得   ④ 復号        ⑤ 結合/リマックス
   ↓                ↓                     ↓                  ↓             ↓
 webRequest       m3u8-parser           Worker Pool        WebCrypto    FFmpeg WASM
 リクエスト        Master/Media        並列で .ts 取得     AES-128-CBC  TS → MP4
 インターセプト    を判別               リトライと         (必要な場合)  または
                                      バックオフ                           直接連結
段階失敗したときの症状該当セクション
① 検出ポップアップに「メディアが検出されません」M3U8 が検出されない
② 解析マニフェストは取れたが画質・セグメント一覧が空マニフェスト解析がおかしい
③ 取得進捗が止まる、403、404、CORSセグメントのダウンロードに失敗する
④ 復号復号エラー、または結合後に無音・画面崩れ暗号化ストリームの復号に失敗する
⑤ 結合ファイルはできるが再生できない、音ズレ結合後のファイルが再生できない
HLS プロトコルとマニフェスト構造(Master vs Media Playlist、EXT-X-KEY、複数音声トラック)の完全な解説は、動画メディア検知 — HLS ストリームをご参照ください。実際のマニフェストがどうなっているか、なぜ「素朴なダウンローダー」が失敗するのかは、HLS ディープで確認できます。

まず試すこと

深掘りする前に、9 割のケースを解決できるこの手順を先に回してみてください:

  1. 元の動画ページを開いて数秒再生する(多くのサイトは遅延読み込み。再生しないと M3U8 をリクエストしません)。
  2. 拡張機能のインストール後にページを再読み込みしていない場合は、一度再読み込みしてください(拡張機能の webRequest 監視は、ページ読み込み後にしか効きません)。
  3. 拡張機能で再検出して、目的の画質を選択します。
  4. MP4 出力を選んで、もう一度ダウンロードします。

これで解決しない場合は、下のセクションから切り分けていきます。


M3U8 が検出されない

症状:FlowPick のポップアップに「メディアリソースが検出されません」と表示される、または一覧にサムネイル・カバー画像しかなく .m3u8 の項目が出ない。

よくある原因

原因確認方法対処
動画がまだ読み込まれていない再生せずに拡張機能を開いた3〜5 秒再生してから拡張機能を開く
拡張機能インストール後にページを再読み込みしていないインストール前にページが読み込み済みだった再読み込みしてリクエストを再発火させる
ネイティブ HLS ではなく MSE を使っている開発者ツールに .m3u8 リクエストが出ない下の「MSE サイトの場合」を参照
マニフェストがクロスオリジンの iframe 内にあるNetwork タブでは見えるが拡張機能から取れないiframe の元ページを直接開いて検出する
広告ブロッカーなど他の拡張機能と競合他のネットワーク系拡張機能を無効化すると検出できるホワイトリストに追加するか読み込み順を調整
独自・プライベートプロトコルNetwork 上で ws://blob:、暗号化ストリームになっているFlowPick では未対応。既知の制限事項を参照

開発者ツールで確認する

F12Network タブ → フィルタ欄に m3u8 と入力します:

  • リクエストがある:サイトは確かに HLS を使っています。問題は検出側(たいていは再読み込み忘れか、他の拡張機能による遮断)。
  • リクエストがない:MSE(Media Source Extensions)を使っていて、.m3u8 を発行せずセグメントを直接 <video> に渡している可能性があります。こうしたサイトは FlowPick では検出できません。ブラウザ層の制限です。

MSE サイトの場合

Network タブに .m4s.chunk のリクエストが大量に出ているのにマニフェストファイルがなければ、MSE + 独自セグメント化(YouTube が典型例)です。対処は 2 つ:

  • .mpd(DASH)の入口を探して DASH ダウンローダーに切り替え、DASH の音声が出ないを参考にする。
  • <video> タグの src を確認。blob: で始まっていたら MSE が生成したもので直接ダウンロードできません。サイトがネイティブの HLS/DASH マニフェストを配信するのを待つしかありません。
検出の仕組み(webRequest.onBeforeRequest、Content-Type 判別)と 25 種類以上の MIME タイプの一覧は、動画メディア検知 — 検出原理をご参照ください。検出できないときの体系的な切り分け手順は、よくある問題のトラブルシューティング — メディア検出問題をご参照ください。

マニフェスト解析がおかしい

症状:M3U8 は検出されたが画質一覧が空、またはセグメント数が異常に少ない(たとえば 1 個だけで、ダウンロードしても数 KB しかない)。

Master か Media か

HLS のマニフェストは 2 層です。ポップアップに Media Playlist(セグメント一覧そのもの)が出ている場合は、画質の選択肢がない可能性があります。逆に Master Playlist の URL しか取れていないのに、解析されたバリアントがすべて空なら、マニフェストの内容が不完全なことが多いです。

Master Playlist          ← 360p / 720p / 1080p のバリアントを列挙
    └── v_720.m3u8       ← Media Playlist。数百個の .ts セグメントを列挙
            └── seg-001.ts, seg-002.ts, ...

マニフェストの内容を自分で確認する

M3U8 の URL をコピーして、curl で中身を見てみましょう(自分の URL に置き換えてください):

curl -sL "https://cdn.example.com/index.m3u8"

正常な Master Playlist には #EXT-X-STREAM-INF の行が見えるはずです:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1280x720
v_720.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=8000000,RESOLUTION=1920x1080
v_1080.m3u8

正常な Media Playlist には #EXTINF + セグメント URL が見えるはずです:

#EXTM3U
#EXT-X-TARGETDURATION:6
#EXT-X-VERSION:3
#EXTINF:6.0,
seg-001.ts
#EXTINF:6.0,
seg-002.ts
#EXTINF:4.2,
seg-003.ts
#EXT-X-ENDLIST

よくある異常

見えた内容問題対処
HTML ページ全体(ログインページ・エラーページ)ホットリンク対策で URL がリダイレクトされた403 とホットリンク対策を参照
#EXTM3U の 1 行だけマニフェストが途中で切れた・レスポンスが不完全ページを開き直して新しい URL を取得
#EXT-X-KEY はあるがセグメントがないキー取得に失敗して以降が出力されない暗号化ストリームの復号に失敗するを参照
#EXT-X-ENDLIST はあるがセグメント数が 5 未満ライブ配信が始まったばかり、または終了済みライブ配信は終了後にアーカイブをダウンロード
セグメント URL が相対パス正常。パーサーがベース URL を補完する対処不要
実際の HLS マニフェストはチュートリアルの例よりずっと複雑です(複数音声トラック、字幕、CODECS フィールド、不連続タグなど)。これらこそ「素朴なダウンローダー」が失敗する高発地域です。解析ロジックの全体像は HLS ディープ動画メディア検知 — Master vs Media Playlistをご参照ください。

セグメントのダウンロードに失敗する

症状:プログレスバーが途中で止まる・エラーになる、またはコンソールに 403/404/CORS エラーが大量に出る。

403 とホットリンク対策

セグメントやマニフェストが 403 Forbidden を返すのは、ほぼホットリンク対策のチェックを通過できていないケースです。代表的な 3 タイプ:

タイプ症状FlowPick の対応
Referer チェックcurl では取れるのに拡張機能は 403 になることがあるv1.1.1 以降、拡張機能が元ページの Referer を自動付与
Cookie / ログイン状態未ログインだと 403、ログインすると正常元の動画ページで拡張機能を使えば Cookie も付与される
短時間トークンURL に ?token=xxx&expires=yyy が付き、数分で失効下の「期限切れ URL」を参照

拡張機能のホットリンク対策プロキシ(v1.1.1+)

v1.1.1 以降、FlowPick にはホットリンク対策プロキシによるプレビュー&ダウンロードが組み込まれています。画像一覧、動画カバー、ホバープレビュー、画像・音声・ドキュメント・字幕のダウンロードは自動的にプロキシを通り、元ページの Referer と Cookie を付与。保存前にレスポンスをチェックするので、ホットリンク対策で返される HTML エラーページを画像や音声として保存してしまう事故を防ぎます。

旧バージョンを使っている場合、v1.1.1+ にアップデートすると Bilibili など Referer チェックがあるサイトのダウンロード成功率が大きく向上します。アップデート方法は インストールガイド — 拡張機能の更新をご参照ください。

オンラインツールが 403 になりがちな理由

オンラインツールは flowpick.com ドメインで動くため、ブラウザは対象サイトの Cookie も元ページの Referer も渡してくれません。つまり、配信元がホットリンク対策をしている限り、オンラインツールはほぼ確実に失敗します。ホットリンク対策のあるサイトは拡張機能を、元の動画ページで使ってください。

curl で 403 を再現する

Referer 問題かどうかを一番早く確かめる方法:

# Referer なしだと、おそらく 403
curl -I "https://cdn.example.com/seg-001.ts"

# 元ページの Referer を付けると 200 のはず
curl -I -H "Referer: https://www.example.com/watch/123" "https://cdn.example.com/seg-001.ts"

2 つ目が 200 を返せば、Referer チェックが原因で確定です。

期限切れ URL(動的トークン)

ライブ配信のアーカイブや一部プラットフォームの VOD は短時間トークンを使います:

https://cdn.example.com/seg-001.ts?token=ab12cd34&expires=1692300000

expires は Unix タイムスタンプで、この時間を過ぎると 403/404 になります。症状は:

  • ダウンロードは順調だったのに、途中から全セグメントが一斉に 403。
  • ページを開き直すとまた取れるが、しばらくするとまた落ちる。

対処

  • マニフェストを検出したらできるだけすぐにダウンロードを開始しましょう。ポップアップで長考しないこと。
  • 大きなファイルがトークンで途切れたら、元ページを再読み込みして拡張機能に新しいマニフェストを取得させ、残りを続けます(FlowPick のリトライは一時的な変動は処理しますが、トークン失効のようなハード障害は抜けられません。新しいマニフェストが必要です)。
FlowPick のダウンロードリトライは指数バックオフ方式で、一時的なネットワークの揺らぎには対応しますが、トークン失効のようなハード障害は迂回できません。リトライの仕組みの詳細は ダウンロードエンジンアーキテクチャ — リトライメカニズムをご参照ください。

404:セグメントが削除された

主にライブ配信のアーカイブで発生します。配信終了後、プラットフォームはアーカイブのセグメントを一定期間しか保持せず、期限が過ぎると 404 になります。

  • 別の画質を試してみる(画質ごとに別のセグメントファイルのことがあります)。
  • アーカイブがまだ保存期間内か確認する。

CORS エラー

コンソールに has been blocked by CORS policy と出るのは、ほぼオンラインツールの問題です。拡張機能は host_permissions を持っているため、同一オリジンポリシーの制約を受けません。

ツールCORS の挙動対処
ブラウザ拡張機能CORS は発生しない
オンラインツールマニフェスト・セグメントのクロスオリジン取得が遮断される拡張機能に切り替える。または配信元が Access-Control-Allow-Origin を返しているか確認
CORS はブラウザのセキュリティ機構であってバグではありません。オンラインツールと拡張機能の機能差・選び方については、オンラインツール — 拡張機能との違いをご参照ください。

ダウンロード途中のネットワーク切断

一時的なネットワークの揺らぎはリトライ機構がカバーします。継続的に失敗する場合:

並列数はどう設定すればいい? デフォルトの 2 は控えめで、デスクトップのネットワークなら 4〜6 が目安、CDN の帯域制限が厳しいサイトは 2〜3 に下げてください。設定方法は設定リファレンス、並列と性能の関係はダウンロードエンジンアーキテクチャ — 並列チューニングをご参照ください。

暗号化ストリームの復号に失敗する

症状:マニフェストに #EXT-X-KEY があり、ダウンロード自体は完了するのに、結合後の出力が無音・画面崩れ・再生不能、またはコンソールに復号エラーが出る。

AES-128 か DRM かをまず見分ける

FlowPick が対応するのは AES-128 という「素の」暗号化だけです。マニフェストに次のタグがあるものは、すべてダウンロードできません:

# AES-128 —— 対応
#EXT-X-KEY:METHOD=AES-128,URI="https://cdn.example.com/key.bin",IV=0x...

# SAMPLE-AES / FairPlay —— 非対応(DRM に近い)
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://..."

# Widevine / PlayReady(DASH でよく見られる)—— 非対応
<ContentProtection schemeIdUri="..."/>

AES-128 復号失敗のよくある原因

原因確認方法対処
キー URL が 403/404コンソールにキー取得失敗のエラー元ページで拡張機能を使う(Cookie/Referer 付き)。キーもトークン化されていることがある
キーにログインが必要未ログインだと 403、ログインすると正常先にログインしてからダウンロード
IV がないマニフェストの #EXT-X-KEYIV= がないFlowPick が仕様どおりセグメント番号から IV を導出するので手動対応は不要
キーが 16 バイトでないcurl で取得した長さがおかしい配信元の異常。FlowPick では修正不可

curl でキーを検証する

# キーが取れるか確認。Referer/Cookie を付けるのを忘れずに
curl -sL -H "Referer: https://www.example.com/watch/123" \
     "https://cdn.example.com/key.bin" | wc -c
# 正常なら 16 が出力される

出力が 16 でなければキー自体に問題があります。16 なのに拡張機能で復号に失敗する場合は、拡張機能のリクエストに Cookie/Referer が付いていないことが大半です(v1.1.1+ にアップグレードすれば、ホットリンク対策プロキシが自動で付与します)。

DRM コンテンツの場合

Widevine、PlayReady、FairPlay、SAMPLE-AES といった DRM 保護コンテンツは、FlowPick は明示的に拒否します。これは仕様であってバグではありません。DRM を破れると主張するダウンローダーは、嘘か違法のどちらかです。法的・技術的なラインについてはストリーミングのダウンロードは合法か?技術と法律のチェックリストをご参照ください。

DRM の検出方法と非対応コンテンツの一覧は既知の制限事項 — DRM 保護コンテンツ、AES-128 復号の Web Crypto 実装は動画メディア検知 — 暗号化ストリームをご参照ください。

結合後のファイルが再生できない

症状:ファイルはダウンロードできてサイズも正常なのに、VLC・プレイヤーで開けない。または映像はあるのに音が出ない、音ズレする。

まず VLC で試す

VLC は互換性が最も高いプレイヤーなので、まずこれで「プレイヤー側の問題」を排除しましょう:

  • VLC で再生できて OS 標準プレイヤーでできない → コーデック・コンテナの互換性問題。プレイヤーを変える。
  • VLC でも再生できない → ファイルそのものが壊れている。

よくある原因

症状原因対処
ファイルが数 KB しかない動画ではなくマニフェストを取ってしまったリソースを選び直す。選んだのが動画で .m3u8 でないことを確認
映像はあるが音が出ない複数音声トラックのマニフェストで映像トラックだけ取得した下の「複数音声トラックのマニフェスト」を参照
音ズレHLS セグメントの PTS が連続していないTS 出力形式に切り替えるか、FFmpeg で再エンコード
画面崩れ・破損一部セグメントの取得失敗で結合が不完全再ダウンロードして全セグメントが揃っていることを確認
MP4 は開けないが TS は再生できるリマックス時に stsd box の書き込みミス下の「TS vs MP4 出力フォーマット」を参照

複数音声トラックのマニフェスト

実際の HLS マニフェスト(Netflix や Disney+ など)では、音声と映像を別々のプレイリストに分けていることがよくあります:

#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac-128",NAME="English",DEFAULT=YES,URI="audio/eng_128.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=3000000,...,AUDIO="aac-128"
v_720.m3u8

v_720.m3u8 だけ取ってセグメントを連結するだけのダウンローダーだと、音声なしの動画になります。FlowPick は音声トラックも同時に取得して結合しますが、その前提として映像ストリームだけでなく音声を含むバリアントを選択してください。複数音声トラックのマニフェストの完全な処理はHLS ディープ — EXT-X-MEDIAをご参照ください。

TS vs MP4 出力フォーマット

MP4 が開けない場合は、まず TS 出力形式に切り替えてみてください。理由:

  • TS セグメントは素の連結で、MPEG-TS は codec 情報を内包しているため、ほぼ間違いません。
  • MP4 へのリマックスは CODECS フィールドの解析と stsd box の書き込みが正しくないと失敗します。非標準の codec 識別子があると壊れやすいです。

TS は再生できるのに MP4 が再生できないのは、ほぼリマックス問題です。まずは TS で応急処置し、MP4 が必要なら FFmpeg コマンドで手動変換してください:

ffmpeg -i output.ts -c copy output.mp4

-c copy は再エンコードしないので、数秒で完了します。

TS/MP4 のリマックス原理と FFmpeg WASM 実装はフォーマット変換、ブラウザ内での結合フロー全体はFlowPickがブラウザ内で数百の動画セグメントをMP4に結合する仕組みをご参照ください。

大容量ファイル・ブラウザのフリーズ

症状:1GB を超える大容量ファイルのダウンロード中にブラウザがカクつく・クラッシュする、または一定の割合でダウンロードが中断する。

これは 書き込み戦略の問題であって、HLS 自体の問題ではありません。FlowPick の 3 段階の書き込み戦略:

戦略発動条件上限
File System Access APIChrome/Edge 86+ハード上限なし
StreamSaver.jsService Worker 対応ブラウザハード上限なし
Blob フォールバックそれ以外1.5GB のハード制限

Blob モードでは 1.5GB 超えは即座に拒否されます。解決策:

  • Chrome 86+ または Edge 86+ を使って、「保存先ディレクトリの選択」機能を有効にする。
  • Firefox は FSA 非対応のため、大容量ファイルは StreamSaver または OPFS 一時ストレージ(v1.1.1+ で最適化)を経由します。
  • どうしてもダメなら並列数を 1〜2 に下げてメモリ使用量を減らす。
3 段階の書き込み戦略の比較とフォールバックのロジックはダウンロードエンジンアーキテクチャ — 戦略比較まとめ、大容量ファイルの切り分けはよくある問題のトラブルシューティング — 大容量ファイルのダウンロードに失敗、Firefox の OPFS 一時ストレージの挙動はインストールガイド — Firefoxをご参照ください。

診断ツール早見表

切り分け時は F12 で開発者ツールを開きます。よく使うチェックポイントはこちら:

チェック内容パネル操作
M3U8 がリクエストされているかNetworkフィルタ欄に m3u8 を入力し、ページを再読み込みして動画を再生
セグメントのステータスコードNetworkフィルタ欄に .ts または .m4s を入力し、Status 列を確認
リクエストに何が付いているかNetwork → リクエスト選択 → HeadersRequest Headers の Referer/Cookie を確認
復号エラーConsoledecrypt または AES で検索
結合エラーConsoleffmpeg または wasm で検索

環境診断レポートの生成

再現しにくい問題は、Console で次のコードを実行して環境情報を生成し、フィードバックに活用してください:

const report = {
  ua: navigator.userAgent,
  fsa: 'showDirectoryPicker' in window,
  sab: typeof SharedArrayBuffer !== 'undefined',
  coi: self.crossOriginIsolated,
  storage: await navigator.storage?.estimate().catch(() => null),
  ts: new Date().toISOString(),
}
console.log(JSON.stringify(report, null, 2))

レポートにはブラウザ環境情報しか含まれません。閲覧履歴や個人データは一切入りません。


本当にダウンロードできない場合

FlowPick が対象にしているのは、公開されている標準的な HLS プレイリストです。次のシナリオは設計上サポート外であって、バグではありません:

  • DRM 保護コンテンツ(Widevine / PlayReady / FairPlay / SAMPLE-AES)
  • ログイン回避やペイウォール突破が必要なコンテンツ
  • MSE による独自セグメント化を使い、ネイティブの M3U8/MPD を配信しないサイト
  • プライベートプロトコル、WebSocket、WebRTC で配信されるメディア

こうした場合、FlowPick は静かに壊れたファイルを作るのではなく、エラーを出すのが正しい振る舞いです。それが FlowPick のスタンスです。法的・技術的なラインの詳細はストリーミングのダウンロードは合法か?技術と法律のチェックリストをご参照ください。


関連ドキュメント