菜单

分段媒体下载器

相关源文件

目的与范围

本文档介绍了 youtube-dl 中分段媒体流的下载器。分段媒体下载器处理将内容分割成多个片段而非作为一个单一文件传输的流媒体格式。这包括 HLS (HTTP Live Streaming)、DASH (Dynamic Adaptive Streaming over HTTP)、F4M (Flash Media Manifest) 和 ISM (IIS Smooth Streaming) 等协议。

有关通用下载器架构的信息,请参阅 下载器系统FileDownloader 基类。有关非分段媒体的 HTTP 下载,请参阅 HTTP 下载器

架构概述

youtube-dl 中的分段媒体下载器共享一个基类,该基类处理下载多个片段并将它们合并成一个文件的核心逻辑。然后,每个特定于协议的下载器实现该协议所需的具体细节。

分段媒体架构

来源: youtube_dl/downloader/fragment.py youtube_dl/downloader/hls.py youtube_dl/downloader/f4m.py youtube_dl/downloader/dash.py youtube_dl/downloader/ism.py

分段下载工作流程

来源: youtube_dl/downloader/fragment.py97-120 youtube_dl/downloader/fragment.py133-167 youtube_dl/downloader/fragment.py268-295

分段下载器基类

FragmentFD 类在 youtube_dl/downloader/fragment.py 提供了所有分段下载器共享的核心功能。它处理以下过程:

  1. 设置下载上下文
  2. 管理片段下载
  3. 跟踪进度
  4. 处理中断下载的续传
  5. 将片段追加到目标文件

FragmentFD 的关键组件

方法目的
_prepare_frag_download设置下载上下文,创建临时文件,处理续传
_start_frag_download初始化进度报告,设置钩子
_download_fragment使用 HTTP 下载器下载单个片段
_append_fragment将下载的片段添加到输出文件
_finish_frag_download完成下载,将临时文件重命名为最终文件名

来源: youtube_dl/downloader/fragment.py youtube_dl/downloader/fragment.py133-167 youtube_dl/downloader/fragment.py206-267 youtube_dl/downloader/fragment.py268-295

分段下载上下文

分段下载过程使用共享的上下文字典来维护下载过程中多个方法调用的状态。上下文中的关键元素包括:

  • filename:最终目标文件名
  • tmpfilename:下载期间的临时文件
  • fragment_index:正在处理的当前片段
  • total_frags:片段总数
  • dest_stream:用于写入片段的文件句柄
  • fragment_filetime:片段的时间戳
  • complete_frags_downloaded_bytes:到目前为止已下载的总字节数

来源: youtube_dl/downloader/fragment.py youtube_dl/downloader/fragment.py206-267

账簿文件 (.ytdl)

对于未完成的分段下载,youtube-dl 会维护扩展名为 .ytdl 的账簿文件。这些 JSON 文件会跟踪:

  • 当前片段索引
  • 片段总数

这使得中断的下载可以在稍后从中断点继续。

{
    "downloader": {
        "current_fragment": {
            "index": [current_fragment_index]
        },
        "fragment_count": [total_fragment_count]
    }
}

来源: youtube_dl/downloader/fragment.py73-96

特定协议下载器

HLS 下载器

HLS (HTTP Live Streaming) 下载器支持 Apple 的 HLS 协议,该协议在 iOS 设备、Apple TV 和许多 Web 平台上广泛用于流媒体。

功能和限制

HlsFD 支持

  • 常规 HLS 流
  • AES-128 加密流(需安装 pycrypto)
  • 过滤广告

HlsFD 无法处理(委托给 FFmpeg)

  • 非 AES-128 加密流
  • 带有媒体初始化片段的流
  • 某些直播流

HLS 下载过程

来源: youtube_dl/downloader/hls.py youtube_dl/downloader/hls.py60-216

F4M 下载器

F4M 下载器处理 Adobe 的 Flash Media Manifest 格式,该格式曾广泛用于基于 Flash 的流。

功能和能力

  • 解析 F4M manifest 以提取引导信息
  • 处理直播和点播流
  • 支持比特率选择
  • 为下载的内容创建 FLV 容器

F4M 下载过程

F4M 下载器

  1. 下载并解析 F4M manifest
  2. 移除任何加密的媒体条目
  3. 根据请求的比特率选择合适的质量级别
  4. 提取引导信息以确定片段
  5. 下载每个片段并将其写入 FLV 容器

来源: youtube_dl/downloader/f4m.py319-438

DASH 下载器

DASH 下载器处理 MPEG-DASH (Dynamic Adaptive Streaming over HTTP) 流,这被 YouTube 等平台广泛使用。

主要功能

  • 支持多种质量级别
  • 处理片段的字节范围请求
  • 失败时重试片段下载
  • 可以跳过不可用的片段

来源: youtube_dl/downloader/dash.py13-83

ISM 下载器

ISM 下载器支持 Microsoft 的 IIS Smooth Streaming 格式。

主要功能

  • 从第一个片段提取轨道元数据
  • 创建适当的容器头
  • 支持片段重试
  • 在需要时处理字节范围请求

来源: youtube_dl/downloader/ism.py206-259

常见挑战与解决方案

处理中断的下载

所有分段下载器都支持通过以下方式恢复中断的下载:

  • .ytdl 文件中的片段索引跟踪
  • 检查临时文件大小
  • 从最后一个成功下载的片段重新开始
if self.__do_ytdl_file(ctx):
    ytdl_file_exists = os.path.isfile(encodeFilename(self.ytdl_filename(ctx['filename'])))
    if continuedl and ytdl_file_exists:
        self._read_ytdl_file(ctx)

来源: youtube_dl/downloader/fragment.py171-193

加密流

  • 当 pycrypto 可用时,HLS 支持 AES-128 加密
  • 其他加密方案需要委托给 FFmpeg 等外部工具

来源: youtube_dl/downloader/hls.py youtube_dl/downloader/hls.py171-181

直播流

直播流带来了特殊的挑战

  • 片段总数未知
  • 下载过程中会出现新片段
  • 旧片段可能变得不可用

HLS 和 F4M 下载器对直播流有特殊的处理方式

  • 限制 HLS 直播流的片段
  • 定期更新 F4M 直播流的片段

来源:youtube_dl/downloader/hls.py36-42 youtube_dl/downloader/f4m.py194-207 youtube_dl/downloader/f4m.py429-434

备用机制

当原生下载器无法处理特定流时

  • HLS 下载器在处理复杂流时会回退到 FFmpeg
  • 重试机制可应对临时网络问题
  • 跳过不可用片段选项有助于部分下载

来源:youtube_dl/downloader/hls.py68-78 youtube_dl/downloader/fragment.py56-62

与提取器系统的集成

分段下载器与提取器系统协同工作,提取器系统提供必要的元数据

  • 清单文件的 URL
  • 分段信息
  • 加密详情
  • 特定协议参数

YouTube、Twitch 和广播媒体网站等提取器通常会在传递给下载器的 info_dict 中提供这些信息。

来源:youtube_dl/downloader/hls.py60-62 youtube_dl/downloader/f4m.py320-322 youtube_dl/downloader/dash.py20-23