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 中读取拆分:一个 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 的网络播放器在播放时使用 MediaSource 扩展将它们拼接在一起:两个 SourceBuffer 实例,一个由视频流馈送,另一个由音频流馈送,在演示时间戳上同步。玩家呈现统一的体验;底层传输从不呈现包含两者的单个文件。 因此,当天真的下载者抓取“视频”时,它会获取它能找到的最大的 DASH_*.mp4 - 并准确地获取该文件的内容:一部完整的、格式良好的无声电影。音频从来没有在里面。在线下载网站也面临着同样的分裂,并在服务器端通过在后端运行 ffmpeg 将曲目混合在一起来覆盖它——直到 Reddit 对其数据中心 IP 进行速率限制、该帖子是 NSFW 并且需要他们的服务器没有的会话 cookie、或者运营商的 ffmpeg 队列被备份并返回 503 为止。 本地优先方法执行相同的多路复用工作,但在浏览器内部:与会话的 cookie 并行获取两个流、解复用、对齐时间戳并写入新的 MP4。没有代理,没有队列,没有静默输出。

2. 客户端复用:如何在没有服务器的情况下将两个文件合二为一

将无声 DASH 视频与其独立的音轨合并听起来像是服务器上 ffmpeg 的一项工作,多年来确实如此。但 MP4 容器格式(正式名称为 ISOBMFF、ISO/IEC 14496-12)是一种结构化的盒层次结构,JavaScript 可以重建它以及给定原始流的任何本机工具。这就是 Video Downloader Bundle 使用 mp4box.js 和 Web Workers 中的本地复用器处理 Reddit 帖子时内部发生的情况。 序列是这样运行的。两个流都并行提取到 ArrayBuffers 中:顶级视频再现 - DASH_1080.mp4(如果可用) - 以及最佳音轨,通常是 128 kbps AAC 文件。 mp4box.js 解析每个缓冲区的盒树:标识容器兼容性的 ftyp、携带轨道元数据的 moov,以及在轨道盒内描述每个帧和音频数据包的示例表(用于计时的 stts、用于块布局的 stsc 和 stsz、用于偏移的 stco)。编解码器私有数据随之而来 - avcC 框保存来自视频轨道的 H.264 参数集,esd 描述来自音频的 AAC 配置。 然后两个时钟得到协调。视频和音频采用不同的时间尺度进行编码,视频轨道通常为每秒 90,000 个刻度,而音频为 44,100 或 48,000 个刻度,因此演示时间戳会重新计算到统一的时间轴上,以保持口型同步准确。合成了一种新的 MP4:新鲜的 ftyp、包含两个轨道的样本表的单个 moov,以及合并到一个 mdat 中的两个流的有效负载。复用器在 mdat(快速启动布局)之前写入 moov,因此文件在完成加载之前就开始播放,并且播放器不会扫描到末尾以查找元数据。 对于一个典型的帖子来说,整个组装只需几秒钟即可完成,并生成一个标准的 MP4,可以在任何地方播放,有声音,可以像任何其他视频一样拖动到 Premiere 或手机图库中。

3. 获取 Muxed MP4:实际工作流程

安装了 Video Downloader Bundle 后,Reddit 是与通用工具的区别最为明显的平台,因为输出是单个完成的文件,而不是无声的孤立文件或仅音频的同级文件。正常浏览 Reddit - 扩展程序的检测器涵盖 old.reddit、new.reddit、sh.reddit 以及 v.redd.it 内容的帖子详细信息页面。视频帖子通过其播放器获得下载按钮,与捆绑包中的所有其他平台相同。 单击它。在底层,适配器解析帖子的媒体:它读取您的会话已经可以访问的帖子 JSON,遍历 DASH 清单以获取可用的演绎版,并选择最高的视频流和最佳音轨。两者都从您的选项卡中并行获取并附加了 cookie - 这悄悄地解决了破坏每个云下载器的 NSFW 情况:隔离的和 18+ subreddit 视频需要您的 reddit_session,而您的浏览器有它,而俄亥俄州的某些服务器没有。多路复用器在工作进程中运行,合并后的 MP4 保存到以帖子标题命名的下载文件夹中。 在 Reddit 上,时机比其他平台更重要,因为内容的流失率很高。版主删除帖子,用户删除自己的论点,而 automod 则实时删除提要。如果您正在保存视频以供参考 - 机械维修剪辑、重新托管之前的新闻剪辑、食谱 - 在您观看时抓住它与计划明天回来确实不同。按钮就在那里的设计反映了这一现实。 关于您在高端获得的内容的说明:Reddit 的源质量上限为上传者提供的任何内容,而 DASH 天梯的最高分辨率为 1080p。音频统一为 64-128 kbps 的 AAC,因为这都是 Reddit 编码。复用器以源质量保留这些流 - 它增加了同步,而不是保真度。

