Skip to content

B站适配+一些小问题 / bili adapters and minor fixes#2540

Open
HittyGubby wants to merge 6 commits intolyswhut:devfrom
HittyGubby:dev
Open

B站适配+一些小问题 / bili adapters and minor fixes#2540
HittyGubby wants to merge 6 commits intolyswhut:devfrom
HittyGubby:dev

Conversation

@HittyGubby
Copy link
Copy Markdown

因为b站有很多音乐视频嘛,一个一个下下来搞比较难受,就想着加一下b站的适配
但是有些地方适配不了,比如专辑这种东西,到底对应up主呢,还是收藏夹呢,还是合集呢
像是歌单推荐这种也完全没法做,压根没有类似的东西
尝试过用up主的视频列表取代搜索结果中的歌单,但万万没想到最近b站加了个限制,无状态用户查看up主视频竟然还要过captcha,这就没办法了
还考虑过用b站的各个分区取代榜单,但是研究半天了还是搞不出来,貌似也有状态校验和风控
b站的评论也有限制,按时间排序的评论也要登录,所以最热和全部评论其实是同一个结果
还有多分p视频也没法做,本来想在加入歌单什么的时候蹦个弹窗选择分p但是感觉有点混乱
所以总之其实就加了热搜、搜索结果、导入收藏夹(对应导入歌单)、评论(只有一种)

做了相应的i18n,而且用eslint修了一些小问题,要不然每次调试都蹦出来怪烦的
至于其他的平台适配我没改,依然是formatter干的(能不能用prettier给仓库过一下,我本来想一并PR但不好意思)
至于从bvid(对应songmid)拿音频流还是蛮简单的,示例:

  if (source === "bili") {
    await httpFetch(`https://api.bilibili.com/x/web-interface/view?bvid=${musicInfo.songmid}`)
      .then(async (response) => {
        await httpFetch(`https://api.bilibili.com/x/player/playurl?bvid=${musicInfo.songmid}&cid=${response.body.data.cid}&qn=16&fnval=16`).then((res) => {
          returnurl = res.body.data.dash.audio[0].baseUrl || null;
        });
      });
  }

第二个commit是在用户脚本注入那里加了个md5的脚本,可有大用处了,比如酷狗的api必须得用md5,就可以避免用自定义脚本90%的空间写一堆奇奇怪怪的天书

@HittyGubby HittyGubby force-pushed the dev branch 3 times, most recently from c09020b to fe4e022 Compare October 3, 2025 21:23
@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 3, 2025

哦再提一嘴哈,细心的可能会发现我fork的介绍里加了个音乐标签分类,这是我打算做的一个功能
目前的列表数据结构是两层树,我觉得两层标签(属性)更好更全面,比如:
{genre:{pop, disco, synthwave}, country:{yugoslav, honduras, antarctica}, language: {中文, srbija}}
用户可以自定义标签和标签种类,根据标签种类动态划分出来列表,可以给所有歌曲分配标签,不用纠结列表无限细分或移来移去等问题,只需要分配标签即可
不过这会对现有数据结构造成严峻挑战,比如能否适应本地数据库?
能否适配旧列表做好无缝切换,还是需要外置转换器?
如果沿用旧数据结构,是否可以在侧栏增加一个新入口,从而不影响既有功能?
最重要的,这是否得不偿失?

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

感谢PR,本项目使用 npm 管理项目,PR不要带上其他包管理器的文件,package.json 并不需要加这些多余的依赖,既然已经清除html标签,hedecode 应该可以使用 innerHTML 代替,重命名 sizeFormat 建议在另一个 PR 中提交,这样更改的文件应该会少很多,另外我看了 src/renderer/views/songList/List/components/OpenListModal.vue 的格式化似乎有问题,md5 加密目前就有提供,在 lx.utils.crypto.md5

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

改好啦
he的decode好像压根没用上(?我加他干嘛的来着)

补充一点,我在测试bili的自定义源时遇到Cannot read properties of undefined (reading 'getMusicUrl'),但是脚本里写了相应的情况(如上面的示例),不知道这是脚本的问题还是代码的问题?

@HittyGubby
Copy link
Copy Markdown
Author

另外手机版也需要相应适配吗

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

image

我看了下,你给的获取音频链接的方式,拿到的是m4s的文件,浏览器似乎播放不了?

搜索结果返回的是视频内容的列表,确定内容是可以播放的吗

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

