Social & Media • 10 min read

Redditビデオを音声付きでダウンロードする方法(サイレントMP4の問題を修正)

一般的な Reddit ダウンローダーはすべて、鮮明な 1080p ビデオ、ゼロサウンドという同じ壁にぶつかります。それが Reddit の DASH アーキテクチャがその役割を果たしているということです。ここでは、分割ストリームの仕組みと、音声を含む単一の多重化された MP4 を完全にブラウザーで取得する方法を説明します。

1. Reddit 動画がサイレントでダウンロードされる理由: DASH 分割ストリーム アーキテクチャ

Reddit のサイレントビデオ現象は、ダウンローダーのバグ、コーデックの癖、または地域の制限ではありません。プラットフォームのアーキテクチャが設計どおりに動作していることです。ビデオが Reddit にアップロードされると、v.redd.it でホストされ、MPEG-DASH 形式にエンコードされます。ビデオ トラックとオーディオ トラックは完全に別個のファイルとしてパッケージ化されます。パス v.redd.it/{post_id}/DASHPlaylist.mpd にあるビデオ投稿のマニフェストを開くと、XML 内の分割を直接読み取ることができます。1 つの AdaptationSet には、解像度によって名前が付けられたビデオ表現 (DASH_240.mp4、DASH_360.mp4、DASH_480.mp4、DASH_720.mp4、DASH_1080.mp4) が列挙されており、それぞれにはビデオ フレームのみが含まれています。別のオーディオ AdaptationSet は、フレームなしでサウンドを伝送する DASH_AUDIO_128.mp4 または DASH_audio.mp4 を保持します。 Reddit の Web プレーヤーは、MediaSource 拡張機能を使用して再生時にこれらをつなぎ合わせます。2 つの SourceBuffer インスタンス (1 つはビデオ ストリームによって供給され、もう 1 つはオーディオ ストリームによって供給され、プレゼンテーション タイムスタンプで同期されます)。プレーヤーは統一されたエクスペリエンスを提供します。基礎となるトランスポートは、両方を含む 1 つのファイルを提示することはありません。 したがって、単純なダウンローダーが「ビデオ」を取得すると、見つけられる最大の DASH_*.mp4 をフェッチし、そのファイルがまさに何であるか、つまり完全で整った形式のサイレント映画を取得します。オーディオは決して入っていませんでした。オンライン ダウンローダー サイトも、バックエンドで ffmpeg を実行してトラックを多重化することで、サーバー側で同じ分割とペーパーオーバーに直面します。これは、Reddit がデータセンター IP のレート制限を行うか、投稿が NSFW でサーバーにないセッション Cookie が必要になるか、オペレーターの ffmpeg キューがバックアップされて 503 を返すまで機能します。 ローカルファーストのアプローチは同じ多重化ジョブを実行しますが、ブラウザ内でセッションの Cookie と並行して両方のストリームを取得し、多重化を解除し、タイムスタンプを調整し、新しい MP4 を書き込みます。プロキシ、キュー、サイレント出力はありません。

2. クライアント側の多重化: サーバーなしで 2 つのファイルが 1 つになる方法