4. 边缘情况:交叉帖子、GIF、已删除的帖子和后备主机

Reddit 的媒体表面有一些边缘情况,将维护的工具与废弃的工具区分开来,并且值得明确每种工具的行为方式。交叉发布是第一个:交叉发布的视频指向 v.redd.it 上原始帖子的媒体,因此适配器通过交叉发布链解析到源媒体,而不是在包装器帖子上失败。您在正在查看的交叉帖子上单击下载并获取原始视频 - 相同的曲目,相同的复用器。在大量联合发布的 r/ subreddits 上,这是大部分流量。 GIF 是第二个,令人惊讶的是,没有涉及视频管道:Reddit 在 i.redd.it 上以直接 .gif 文件的形式提供真正的 GIF 上传,因此下载是文件本身的单次获取,没有混合,没有演绎。一些旧版上传还公开 MP4 转换以实现更流畅的播放;如果两者都存在,则适配器更喜欢 MP4,因为对于相同的内容,MP4 的数量级要小一些。 删除和删除的帖子是诚实的限制:一旦 Reddit 停止向您的会话提供媒体服务,DASH URL 就会随之消失,并且没有任何工具可以恢复平台已从您那里撤回的内容。任何声称可以恢复已删除 Reddit 视频的东西都在向您出售来自某个地方的缓存副本 - 可能是在原始发布者不知情的情况下,这本身就是道德问题。 回退托管是最后一个难题:Reddit 还公开了一个回退再现集 - redd.it 主机上的 source=fallback 变体 - 当 DASH 协商失败时,一些客户端会播放该集。适配器将它们视为较低优先级的回退,并且仅在主清单不可用时才使用它们。所有这些情况的结果都是一致的:您的会话可以看到的是可下载、混合和保存的;它看不到的东西是所有工具都无法触及的,包括这个工具。

5. 将 Reddit 视频与上下文一起归档 - 并且在不被标记的情况下进行

Reddit 视频很少是孤立存在的:剪辑的价值通常是帖子的标题、解释该视频的热门评论或发布该视频的 Reddit 子版块上下文。档案管理员和研究人员将 Reddit 媒体用于重要用途(错误信息跟踪、事件记录、趋势研究),需要元数据与文件一起传输,否则档案会在几个月内退化为数百个无法识别的剪辑。有效的实用模式:扩展名称从帖子标题下载,并在 chrome.storage.local 中保留本地历史记录;将其与 subreddit 和日期的文件夹方案配对可以稍后重建完整的上下文。如果您需要评论上下文,请在页面上时将帖子 JSON 与视频一起保存 - 这是您的会话数据,一次复制粘贴,它会冻结下周可能删除的讨论。 关于速率限制问题,诚实的工程答案是节奏很重要。 Reddit 的公共端点可以容忍住宅 IP 的正常浏览,并挑战看似抓取的模式。批量下载程序故意调整其队列的速度 - 通过重试和退避来测量请求时间 - 因为在几秒钟内触发数百个请求的工具会标记用户的会话,而标记的会话会降低您在网站上执行的所有其他操作的体验。当替代方案是临时块时,设计上较慢的速度总体上会更快。 隐私框架与该捆绑包中的每个平台相同,但有一个 Reddit 特有的问题:您在 Reddit 上浏览的内容通常是敏感的关联 - 健康 subreddits、法律建议、支持社区。云下载器会记录您根据 IP 保存的每个帖子 URL。本地提取会将其记录到您自己磁盘上的 chrome.storage.local,并一直保留在那里,直到您清除它。对于任何以专业身份进行归档的人来说,这种区别就是整个游戏的全部。 下载你能看到的内容,将其保存在本地,转发时归功于创建者 - Reddit 存档的无声 MP4 时代已经结束。