啊是的...
当时用DASH是因为他天然提供音视频分离,其他的没有这个条件
也许可以加个支持m4s的库或者用ffmpeg什么的转一下(?

搜索结果返回列表和可否播放有关系吗(?

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

不对,m4s虽然无法直接播放,但是DASH是支持的,比如尝试把后缀名改一下就可以在浏览器播放
改:不对啊好像也可以直接播放,只是b站的cdn默认octet-stream了吧

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

我试了下 listen1 的播放,m4s是可以直接播放的,但是播放链接需要加 Refererhttps://www.bilibili.com/ 请求头,一时没搞清楚它是怎么加的,也不确定这是否适用于lx: https://github.com/listen1/listen1_chrome_extension/blob/master/js/provider/bilibili.js

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

进一步研究,是注入了请求头:https://github.com/listen1/listen1_chrome_extension/blob/24f04d3c9e80f1b076006aff493d312e0bfe6871/js/background.js#L70

遗憾的是这目前并不适用于LX,如果非要支持的话,也得添加相关功能,并且它的音频并不是mp3之类的格式,会导致下载功能异常,权衡后觉得改动太大,还是决定不添加这个源 :(

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

覆写referer好像不是必须的吧?我用mpv/curl都可以直接下载/播放,只提供url即可
另外为什么不是mp3就会下载异常
补充一下,一些视频返回的body.data.dash.audio[0].baseUrl可能404,还是audio[1]更保险一点

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

据测试现在似乎是必须的,你可以试试

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

经测试确实没区别(
CopyQ zOQaXQ
等下,你说的是获取播放链接的api还是播放链接本身

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

我说的是播放链接本身,你直接把链接粘贴到浏览器地址栏打开会发现打不开,或者写一个自定义源测试下就知道了

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

对啊,连mpv/curl这种无状态的都能成功下载,不更说明这其实是返回Content-Type设置为octet-stream的原因吗
比如说你把m4s文件下下来放在自建的文件服务器上,就发现可以正常播放,因为m4s默认确实不是octet-stream,不会触发下载
另,我之前用别的平台自定义源的时候也遇到过octet-stream,但是能成功播放,这个应该不是主要原因
我写的自定义源和最上面的示例一样,不过返回的错误提示是Cannot read properties of undefined (reading 'getMusicUrl'),不知道这是脚本还是代码的问题

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

想要重现也很简单,你创建一个简单静态HTML文件,里面加个audio标签,将你拿到的链接设置到src上看能不能播放就知道了

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

可以播放,你那边不行吗?
图二我覆写了返回的content-type,就不会触发下载而是老老实实播放了
CopyQ oKVmiv
CopyQ HaDkxs

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

我这边测试是返回403,是不是你那边的网络进行了什么处理?
我看 listen1 支持的第一个版本也包含覆盖:listen1/listen1_chrome_extension@bcbc152#diff-c4c3080a6565c37661d66c7836cb5f5c90921cf68289c4b6707a4f1a55511139R36-R49

@HittyGubby
Copy link
Copy Markdown
Author

我除了挂梯子没有别的网络处理,会不会是比如你的浏览器装了什么插件屏蔽了?
刚刚关了梯子尝试是一样的,毕竟b站cdn代理应该默认也是白名单
listen1的确实进行了覆写,但重点是其是否是必须的,就我测试结果看应该是非必要

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

你可以修改这个方法,将传入的src重新赋值为你获取到的url,如果仍然可以播放,那估计是你那边网络特殊或者那个url确实不受限制?

if (audio) audio.src = src

listen1的确实进行了覆写,但重点是其是否是必须的,就我测试结果看应该是非必要

我这边测试了如果不加那个请求头那么listen1也无法播放

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

刚刚改成了if (audio) audio.src = ‘https://......‘ ,成功播放对应的m4s音频!
很好奇你那边用的是什么网络?或浏览器有何限制?可否开个新浏览器配置,或用无状态cli工具(如curl)试试?
CopyQ SxAGBU

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

我这边不行:
image

你那边拿到的链接是怎样的?发下出来?
我这边拿到的是:https://upos-sz-mirrorcoso1.bilivideo.com/upgcxcode/69/81/32831048169/32831048169-1-30216.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&oi=1866074286&trid=dce7103293dc4915bd5910007eec1eeu&gen=playurlv3&os=coso1bv&deadline=1759584978&og=cos&nbs=1&uipk=5&platform=pc&mid=0&upsig=2c07e2b8be4c115fb63850d4cbc966e4&uparams=e,oi,trid,gen,os,deadline,og,nbs,uipk,platform,mid&bvc=vod&nettype=0&bw=323459&agrr=0&buvid=&build=0&dl=0&f=u_0_0&orderid=0,3

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

我链接是这个:https://xy182x89x195x24xy.mcdn.bilivideo.cn:8082/v1/resource/1620385010-1-30280.m4s?agrr=0&build=0&buvid=1DD826FB-78D1-3884-F71A-AE467557B5D656251infoc&bvc=vod&bw=168187&deadline=1759585277&dl=0&e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M%3D&f=u_0_0&gen=playurlv3&mid=329360530&nbs=1&nettype=0&og=ali&oi=0x240e03603d08d7000e5415fffe809391&orderid=0%2C3&os=estgoss&platform=pc&sign=88fae7&traceid=trIBfuvqjOVHBU_0_e_N&uipk=5&uparams=e%2Ctrid%2Cdeadline%2Cplatform%2Cmid%2Cnbs%2Cgen%2Cos%2Cuipk%2Cog%2Coi&upsig=8ed6d1161ae4396f94cade7131168b91

和你那边cdn的地址大有不同,不会是运营商的问题吧?
另外你那个链接好像就算加了referer也是403啊...

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 4, 2025

不清楚,我这边是移动的网
获取地址:https://api.bilibili.com/x/player/playurl?bvid=BV19vxxzyE5T&cid=32831048169&qn=16&fnval=16

image image

还有可能是你获取URL的时候加了什么 cookie 之类的,我获取的时候什么都不传

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

这就很奇怪了,我也是无状态的,没有cookie,跟你一模一样的地址,难不成真是运营商干的?我是电信的
CopyQ xVoxoy
CopyQ zPfVXY

@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 4, 2025

不过确实,我发现upos-sz-mirrorcoso开头的好像确实访问失败,*.mcdn.bilivideo的就没问题
而且访问失败与否在我这似乎与UA有关,而非referer(?诡异
还有之前问的那个问题,我这边如果获取链接并直接播放可以的话为什么会出现Cannot read properties of undefined (reading 'getMusicUrl')?

@lyswhut
Copy link
Copy Markdown
Owner

lyswhut commented Oct 5, 2025

我试了这个是没问题的:

/**
 * @name 测试音乐源
 * @description 我只是一个测试音乐源哦
 * @version 1.0.0
 * @author xxx
 * @homepage http://xxx
 */


const { EVENT_NAMES, request, on, send } = globalThis.lx

on(EVENT_NAMES.request, ({ source, action, info }) => {
  // 被调用时必须返回 Promise 对象
  switch (action) {
    // action 为 musicUrl 时需要在 Promise 返回歌曲 url
    case 'musicUrl':
      return Promise.resolve('https://upos-sz-mirrorcos.bilivideo.com/upgcxcode/69/81/32831048169/32831048169-1-30216.m4s')
  }
})

// 脚本初始化完成后需要发送 inited 事件告知应用
// 注意:初始化事件被发送前,执行脚本的过程中出现任何错误将视为脚本初始化失败
send(EVENT_NAMES.inited, {
  openDevTools: true, // 是否打开开发者工具,方便用于调试脚本
  sources: { // 当前脚本支持的源
    bili: { // 支持的源对象,可用 key 值:kw/kg/tx/wy/mg/local
      name: '哔哩哔哩',
      type: 'music',  // 目前固定为 music
      actions: ['musicUrl'], // 除了 local 外,其他的固定为 ['musicUrl']
      qualitys: [],
    },
  },
})

HittyGubby added a commit to HittyGubby/LX-Source-Vanced that referenced this pull request Oct 5, 2025
@HittyGubby
Copy link
Copy Markdown
Author

HittyGubby commented Oct 5, 2025

草,才发现没在最后面注册b站的源对象(逃
修好之后发现可以正常播放的
另外手机版适配怎么办?
还有之前提到的标签分类可以做吗

目前的列表数据结构是两层树,我觉得两层标签(属性)更好更全面,比如:
{genre:{pop, disco, synthwave}, country:{yugoslav, honduras, antarctica}, language: {中文, srbija}}
用户可以自定义标签和标签种类,根据标签种类动态划分出来列表,可以给所有歌曲分配标签,不用纠结列表无限细分或移来移去等问题,只需要分配标签即可

@HittyGubby
Copy link
Copy Markdown
Author

另提一个问题,由于b站头像/封面有cors问题所以加了一个图片代理,但build并使用的时候发现头像/封面都无法正常显示,dev的时候是可以的
CopyQ fWYvik

@HittyGubby
Copy link
Copy Markdown
Author

研究之后发现好像短视频的cdn确实有referer限制,长视频的没有
不过注入referer好像也不难的说,只要在src/main/modules/winMain/main.ts ln72那块注入一个header就好,比如:

  const filter = {
    urls: ['*://*/*bili*/*']
  }
  ses.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
      details.requestHeaders.Referer = 'https://www.bilibili.com'
    callback({ requestHeaders: details.requestHeaders })
  })

我改过了,已经放PR里了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants