dsh-bili-audio:把 B 站视频当播客听的 DSH 插件

前言

DSH 插件以「一切皆插件」为理念,将宿主能力按需挂载到 Web 界面。开发者在用 DSH 智能体时,常需要从视频网站获取音频内容。直接在 Web 界面嵌入 <audio> 会遇到 CDN 的 Referer 校验,导致 403 错误。dsh-bili-audio 插件通过宿主侧的反向代理解决这一问题,让用户在浏览器里就能播放 B 站音频。

插件定位

dsh-bili-audio 是一个「B 站音频悬浮播放条」DSH 插件,由维护者 lihua12345670-jpg 在 GitHub 开源。它将 B 站视频转为播客音频,在 DSH Web 界面右下角挂一个圆形「♪」按钮,展开后是播放条。支持队列、进度、音量、倍速、上一条/下一条,队列和最近播放记在本地,刷新后还在。

核心功能

  • 音频解析:支持视频页链接(BV 号、av 号、短链)、番剧 ep/ss 链接或编号(ep123、ss123)、媒体页(会先换成对应季再播放第一集正片)。
  • 播放控制:展开播放条后,支持空格/媒体播放键播放/暂停,←/→ 后退/前进 10 秒,Shift+←/Shift+→ 上一条/下一条。
  • 队列管理:多条用空格、换行或逗号分开会依次入队,Shift+Enter 为「只入队」不抢占当前播放。队列里可切歌、× 移除,支持「按标题排序」「清空」。队列最多保留 100 条。
  • 本地持久化:队列、最近播放(最多 30 条)、音量、倍速、展开/收起状态保存在浏览器 localStorage,不上传。
  • 代理音频流:宿主侧的 /bili-audio/api/stream 代理 B 站音频 CDN,解决 Referer 403,支持 Range 与 206,进度条可拖动。
  • 错误处理:播放失败会自动尝试备用 CDN 地址并重新解析(B 站音频地址带 deadline,过期只能重取)。失败原因直接写在队列行上(最多两行,悬停可看全文)。

安装与启用

克隆仓库后从本地目录安装(把路径换成你的副本;--profile 按实际 profile 名,桌面版通常是 desktop):

git clone https://github.com/lihua12345670-jpg/dsh-bili-audio.git
dsh plugin --profile desktop add link:./dsh-bili-audio

若包已发布到 npm:

dsh plugin --profile desktop add dsh-bili-audio

安装后在 DSH Web 界面右下角会出现一个「♪」圆形按钮,点开是播放条;也可以在「设置 → 插件」里确认 dsh-bili-audio 已加载。

典型用法

  1. 点右下角「♪」展开播放条;
  2. 粘贴 B 站链接或编号:
    - 视频页 https://www.bilibili.com/video/BV...、b23.tv 短链、BV 号、av 号;
    - 番剧 https://www.bilibili.com/bangumi/play/ep...、.../ss...、b23.tv/ep...、b23.tv/ss...,或裸编号 ep123 / ss123;
    - 媒体页 .../bangumi/media/md... 会先换成对应季,再播放第一集正片;
  3. 点「解析并播放」(输入框里按 Enter 等价;Shift+Enter 是「只入队」);
  4. 多条用空格、换行或逗号分开:会依次加入队列。「只入队」不抢占当前播放;
  5. 队列里点任意一条切歌,× 移除,「按标题排序」「清空」在队列头部。失败原因直接写在该行上(最多两行,悬停可看全文)。

ss 和媒体页没有指定集时播放第一集正片,不读取观看进度(那需要登录)。?ep_id= 或路径里的 ep 会点名那一集。

接口说明

方法 路径 说明
GET /bili-audio/api/health {ok:true, version}
GET /bili-audio/api/resolve?url=<BV/av/ep/ss/链接> {ok:true, title, bvid, cid, duration, page, pages, audioUrl, backups[], mimeType, codecs}。番剧还会带 epId、seasonId
GET /bili-audio/api/stream?u=<urlencoded audioUrl> 反向代理音频字节,支持 Range 与 206

错误统一是:

{ "error": { "code": "no_audio_stream", "message": "这个视频没有可用的音频流(可能是充电专属、付费或地区限制内容)" } }

安全边界

插件挂了一个「替浏览器发请求」的路由,白名单是硬编码的,不是配置项:

  • resolve 只接受 bilibili.com / b23.tv / bilibili.tv 的页面链接(含子域);
  • stream 只代理 *.bilivideo.com、*.akamaized.net、*.mcdn.bilivideo.cn、*.bilibili.com;
  • 跟随 CDN 重定向后会再校验一次最终主机,避免 CDN 302 到别处把插件当跳板;
  • 拒绝带用户名/密码的 URL、非 http(s) 协议、IP 字面量(127.0.0.1、[::1]);
  • 只透传浏览器的 Range,不转发 Cookie / Authorization 等其它请求头;
  • 单次外呼 15 秒超时;客户端断开时立刻取消上游连接。

它不是一个通用 CORS/代理工具:任何不在上述白名单里的 URL 都会得到 400。

适用场景与注意

适合需要在 DSH 环境里直接播放 B 站音频内容的开发者或用户。插件以当前 DSH 进程权限运行,音频字节通过宿主代理获取,不直接在浏览器里请求 CDN。安装前应检查源码与许可证(MIT)。

已知限制(v0.2):

  • 没有字幕、登录、Cookie、下载、离线缓存。原 Python 版的 CC/AI 字幕需要登录 Cookie,这个插件不读 Cookie,也不把浏览器的 Cookie / Authorization 转给 B 站;
  • 需要联网:解析与播放都依赖 B 站接口与 CDN。队列元数据在本地,音频字节不缓存;
  • 充电专属、付费、大会员、地区限制、需要登录的内容可能没有音频流,会返回 no_audio_stream 或 bangumi_restricted;
  • 番剧 ss / 媒体页只解析一集(第一集正片,或 ep / ?ep_id= 点名的那一集),不会把整季自动塞进队列;
  • 直播、课堂、专栏、空间、音频区链接会得到 unsupported_link,不会当成视频去猜;
  • 播放依赖浏览器的自动播放策略:解析后的自动播放若被拦截,点一下播放按钮即可。刷新页面也不会自动开播。

结尾

dsh-bili-audio 让 DSH 用户可以在浏览器里直接播放 B 站音频,解决 CDN Referer 403 问题,并提供队列、进度、倍速等常用控制。队列和最近播放记在本地,不上传。插件以宿主代理方式处理音频流,白名单硬编码,不转发 Cookie 或其它请求头。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