無音の DASH ビデオと分離されたオーディオ トラックをマージするのは、サーバー上の ffmpeg の仕事のように思えますが、何年もの間そうでした。しかし、MP4 コンテナ形式 (正式には ISOBMFF、ISO/IEC 14496-12) は構造化されたボックス階層であり、JavaScript は生のストリームが与えられたネイティブ ツールと同様にそれを再構築できます。これは、Video Downloader Bundle が Web Workers の mp4box.js とローカル マルチプレクサを使用して Reddit 投稿を処理するときに内部で起こっていることです。 シーケンスはこのように実行されます。両方のストリームが ArrayBuffers に並行してフェッチされます。トップのビデオ レンディション (利用可能な場合は DASH_1080.mp4) と、最高のオーディオ トラック (通常は 128 kbps AAC ファイル) です。 mp4box.js は各バッファのボックス ツリーを解析します。コンテナの互換性を識別する ftyp、トラック メタデータを保持する moov、およびトラック ボックス内のサンプル テーブル (タイミングの stts、チャンク レイアウトの stsc と stsz、オフセットの stco) で、すべてのフレームとオーディオ パケットを記述します。コーデックのプライベート データも一緒に出力されます。avcC ボックスはビデオ トラックからの H.264 パラメーター セットを保持し、esds はオーディオからの AAC 構成を記述します。 その後、2 つの時計が調整されます。ビデオとオーディオは異なるタイムスケール (通常、ビデオ トラックは 1 秒あたり 90,000 ティック、オーディオは 44,100 または 48,000 ティック) でエンコードされているため、リップシンクの正確性を保つために、プレゼンテーションのタイムスタンプが統合されたタイムライン上で再計算されます。新しい MP4 が合成されます: 新しい ftyp、両方のトラックのサンプル テーブルを含む単一の moov、および両方のストリームのペイロードが 1 つの mdat に統合されます。マルチプレクサは、mdat (ファストスタート レイアウト) の前に moov を書き込むため、ファイルはロードが完了する前に再生を開始し、プレーヤーはメタデータを最後までスキャンしません。 通常の投稿ではアセンブリ全体が数秒で完了し、どこでも音声付きで再生できる標準 MP4 が生成され、他のビデオと同様に Premiere や携帯電話のギャラリーにドラッグできます。

3. 多重化された MP4 の取得: 実際のワークフロー

Video Downloader Bundle がインストールされている Reddit は、出力がサイレント孤立ファイルや音声のみの兄弟ファイルではなく、単一の完成したファイルになるため、汎用ツールとの違いが最も顕著に表れるプラットフォームです。通常どおり Reddit を参照します。拡張機能の検出機能は、old.reddit、new.reddit、sh.reddit、および v.redd.it コンテンツの投稿詳細ページをカバーします。ビデオ投稿には、バンドル内の他のプラットフォームと同様に、プレーヤーの上にダウンロード ボタンが表示されます。 それをクリックしてください。アダプタは内部で投稿のメディアを解決します。つまり、セッションがすでにアクセスできる投稿の JSON を読み取り、DASH マニフェストを調べて利用可能なレンディションを探し、最高のビデオ ストリームと最高のオーディオ トラックを選択します。どちらも、Cookie が添付された状態でタブから並行して取得します。これにより、すべてのクラウド ダウンローダーが壊れる NSFW 問題が静かに解決されます。隔離された 18 歳以上のサブレディットのビデオには reddit_session が必要です。ブラウザには reddit_session が必要ですが、オハイオ州の一部のサーバーにはそれがありません。マルチプレクサはワーカーで実行され、結合された MP4 は投稿タイトルにちなんで名付けられたダウンロード フォルダーに保存されます。 Reddit ではコンテンツが激しく変動するため、他のプラットフォームよりもタイミングが重要です。モデレータは投稿を削除し、ユーザーは引数で自分の投稿を削除し、フィードをリアルタイムで自動修正します。機械の修理クリップ、再ホストされる前のニュースクリップ、レシピなど、参考用にビデオを保存している場合、見ている瞬間にそれを取得することは、明日また見に行くことを計画することとはまったく異なります。ボタンがすぐそこにあるデザインは、その現実を反映しています。 最上位で得られるものについてのメモ: Reddit のソース品質はアップローダーが提供するものに上限があり、DASH ラダーの最高点は 1080p です。すべて Reddit でエンコードされるため、オーディオは一律に 64 ~ 128 kbps の AAC です。マルチプレクサーは、これらのストリームをソース品質で保存します。忠実度ではなく同期を追加します。

4. エッジケース: クロスポスト、GIF、削除された投稿、フォールバック ホスト

