YouTube.js 版本演进全解读:从 v3 到 v18 的 InnerTube 客户端发展路线图
YouTube.js 版本演进全解读:从 v3 到 v18 的 InnerTube 客户端发展路线图
本文以仓库根目录 CHANGELOG.md 为主体脉络,结合 src/ 源码,系统梳理 YouTube.js(youtubei.js)从 v3.0.0 到 v18.0.0 的完整演进历史。读者可以从中掌握:客户端(Client)体系如何从单一 Web 模拟走向多端适配(iOS、Android VR、visionOS、TV 等)、解析器(Parser)与播放器(Player)核心机制的重大重构、以及升级迁移时必须关注的破坏性变更,是一份面向开发者与二次开发者的版本迁移与功能认知指南。
项目与版本总览
YouTube.js 是一个用 TypeScript 编写的 YouTube 内部 API(InnerTube)JavaScript 客户端。从 package.json 可以确认,当前仓库版本为 18.0.0,包名 youtubei.js,采用 ESM 模块("type": "module"),运行时依赖仅三个:@bufbuild/protobuf(protobuf 编解码)、fflate(压缩)与 meriyah(JS 解析器),核心能力均自行实现。
CHANGELOG 记录了从 v3.0.0(2023-02-17)到 v18.0.0(2026-08-13) 三年半间约 15 个大版本、数十个小版本的演进。整体演进脉络可归纳为四条主线:
- 客户端矩阵扩张:从早期模拟 Web 请求,逐步新增 MWEB、TVHTML5、WEB_EMBEDDED、WEB_CREATOR、TV_SIMPLY、ANDROID_VR、VISIONOS 等客户端,以应对 YouTube 对不同端返回不同数据结构的事实。
- 解析器深度重构:引入自动生成 parser 代码、endpoint/command 解析器、view model 解析、continue 机制升级。
- 播放器与流媒体能力增强:签名(sig/nsig)解密算法持续修复、DASH 清单生成能力不断扩展(字幕、DRM、多音轨、SABR 等)。
- 工程化与体验优化:移除 CommonJS、引入会话缓存、AST 级 JS 提取等。
客户端(Client)矩阵的持续扩张
从单一 Web 到多端模拟
InnerTube API 会根据请求携带的 context.client 信息返回不同结构的响应。早期版本主要模拟 WEB 客户端,随后 CHANGELOG 记录了以下客户端的陆续加入:
| 版本 | 新增客户端 | 说明 |
|---|---|---|
| v11.0.0 | TVHTML5、WEB_CREATOR |
TV 大屏端与创作者工作室 Web 端 |
| v12.1.0 | MWEB |
移动 Web 端 |
| v14.0.0 | TV_SIMPLY |
TV 简化版(TVHTML5_SIMPLY) |
| v17.0.0 | ANDROID_VR |
Meta Quest 等 Android VR 端 |
| v18.0.0 | VISIONOS |
Apple Vision Pro 端 |
在 src/utils/Constants.ts 的 CLIENTS 常量中可以看到每个客户端的完整模拟参数。以最新加入的为例:
- VISIONOS:
VERSION: '1.02',DEVICE_MODEL: 'RealityDevice17,1',OS_NAME: 'visionOS',并带有 Safari 内核的 User-Agent; - ANDROID_VR:
VERSION: '1.65.10',DEVICE_MAKE: 'Oculus',DEVICE_MODEL: 'Quest 3',User-Agent 为com.google.android.apps.youtube.vr.oculus/...; - TV_SIMPLY:内部名
TVHTML5_SIMPLY,v14.0.0 修复了它在部分文件中缺失的问题,并在CLIENT_NAME_IDS中补入对应 ID'74'。
从 Constants.ts 的 CLIENT_NAME_IDS 可以看出,每个客户端都对应一个数字 ID(如 WEB: '1'、IOS: '5'、TVHTML5: '7'、VISIONOS: '101'),这些 ID 会写入 InnerTube context。v13.0.0 将客户端名 ID 独立为 CLIENT_NAME_IDS 对象,属于纯性能优化(避免不必要的属性遍历)。
Session 层面的客户端配置能力
客户端不仅仅是一个常量对象。从 src/core/Session.ts 的 SessionArgs 可以看到 Session 支持大量覆盖默认值的选项,这些能力大多是 CHANGELOG 中逐步加入的:
user_agent(v13.0.0 加入):允许为 InnerTube 请求使用固定 User-Agent,替代默认的随机桌面 UA;on_behalf_of_user(v6.3.0 加入):以某个用户身份发起请求;retrieve_innertube_config(v13.4.0 加入):是否在 Session 建立时拉取 YouTube 的 innertube config;fail_fast(v16.0.0 加入):获取会话数据失败时立即抛出错误而非回退;enable_session_cache(v10.0.0 加入):结合 LZW 压缩的会话缓存,避免重复初始化;deviceExperimentId与rolloutToken(v13.4.0 加入):写入 session data 的实验参数。
核心架构演进:解析器(Parser)
解析器是 YouTube.js 的心脏。CHANGELOG 中超过半数条目与 parser 相关,其演进脉络如下。
从手写解析到自动生成
- v4.0.0:解析器大规模重构(#344),并引入 just-in-time YTNode 生成(#310),即从 YouTube 返回的原始 JSON 中按
*Renderer键动态实例化对应节点类。 - v8.1.0:generator 支持数组与 view model 生成(#550、#556)。从仓库 dev-scripts/gen-parser-map.mjs 与 dev-scripts/generate-proto.mjs 可以看到,parser 映射表与 protobuf 生成均已脚本化,构建命令
build:parser-map和build:proto在 package.json 中定义。 - v16.0.0:修正了 gen-parser-map 脚本在自动生成文件中的引用路径(#1036)。
endpoint/command 解析器体系
- v12.0.0:实现 endpoint/command 解析器(#812),将
NavigationEndpoint的解析逻辑下沉为独立的 endpoint 类。仓库 src/parser/classes/endpoints 下现已有 26 个 endpoint 类(如BrowseEndpoint、PlayerEndpoint、SearchEndpoint等),src/parser/classes/commands 下则有ContinuationCommand、RunAttestationCommand等命令类。 - v12.0.0 同时移除了长期废弃的 getter(#815)与旧的评论节点(breaking change)。
节点(YTNode)的持续补充
parser 的演进也体现为大量新节点类的加入。仅从近几个版本看:
- v18.0.0:
VideoDescriptionYouchatSectionView、ThumbnailOverlayAvatarStackView、TicketEvent、TicketShelf; - v17.1.0:
HypeFanCreditsSectionView、ShowSheetCommand/SheetView、ThumbnailOverlayTitleView、PageIndicatorView; - v17.0.0:
VideoSummaryContentView、VideoSummaryParagraphView; - v16.0.0:
Form、FormPopup; - v15.0.0:
CompositeVideoPrimaryInfo、DismissableDialog、HypePointsFactoid、SectionHeaderView、GridShelfView、ToggleFormField。
这些节点在仓库 src/parser/classes 下均有对应文件,例如 VideoSummaryContentView.ts、TicketEvent.ts、SheetView.ts 等。对于二次开发而言,若遇到未知 renderer,可以对照 CHANGELOG 确认是否为新增节点。
结构性数据视图(View)的崛起
YouTube 前端近年大规模切换到以 *View 结尾的结构化数据(如 LockupView、CommentView、ListView)。CHANGELOG 记录了这条迁移线:
- v9.2.0:支持
LockupView及其子节点(#609)、CommentView(#614); - v10.5.0:
ShortsLockupView、BadgeView(#746); - v15.1.0:
ListView、ListItemView、SubscribeButtonView(#1025); - v17.2.0:
ContinuationItemView被当作 continuation 处理(#1193),并修复了播放列表项中 LockupView 的解析。
播放器与流媒体:签名解密与 DASH
签名算法(sig/nsig)的持续对抗
YouTube 的流媒体 URL 签名(signature)与 n 参数(n-token)解密算法会不定期变更。CHANGELOG 中出现频率最高的修复即集中于此:
- v4.0.1、v5.0.0、v10.2.0、v10.3.0、v12.1.0、v12.2.0、v13.2.0、v13.3.0、v13.4.0、v15.1.0、v16.0.0 等多个版本都包含 "Fix extracting the n-token decipher algorithm" 或签名算法提取类修复;
- v15.1.0 修复了解密代码中全局变量提取的问题(#1029);
- v15.1.1 将完整库版本写入缓存条目(#1032),避免不同版本间缓存污染。
这一系列修复的根源在于:YouTube 会动态下发包含解密函数的 JS,客户端需要从中提取并执行。v16.0.0 的重大重构(#1052)将提取方式升级为 AST 级 JS 提取 + 副作用安全(side-effect safe)代码发射,配合 src/utils/javascript/JsAnalyzer.ts 与 src/utils/javascript/JsExtractor.ts 实现,并将 JS 求值器改为 async/await(#1047)。这是 v16 最重要的技术升级之一。
DASH 清单能力扩展
src/utils/DashManifest.tsx 负责 DASH 清单生成,其能力随版本不断扩张:
- v4.0.0:
toDash变为异步(返回Promise<string>),以支持 OTF 格式流的首段获取; - v5.1.0:音频轨道标签写入清单(#402);
- v5.3.0:加入颜色信息(#430),并将重复属性从 Representation 提升至 AdaptationSet(#431);
- v5.6.0:可选在清单中包含缩略图(#446);
- v9.0.0:支持 Post Live DVR 直播回放清单(#580);
- v10.1.0:支持 WebVTT/TTML 字幕(#673)、翻译字幕的 "dub" 角色(#677);
- v15.0.0:DRM 信息写入 MPD。
流媒体格式(Format)字段的精细化
- v6.2.0 修复
is_original恒为 true 的问题(#492); - v9.4.0 新增
projection_type、stereo_layout(#643)、spatial_audio_type(#647); - v10.0.0 新增
is_drc(#656); - v10.2.0 新增
is_secondary用于识别次要音轨(#697); - v13.2.0 从 protobuf 解析 xtags 以支持 SABR-only 响应(#909);
- v14.0.0 在
StreamingInfoOptions中新增is_sabr选项(#974); - v17.0.0 支持 Voice Boost 与 Super Resolution 格式(#1092),并在 StreamingInfo 中标注 Voice Boost 音轨(#1105)。
这些字段定义在 src/utils/FormatUtils.ts 与 src/types/FormatUtils.ts 中,是选择流与构建自定义播放器时的关键依据。
主要破坏性变更与迁移要点
升级 YouTube.js 前,务必关注以下被标记为 ⚠ BREAKING CHANGES 的变更:
v4.0.0
toDash变为异步:toDash(...)现在返回Promise<string>而非string,调用处必须await。
v8.0.0
- 频道 "Channels" 标签被 YouTube 移除:
YT.Channel#getChannels()方法与has_channelsgetter 被删除;推荐频道改由首页 tab 的channelsgetter 获取(见 src/parser/youtube/Channel.ts); - Library 新布局:移除 profile 与 stats 信息。
v10.0.0
- OAuth2 模块重写(#661):auth 模块整体重构,当前实现见 src/core/OAuth2.ts;
Innertube#getPlaylists返回Feed实例而非裸数组。
v12.0.0
Log类转换为纯模块(#814);- 移除旧评论节点与长期废弃的 getter(#815);
- 实现 endpoint/command 解析器(#812)。
v13.0.0
- 移除
web.bundle.min构建产物(当前 package.json 的 exports 中已无该条目)。
v15.0.0
- 完全移除 CommonJS 支持(仅 ESM);
getInfo/getBasicInfo第二参数改为对象:Innertube.getInfo('jNQXAC9IVRw', 'MWEB')必须改写为Innertube.getInfo('jNQXAC9IVRw', { client: 'MWEB' })。Music与Kids客户端类中的同名方法同理。
v17.0.0
- 移除
getTrending(YouTube 已下线 trending feed,#1114); - 搜索过滤器更新(#1136):搜索过滤参数需要按新版 API 调整,实现见 src/parser/youtube/Search.ts。
v18.0.0
- 评论支持线程化(threaded comments)(#1194):评论区数据结构与交互方式变更,详见下文。
高频功能的演进亮点
评论:从 CommentThread 到线程化
评论一直是重点迭代对象。v9.3.0 为 CommentView 实现交互方法(点赞、回复等),v12.0.0 移除旧评论节点,而 v18.0.0 正式支持线程化评论。
从 src/parser/youtube/Comments.ts 可以看到当前的 Comments 类结构:它解析 on_response_received_endpoints 中的头部与正文节点,提取 CommentsHeader、CommentThread 数组与 ContinuationItem,并提供 applySort('TOP_COMMENTS' | 'NEWEST_FIRST') 与 getContinuation() 方法。仓库 src/parser/classes/comments 下还包含 CommentThread.ts、CommentView.ts 等 17 个评论相关节点文件,配套的 examples/comments 目录提供了 CommentThread 与 CommentView 的文档说明。
搜索与建议
- v5.6.0 新增
IncludingResultsFor节点(#447); - v7.0.0
music#getSearchSuggestions改为返回SearchSuggestionsSection数组(breaking); - v13.0.0
getSearchSuggestions增加可选pq参数以获取更精准建议(对应 src/Innertube.ts 中的getSearchSuggestions); - v17.1.0 搜索支持 refinement chips(#1167)。
社区与内容获取
- v3.0.0 支持 hashtag 聚合页(#312),当前 src/Innertube.ts 中
getHashtag通过 protobuf 编码参数并做 URL-safe Base64(u8ToBase64(..., true))后请求FEhashtag,这正是 v18.0.0 修复的内容(#1211,此前误用非 URL-safe 编码); - v13.0.0 新增
getAttestationChallenge(#869,对应 src/Innertube.ts)以及单条社区帖子getPost、帖子评论getPostComments的获取能力(#861); - v6.4.0 支持 字幕/转录(transcript)获取(#500,见 src/parser/youtube/TranscriptInfo.ts 与 examples/transcript);
- v3.0.0 支持 YouTube Kids(#291,src/parser/ytkids),v7.0.0 为其增加
blockChannel命令(#503)。
播放列表与创作者端
- v6.4.0
PlaylistManager增加setName()/setDescription()(#498); - v10.3.0 支持按 set ID 移除视频(#715);
- v13.0.0 播放列表实现
addToLibrary/removeFromLibrary(#844); - v18.0.0
Author#collaborators与Playlist#getCollaborators()(#1203)用于获取协作者; - v11.0.0 支持自动配音音轨(#786)与从观看历史移除视频(#706)。
直播相关
- v12.0.0 起直播聊天节点持续扩充:
LiveChatBannerRedirect、LiveChatBannerChatSummary、LiveChatModeChangeMessage、LiveChatSponsorships*系列(#793、#795、#799、#809、#811); - v13.0.0 更新了
LiveChatPaidMessage、LiveChatPaidSticker、LiveChatTextMessage等节点并新增ReplaceLiveChatAction(#847); - v13.0.0 起
sendMessage能处理RunAttestationCommand(#859,对应 RunAttestationCommand.ts)。
稳定性、性能与工程化
高频 Bug 修复的模式
从 CHANGELOG 可以总结出 YouTube.js 的 Bug 修复呈现三大主题:
- 字段可选性(optionality):YouTube 响应经常缺字段,v13.0.0 修复了
LiveChatTextMessage某些字段缺失、v17.0.0 修复ChannelSubMenu/ContentMetadataView的undefined值、v11.0.0 修复ShortsLockupView假设主文本恒存在等; - 类型不匹配:如 v12.0.0 的
PlaylistAddToOption类型、v10.0.0 的ButtonView#type重命名为button_type、v17.1.0 的ThumbnailBadgeView图标解析; - 参数编码:v13.1.0 修复
getPost参数编码(#882)、v14.0.0 修复getPostComments编码(#955)、v18.0.0 修复getHashtag的 URL-safe Base64(#1211)。
性能优化路线
- v3.2.0~v4.x:parser 性能与 DASH 生成速度优化;
- v5.2.0:搜索结果解析提速(#408)、
toDash格式过滤提速(#405); - v6.4.1:按 info 响应缓存解密后的 n-params(#505);
- v8.0.0:使用具名 Parser 导入以利于打包器建立直接函数引用(#535);
- v10.0.0:会话缓存 + LZW 压缩(#663);
- v13.0.0:DASH 清单生成优化(#870);
- v15.1.0:用
Array#find替换ObservableArray#get(#1013); - v16.0.0:AST 级 JS 提取。
构建与平台支持
- v3.0.0:清理平台支持(#306),为后续多平台打基础;
- v9.2.0:支持 Cloudflare Workers(#596,入口 src/platform/cf-worker.ts,示例见 examples/cloudflare-worker);
- v10.0.0:支持 react-native 平台(#593,src/platform/react-native.ts);
- v15.0.0:deno 条件导出优先级高于 node(#983);
- v9.0.1:修复 webpack 下循环导入导致的构建问题(#81dd5d3);
- v10.5.0:Session 为
hl/gl设置默认值(#7a39326)。
结语:如何用好这份 CHANGELOG
对于 YouTube.js 的使用者与贡献者,这份 CHANGELOG 的价值在于:
- 升级前必读:重点关注各版本顶部
⚠ BREAKING CHANGES区块,特别是 v15 的 ESM-only 与参数对象化、v17 的getTrending移除、v18 的线程化评论,均需要代码层面的适配; - 理解内部机制:签名解密、parser 生成、DASH 生成等条目可以直接对应到 src/utils、src/parser 下的具体实现文件,作为源码阅读的索引;
- 判断版本能力边界:如果需要某个能力(如 SABR、Voice Boost、特定客户端、协作者列表),可以按版本号快速定位引入它的版本与 PR,再对照当前源码确认 API 形态;
- 参与贡献的入口:CHANGELOG 中大量 "Add support for X" 类条目,展示了一个第三方客户端在无官方文档的情况下,如何通过对响应结构的持续逆向与建模保持可用性,这正是 docs/updating-the-parser.md 中所述 "更新解析器" 工作流的实践缩影。
简而言之,这份 CHANGELOG 不仅是一份变更清单,更是一部记录 YouTube 前端数据结构的演化史,是理解 YouTube.js 架构、评估升级风险与定位功能来源的一手资料。