菜单

YouTube 提取器

相关源文件

YouTube 提取器是 youtube-dl 中负责从 YouTube 提取视频信息的专用组件。它处理 YouTube 视频交付系统的复杂性,包括 URL 解析、元数据提取、签名解密、身份验证和格式选择。本文档解释了 YouTube 提取器的工作原理以及它如何与其他 youtube-dl 组件交互。

有关提取系统架构的常规信息,请参阅 提取器系统

类层次结构

YouTube 提取器被实现为一个类层次结构,该结构专门用于处理 YouTube 特定的提取逻辑。

来源: youtube_dl/extractor/youtube.py73-593 youtube_dl/extractor/youtube.py594-1084

提取过程概述

YouTube 提取过程遵循复杂的流程来检索和处理视频数据

来源: youtube_dl/extractor/youtube.py2380-2700 youtube_dl/extractor/youtube.py145-327

URL 匹配

YouTube 提取器支持各种 URL 模式,以从 YouTube 及其镜像网站提取视频。_VALID_URL 正则表达式模式定义了所有支持的 URL 格式。

https://www.youtube.com/watch?v=VIDEO_ID         (Standard video URL)
https://youtu.be/VIDEO_ID                        (Short URL)
https://www.youtube.com/embed/VIDEO_ID           (Embed URL)
https://www.youtube.com/shorts/VIDEO_ID          (Shorts URL)

该提取器还通过全面的正则表达式模式支持许多 Invidious 实例(YouTube 前端)。

来源: youtube_dl/extractor/youtube.py596-688

数据提取

初始数据检索

提取器首先下载视频网页并提取两个关键的 JavaScript 对象

  1. ytInitialData - 包含视频的元数据
  2. ytcfg - 包含配置数据,包括 API 密钥

这些对象使用正则表达式提取,然后解析为 JSON。

_YT_INITIAL_DATA_RE = r'(?:window\s*\[\s*["\']ytInitialData["\']\s*\]|ytInitialData)\s*=\s*({.+?})\s*;'
_YT_INITIAL_PLAYER_RESPONSE_RE = r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;'

来源: youtube_dl/extractor/youtube.py347-349 youtube_dl/extractor/youtube.py397-403 youtube_dl/extractor/youtube.py420-424

API 调用

为了检索某些数据,提取器会进行 InnerTube API 调用(YouTube 的内部 API)

提取器支持多种客户端配置文件来发起 API 请求,例如 web、mobile、TV 和 iOS。

来源: youtube_dl/extractor/youtube.py378-395 youtube_dl/extractor/youtube.py89-143

签名解密

YouTube 提取器最复杂的方面之一是签名解密过程。YouTube 使用加密签名来混淆视频 URL,这些签名需要使用 JavaScript 代码进行解密。

JavaScript 解释过程

提取器使用自定义 JavaScript 解释器(JSInterpreter)来执行签名解密代码,而无需依赖外部 JavaScript 引擎。

来源: youtube_dl/jsinterp.py402-1630 youtube_dl/extractor/youtube.py2400-2550

签名函数提取

提取器在 JavaScript 代码中查找特定模式,以识别和提取签名解密函数

  1. 首先,它使用正则表达式模式识别播放器 JavaScript 文件
  2. 然后它使用类似 a=a.split("") 或类似操作的模式提取函数名
  3. 最后,它提取函数体和所有依赖项

来源: youtube_dl/extractor/youtube.py2350-2400 test/test_youtube_signature.py351-443

格式选择和处理

YouTube 提取器检索多种视频格式,包括:

  1. 旧格式(来自 url_encoded_fmt_stream_map
  2. 自适应格式(来自 adaptive_fmts
  3. DASH manifest 格式
  4. HLS (HTTP Live Streaming) 格式

格式类型表

格式类型来源质量范围特性
传统/遗留url_encoded_fmt_stream_map144p-720p合并的音频/视频
自适应adaptive_fmts144p-4K独立的音频/视频流
DASHdashmpd URL144p-8K自适应流,独立流
HLShlsvp URL144p-1080p自适应流,通常合并

每种格式都会被解析并组织成标准化的结构,其中包含分辨率、比特率、编解码器等信息。

来源: youtube_dl/extractor/youtube.py2700-2900

身份验证流程

提取器支持身份验证,以访问私有或年龄限制的视频

来源: youtube_dl/extractor/youtube.py145-327

YouTube 在某些地区需要同意 cookie。提取器通过以下方式处理此问题:

来源: youtube_dl/extractor/youtube.py329-337

年龄限制处理

提取器采用多种策略来访问年龄限制的视频

  1. 使用身份验证(当提供凭据时)
  2. 使用嵌入页面解决方法
  3. 使用电视客户端嵌入解决方法
  4. 使用移动 API 客户端

这些策略按顺序尝试,直到其中一个成功。

来源: youtube_dl/extractor/youtube.py2000-2100

YouTube API 集成

提取器利用 YouTube 的 InnerTube API 进行各种操作

InnerTube 客户端

这些客户端配置允许提取器通过具有不同功能和访问级别的“角色”来访问 YouTube。

来源: youtube_dl/extractor/youtube.py89-143

与 JSInterpreter 的集成

YouTube 提取器在很大程度上依赖 JSInterpreter 模块来处理 JavaScript 代码执行,特别是签名解密。

JSInterpreter 实现了一个基本的 JavaScript 解释器,能够执行签名解密所需的 JavaScript 子集。

来源: youtube_dl/jsinterp.py402-1630 test/test_jsinterp.py1-658

错误处理

YouTube 提取器实现了强大的错误处理机制,以应对各种失败场景

  1. 地理限制视频
  2. 已删除或不可用视频
  3. 私有视频
  4. 年龄限制视频
  5. 需要登录的视频
  6. 签名解密失败

每种错误情况都会提供信息丰富的错误消息以指导用户。

来源: youtube_dl/extractor/youtube.py3000-3100

性能优化

签名缓存

为了提高性能,提取器按播放器 ID 缓存签名解密函数

这可以防止为使用相同播放器版本的视频重复下载和重新解析相同的 JavaScript 代码。

来源: youtube_dl/extractor/youtube.py2380-2385

测试

YouTube 提取器经过广泛测试,专门针对以下方面进行测试:

  1. URL 模式匹配
  2. 签名解密
  3. 播放器信息提取
  4. 格式选择

测试套件包含参考签名和测试用例,以验证签名解密功能。

来源: test/test_youtube_signature.py26-348

总结

YouTube 提取器是一个复杂的组件,可处理从 YouTube 提取视频信息的复杂性。它采用各种技术,包括 JavaScript 解释、API 调用以及处理限制的多种策略。其稳健的设计使其能够适应 YouTube 的频繁更改,并在混淆尝试中保持功能。

该提取器与 JSInterpreter 模块的集成使其能够处理基于 JavaScript 的签名解密,而无需外部依赖,从而使其更具可移植性,并能更好地抵御 YouTube 的反抓取措施。