Bilibili-Evolved 网址AV号转换(avUrl)组件:BV 链接自动改写为 AV 号的实现与注意事项
【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved
Bilibili-Evolved(哔哩哔哩增强脚本)内置了一个名为「网址AV号转换」(组件标识avUrl)的实用组件,用于在用户通过 BV 号链接访问视频时,自动将地址栏中的 BV 号改写为对应的 AV 号。本文以该组件为核心,结合其组件文档与核心实现,讲解它的功能定位、实现原理,以及文档明确警告的浏览器历史记录副作用,帮助读者理解这一改写的底层机制并正确评估是否启用。
功能概述:把 BV 链接自动改写为 AV 链接
B 站视频的链接同时存在两种编号形式:
- BV 号:形如
BV1xx411c7mD,是当前主流的分享链接形式; - AV 号:形如
av170001,是更早的编号体系。
「网址AV号转换」组件的核心行为是:当视频页面的链接是 BV 号时,自动将其转换为对应的 AV 号。它覆盖的不只是普通视频页,也包含番剧(bangumi)播放页,源码中的改写正则/\/(video|bangumi)\/(BV[\w]+)/i同时匹配/video/BV...与/bangumi/BV...两种路径即可佐证(见 av-url/index.ts)。
该组件在官方功能清单中同样有登记,位于 doc/features/features.md,功能标签为「视频」「工具」(tags: [componentsTags.video, componentsTags.utils])。
使用前提与生效范围
组件通过urlInclude: videoUrls限定只在包含视频的页面生效(见 av-url/index.ts)。videoUrls定义于 src/core/utils/urls.ts,包括:
//www.bilibili.com/video/(普通视频页)- 拜年纪等节日活动页面(
festivalUrls,见 urls.ts) - 稍后再看、收藏夹连播、UP 主连播、合集等媒体列表页面(
mediaListUrls,见 urls.ts)
也就是说,在这些页面范围内打开 BV 号链接时,脚本会尝试改写;页面结构不符合匹配条件(如无 AV 号可用)时则保持原样。
实现原理:基于加载时机、URL 监听与历史记录替换的三步流程
组件入口在页面完全加载后启动,整个改写流程可分为三个阶段(源码见 av-url/index.ts):
第一步:等待页面完全加载
入口使用fullyLoaded包装回调。fullyLoaded定义于 src/core/life-cycle.ts:若document.readyState已经是complete则立即执行,否则等待window的load事件。这保证了改写动作发生在页面资源基本就绪之后。
第二步:监听 URL 变化并获取 AV 号
组件通过urlChange注册回调。urlChange定义于 src/core/observer.ts,其内部通过lodash.once保证只初始化一次监听器:借助allMutations观察 DOM 变更,一旦发现document.URL发生变化,就派发自定义的urlChange事件;urlChange在注册时还会立即用当前 URL 调用一次回调,因此首次进入页面时也会触发改写逻辑。
回调内部通过select轮询获取全局对象上的unsafeWindow.aid。select定义于 src/core/spin-query.ts,它会反复执行传入的函数,直到返回非null且非undefined的值为止,适合等待 B 站页面异步填充的播放数据。如果最终拿不到aid,组件直接return,不做任何改写。
第三步:改写 URL 并替换历史记录
拿到aid后,组件先做一次特殊排除:如果当前 URL 包含videocard_series(系列视频相关页面),则跳过改写并打印skip video series日志——源码注释明确指出,系列视频不能转换,否则会触发无限刷新(见 av-url/index.ts)。
随后用正则匹配 URL 中的 BV 段:
const newUrl = document.URL.replace( /\/(video|bangumi)\/(BV[\w]+)/i, (_, type) => `/${type}/av${aid}`, )即把/video/BV1xx...改写为/video/av170001,番剧路径同理。改写使用window.history.replaceState(history.state, '', newUrl)完成(见 av-url/index.ts)。
replaceState的语义是替换当前历史记录条目而不是新增条目,这是理解该组件副作用的关键:它不会在历史堆栈中多压入一条记录,当前地址栏 URL 被原地替换为 AV 号形式,而页面本身不会重新加载,因此改写是无刷新的、对用户几乎无感的。
必须了解的副作用:历史记录重复标题与后退次数增加
这是组件文档中明确警告的内容,属于使用前应当知情的重要注意事项:
请注意这会导致浏览器历史记录出现重复的标题(分别是转换前后的网址),并可能导致后退要多退几次。
其成因与上述replaceState机制相关,可以从实现层面这样理解:你通过某个 BV 链接进入页面时,浏览器历史中已经写入了一条以 BV 链接为地址的记录;脚本随后用replaceState将当前条目替换为 AV 地址,但这条记录原有的标题(来自 BV 链接页面)并不会随之变更。于是你的历史列表里会出现两条「内容相同、标题相近但地址不同」的记录,分别对应转换前后的网址。当你连续多次在不同 BV 链接间跳转并想通过后退返回时,由于每条记录都被拆分成了转换前、转换后两个条目,后退需要的次数会比直观预期更多。
如果你的使用习惯高度依赖浏览器后退键,且对历史记录整洁度敏感,可以考虑关闭该组件;反之,若你更在意地址栏中显示统一的 AV 号形式,则该副作用通常可以接受。
如何在 Bilibili-Evolved 中启用与关闭
「网址AV号转换」属于脚本的常规功能组件,启用/关闭操作与其他组件一致:打开 Bilibili-Evolved 的设置面板,在功能列表中找到「网址AV号转换」(搜索avUrl即可定位),切换开关即可控制是否启用。它不提供额外的配置选项,行为即「开启则自动改写,关闭则保持 BV 链接原样」。由于脚本默认会加载功能清单中启用的组件,关闭后地址栏将不再发生改写。
与其他编号相关组件的区分
Bilibili-Evolved 中还有另一个易混淆的组件「BV 号转换」(bvidConvert),它的作用是在功能面板中显示视频的 AV 号和 BV 号,并提供带标题复制链接等选项(见 bvid-convert/index.md 与 bvid-convert/index.ts)。两者定位不同:avUrl是地址栏层面的静默改写,bvidConvert是面板层的编号展示与复制工具,可按需分别启用。
小结
「网址AV号转换」是一个小而精的实用组件:借助fullyLoaded+urlChange+select的组合(分别来自 life-cycle.ts、observer.ts、spin-query.ts),它能在页面加载后无刷新地把 BV 链接改写为 AV 链接,同时通过replaceState保持历史记录条目数量不变。但正如其官方文档所提示的,这一改写会带来历史记录标题重复、后退次数增多的副作用,是否启用取决于个人对地址栏显示形式与浏览器历史整洁度的权衡。理解其实现机制后,你可以更有把握地决定这个开关的去留。
【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考