Reddit のメディア表面には、維持されているツールと放棄されたツールを区別するいくつかのエッジケースがあり、それぞれがどのように動作するかを明確にする価値があります。クロスポストは 1 つ目です。クロスポストされたビデオは、v.redd.it 上の元の投稿のメディアをポイントバックするため、アダプターはラッパー 投稿で失敗するのではなく、クロスポスト チェーンを通じてソース メディアに解決されます。表示しているクロスポストでダウンロードをクリックすると、同じトラック、同じマルチプレクサのオリジナルのビデオが取得されます。大量にシンジケートを行う r/subreddit では、これがトラフィックのほとんどです。 GIF が 2 番目で、驚くべきことに、ビデオ パイプラインが関与していないことです。Reddit は、本物の GIF アップロードを i.redd.it に直接 .gif ファイルとして提供するため、ダウンロードはファイル自体の 1 回のフェッチであり、多重化やレンディションはありません。一部の従来のアップロードでは、よりスムーズに再生するために MP4 変換も公開されています。両方が存在する場合、同じコンテンツに対して MP4 の方が 1 桁小さいため、アダプターは MP4 を優先します。 投稿の削除と削除は正直な制限です。Reddit がセッションへのメディアの提供を停止すると、DASH URL も消滅し、プラットフォームが削除したコンテンツを復活させるツールはありません。削除された Reddit 動画を回復すると主張するものはすべて、おそらく元の投稿者の知らないうちに、どこかからキャッシュされたコピーを販売していることになり、それ自体が倫理上の問題です。 フォールバック ホスティングが最後の問題です。Reddit は、DASH ネゴシエーションが失敗したときに一部のクライアントが再生するフォールバック レンディション セット (redd.it ホスト上のsource=fallback バリアント) も公開しています。アダプターはこれらをそのまま、低優先のフォールバックとして扱い、プライマリ マニフェストが使用できない場合にのみそれらにアクセスします。これらすべてのケースでの結果は一貫しています。セッションで確認できるものは、ダウンロード可能、多重化、および保存可能です。見えないものは、このツールを含むすべてのツールでは手の届かないところにあります。

5. Reddit ビデオをコンテキスト付きでアーカイブ - フラグを立てずに実行する

Reddit ビデオが単独で存在することはほとんどありません。クリップの価値は、多くの場合、投稿のタイトル、それを説明するトップのコメント、またはその日付を示すサブレディットのコンテキストです。誤った情報の追跡、事件の記録、トレンド調査など、重大な用途で Reddit メディアを取得するアーキビストや研究者は、ファイルと一緒にメタデータを移動する必要があります。そうしないと、アーカイブは数カ月以内に何百もの識別不能なクリップに劣化してしまいます。実際に機能するパターン: 拡張機能名は投稿タイトルからダウンロードされ、ローカル履歴が chrome.storage.local に保存されます。これをサブレディットと日付によるフォルダー スキームと組み合わせると、後で完全なコンテキストが再構築されます。コメントのコンテキストが必要な場合は、ページを表示しているときにビデオの横に投稿 JSON を保存します。これはセッションのデータであり、1 回のコピーと貼り付けであり、来週削除される可能性のあるディスカッションが凍結されます。 レート制限についての正直なエンジニアリングの答えは、ペースが重要であるということです。 Reddit のパブリック エンドポイントは、住宅用 IP からの通常のブラウジングを許容し、スクレイピングのようなパターンに挑戦します。バッチ ダウンローダーは、キューのペースを意図的に調整します (再試行とバックオフでリクエストのタイミングを測定します)。これは、秒単位で数百のリクエストを発行するツールではユーザーのセッションにフラグが立てられ、フラグが立てられたセッションにより、サイトで行う他のすべての操作のエクスペリエンスが低下するためです。代替手段が一時ブロックである場合、設計上遅い方が全体的には速くなります。 プライバシーの枠組みは、このバンドルのすべてのプラットフォームと同じですが、Reddit 特有のしわが 1 つあります。Reddit で閲覧する内容は、健康サブレディット、法的アドバイス、サポート コミュニティなど、関連性の高いものであることが多いです。クラウド ダウンローダーは、保存したすべての投稿 URL を IP に対して記録します。ローカル抽出では、それを自分のディスク上の chrome.storage.local に記録し、クリアするまでそこに残ります。プロの立場でアーカイブを行う人にとって、その違いは競技全体に関わるものです。 目に見えるものをダウンロードし、ローカルに保存し、再共有するときに作成者のクレジットを表示します。これで、Reddit アーカイブのサイレント MP4 時代は終わりました。