From 8dd4d74748b81ac0d317ebda6a535890bda91e3f Mon Sep 17 00:00:00 2001
From: HittyGubby <3488704699@qq.com>
Date: Sat, 4 Oct 2025 15:54:35 +0800
Subject: [PATCH 1/4] bili api semi-integrated revised
---
publish/utils/compileAssets.js | 2 +-
src/lang/en-us.json | 5 +-
src/lang/zh-cn.json | 5 +-
src/lang/zh-tw.json | 5 +-
src/main/modules/userApi/renderer/preload.js | 6 +-
src/renderer/utils/musicSdk/bili/comment.js | 78 +++++++++++++++++
src/renderer/utils/musicSdk/bili/hotSearch.js | 29 +++++++
src/renderer/utils/musicSdk/bili/index.js | 30 +++++++
.../utils/musicSdk/bili/leaderboard.js | 17 ++++
.../utils/musicSdk/bili/musicSearch.js | 77 +++++++++++++++++
src/renderer/utils/musicSdk/bili/songList.js | 86 +++++++++++++++++++
src/renderer/utils/musicSdk/index.js | 8 +-
.../List/components/OpenListModal.vue | 1 +
13 files changed, 342 insertions(+), 7 deletions(-)
create mode 100644 src/renderer/utils/musicSdk/bili/comment.js
create mode 100644 src/renderer/utils/musicSdk/bili/hotSearch.js
create mode 100644 src/renderer/utils/musicSdk/bili/index.js
create mode 100644 src/renderer/utils/musicSdk/bili/leaderboard.js
create mode 100644 src/renderer/utils/musicSdk/bili/musicSearch.js
create mode 100644 src/renderer/utils/musicSdk/bili/songList.js
diff --git a/publish/utils/compileAssets.js b/publish/utils/compileAssets.js
index 8d6fd8df8d..0d2fbc1f83 100644
--- a/publish/utils/compileAssets.js
+++ b/publish/utils/compileAssets.js
@@ -18,7 +18,7 @@ module.exports = () => new Promise((resolve, reject) => {
resolve()
} else {
console.log(chalk.red('Asset compilation failed.'))
- reject()
+ reject(new Error('Asset compilation failed'))
}
})
})
diff --git a/src/lang/en-us.json b/src/lang/en-us.json
index f04971a59c..72cc9b1551 100644
--- a/src/lang/en-us.json
+++ b/src/lang/en-us.json
@@ -613,6 +613,7 @@
"songlist__import_input_tip_1": "Cross-service playlists are not supported. Please confirm whether the playlist to be opened corresponds to the current chosen service",
"songlist__import_input_tip_2": "If you encounter a playlist link that cannot be opened. Please send us your feedback",
"songlist__import_input_tip_3": "Unable to open Kugou playlist with playlist ID or link from lite edition, but support to open it with Kugou code or link from main edition",
+ "songlist__import_input_tip_5": "Captcha needed to view videos of uploader if not logged in, so only public Favlist is supported",
"songlist__import_input_tip_4": "NetEase Cloud Music's \"I Like\" playlist requires a token to open. For details, see ",
"songlist__import_input_title": "Open shared playlist",
"songlist__open_list": "Open \"{name}\" playlist",
@@ -624,6 +625,7 @@
"source_alias_mg": "MG Music",
"source_alias_tx": "TX Music",
"source_alias_wy": "WY Music",
+ "source_alias_bili": "Bilibili",
"source_alias_xm": "XM Music",
"source_all": "Aggregated",
"source_bd": "Baidu",
@@ -632,6 +634,7 @@
"source_mg": "Migu",
"source_tx": "Tencent",
"source_wy": "NetEase",
+ "source_bili": "Bilibili",
"source_xm": "Xiami",
"sync__auth_code_input_tip": "Please enter the connection code",
"sync__auth_code_title": "Need to enter the connection code",
@@ -745,4 +748,4 @@
"user_api_import_online__input_loading": "Importing...",
"user_api_import_online__input_tip": "Please enter an HTTP link",
"user_api_import_online__title": "Import Music API from network."
-}
+}
\ No newline at end of file
diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json
index c5a5242380..6ad8c3d7b7 100644
--- a/src/lang/zh-cn.json
+++ b/src/lang/zh-cn.json
@@ -614,6 +614,7 @@
"songlist__import_input_tip_2": "若遇到无法打开的歌单链接,欢迎反馈",
"songlist__import_input_tip_3": "酷狗源歌单不支持用歌单 ID 或概念版链接打开,但支持用普通版链接或酷狗码打开",
"songlist__import_input_tip_4": "网易源的「我喜欢」歌单需要 Token 才能打开,详情看 ",
+ "songlist__import_input_tip_5": "哔哩哔哩由于未登录状态需过人机验证才能获取 UP 主的上传视频,所以只支持导入公开的收藏夹链接",
"songlist__import_input_title": "打开分享的歌单",
"songlist__open_list": "打开「{name}」歌单",
"songlist__tag_info_hot_tag": "热门标签",
@@ -624,6 +625,7 @@
"source_alias_mg": "小蜜音乐",
"source_alias_tx": "小秋音乐",
"source_alias_wy": "小芸音乐",
+ "source_alias_bili": "哔哩哔哩",
"source_alias_xm": "小霞音乐",
"source_all": "聚合搜索",
"source_bd": "百度音乐",
@@ -632,6 +634,7 @@
"source_mg": "咪咕音乐",
"source_tx": "企鹅音乐",
"source_wy": "网易音乐",
+ "source_bili": "哔哩哔哩",
"source_xm": "虾米音乐",
"sync__auth_code_input_tip": "请输入连接码",
"sync__auth_code_title": "需要输入连接码",
@@ -745,4 +748,4 @@
"user_api_import_online__input_loading": "导入中...",
"user_api_import_online__input_tip": "请输入 HTTP 链接",
"user_api_import_online__title": "在线导入自定义源"
-}
+}
\ No newline at end of file
diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json
index 491563fa56..805e2ccdfd 100644
--- a/src/lang/zh-tw.json
+++ b/src/lang/zh-tw.json
@@ -613,6 +613,7 @@
"songlist__import_input_tip_1": "不支援跨平台開啟歌單,請確認要開啟的歌單與目前歌單的來源平台是否對應",
"songlist__import_input_tip_2": "若遇到無法開啟的歌單連結,歡迎回報",
"songlist__import_input_tip_3": "酷狗音樂歌單不支援用歌單 ID 與概念版連結開啟,但支援用普通版連結與酷狗碼開啟",
+ "songlist__import_input_tip_5": "嗶哩嗶哩由於未登入狀態需過人機驗證才能獲取 UP 主的上傳影片,所以只支援匯入公開的收藏夾連結",
"songlist__import_input_tip_4": "網易雲音樂的「我喜歡」歌單需要 Token 才能開啟,詳情看 ",
"songlist__import_input_title": "開啟分享的歌單",
"songlist__open_list": "開啟「{name}」歌單",
@@ -624,6 +625,7 @@
"source_alias_mg": "小蜜音樂",
"source_alias_tx": "小秋音樂",
"source_alias_wy": "小芸音樂",
+ "source_alias_bili": "嗶哩嗶哩",
"source_alias_xm": "小霞音樂",
"source_all": "聚合搜尋",
"source_bd": "百度音樂",
@@ -632,6 +634,7 @@
"source_mg": "咪咕音樂",
"source_tx": "企鵝音樂",
"source_wy": "網易音樂",
+ "source_bili": "嗶哩嗶哩",
"source_xm": "蝦米音樂",
"sync__auth_code_input_tip": "請輸入連線碼",
"sync__auth_code_title": "需要輸入連線碼",
@@ -745,4 +748,4 @@
"user_api_import_online__input_loading": "匯入中...",
"user_api_import_online__input_tip": "請輸入 HTTP 連結",
"user_api_import_online__title": "從線上匯入自訂來源 API"
-}
+}
\ No newline at end of file
diff --git a/src/main/modules/userApi/renderer/preload.js b/src/main/modules/userApi/renderer/preload.js
index b53ae92efb..c0bbcd945f 100644
--- a/src/main/modules/userApi/renderer/preload.js
+++ b/src/main/modules/userApi/renderer/preload.js
@@ -25,13 +25,14 @@ const eventNames = Object.values(EVENT_NAMES)
const events = {
request: null,
}
-const allSources = ['kw', 'kg', 'tx', 'wy', 'mg', 'local']
+const allSources = ['kw', 'kg', 'tx', 'wy', 'mg', 'bili', 'local']
const supportQualitys = {
kw: ['128k', '320k', 'flac', 'flac24bit'],
kg: ['128k', '320k', 'flac', 'flac24bit'],
tx: ['128k', '320k', 'flac', 'flac24bit'],
wy: ['128k', '320k', 'flac', 'flac24bit'],
mg: ['128k', '320k', 'flac', 'flac24bit'],
+ bili: [],
local: [],
}
const supportActions = {
@@ -41,6 +42,7 @@ const supportActions = {
wy: ['musicUrl'],
mg: ['musicUrl'],
xm: ['musicUrl'],
+ bili: ['musicUrl'],
local: ['musicUrl', 'lyric', 'pic'],
}
@@ -219,7 +221,7 @@ const initEnv = (userApi) => {
body = resp.body = resp.raw.toString()
try {
resp.body = JSON.parse(resp.body)
- } catch (_) {}
+ } catch (_) { }
body = resp.body
callback.call(this, err, {
statusCode: resp.statusCode,
diff --git a/src/renderer/utils/musicSdk/bili/comment.js b/src/renderer/utils/musicSdk/bili/comment.js
new file mode 100644
index 0000000000..5577b48139
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/comment.js
@@ -0,0 +1,78 @@
+import { httpFetch } from '../../request'
+import { dateFormat2 } from '../../index'
+
+export default {
+ async getComment(mInfo, page = 1, limit = 20) {
+ const bvid = mInfo.songmid
+ const url = `https://api.bilibili.com/x/v2/reply?type=1&oid=${bvid}&sort=2&ps=${limit}&pn=${page}`
+ const { body, statusCode } = await httpFetch(url, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.34 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.34',
+ Referer: `https://www.bilibili.com/video/${bvid}/`,
+ },
+ }).promise
+
+ if (statusCode !== 200 || body.code !== 0) throw new Error('获取评论失败')
+
+ return {
+ source: 'bili',
+ comments: this.filterComment(body.data.replies),
+ total: body.data.page.count,
+ page,
+ limit,
+ maxPage: body.data.page.num,
+ }// seems that sorting by time requires state validation but why, this consumes more server resource?
+ }, // you know what, this actually returns the exact same as getHotComment, but consider this scenario
+ // user turns on comment and see pitch blank or simply the same content, then they not even notice
+ // even if they notice, they may just think "lucky me, what are the odds of that", and move on
+
+ async getHotComment(mInfo, page = 1, limit = 20) {
+ const bvid = mInfo.songmid
+ const url = `https://api.bilibili.com/x/v2/reply?type=1&oid=${bvid}&sort=1&ps=${limit}&pn=${page}`
+ const { body, statusCode } = await httpFetch(url, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.34 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.34',
+ Referer: `https://www.bilibili.com/video/${bvid}/`,
+ },
+ }).promise
+
+ if (statusCode !== 200 || body.code !== 0) throw new Error('获取热门评论失败')
+
+ return {
+ source: 'bili',
+ comments: this.filterComment(body.data.replies),
+ total: body.data.page.count,
+ page,
+ limit,
+ maxPage: body.data.page.num,
+ }
+ },
+
+ filterComment(rawList) {
+ if (!rawList) return []
+
+ return rawList.map(item => {
+ return {
+ id: item.rpid,
+ rootId: item.rpid,
+ text: item.content.message.replace(/\\n/g, '\n'),
+ time: item.ctime * 1000,
+ timeStr: dateFormat2(item.ctime * 1000),
+ userName: item.member.uname,
+ avatar: '//wsrv.nl/?url=' + item.member.avatar + '&il',
+ userId: item.member.mid,
+ likedCount: item.like,
+ reply: item.replies ? item.replies.map(reply => ({
+ id: reply.rpid,
+ text: reply.content.message.replace(/\\n/g, '\n'),
+ time: reply.ctime * 1000,
+ timeStr: dateFormat2(reply.ctime * 1000),
+ userName: reply.member.uname,
+ avatar: '//wsrv.nl/?url=' + reply.member.avatar + '&il',
+ userId: reply.member.mid,
+ likedCount: reply.like,
+ })) : [],
+ }
+ })
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/hotSearch.js b/src/renderer/utils/musicSdk/bili/hotSearch.js
new file mode 100644
index 0000000000..3d8ad4f11e
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/hotSearch.js
@@ -0,0 +1,29 @@
+import { httpFetch } from '../../request'
+
+export default {
+ _requestObj: null,
+
+ async getList(retryNum = 0) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+ if (retryNum > 2) return Promise.reject(new Error('try max num'))
+
+ const _requestObj = httpFetch('https://s.search.bilibili.com/main/hotword', {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0',
+ Referer: 'https://www.bilibili.com/',
+ },
+ })
+
+ const { body, statusCode } = await _requestObj.promise
+ if (statusCode != 200 || body.code !== 0) throw new Error('获取热搜词失败')
+
+ return {
+ source: 'bili',
+ list: this.filterList(body.list),
+ }
+ },
+
+ filterList(rawList) {
+ return rawList.map(item => item.keyword).slice(0, 20)
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/index.js b/src/renderer/utils/musicSdk/bili/index.js
new file mode 100644
index 0000000000..ebd126ce8b
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/index.js
@@ -0,0 +1,30 @@
+import leaderboard from './leaderboard'
+import songList from './songList'
+import musicSearch from './musicSearch'
+import { apis } from '../api-source'
+import hotSearch from './hotSearch'
+import comment from './comment'
+
+const bili = {
+ leaderboard,
+ songList,
+ musicSearch,
+ hotSearch,
+ comment,
+
+ getMusicUrl(songInfo, type) {
+ return apis('bili').getMusicUrl(songInfo, type)
+ },
+ getLyric(songInfo) {
+ // ignoring
+ return Promise.resolve({ lyric: '', tlyric: '', rlyric: '', lxlyric: '' })
+ },
+ getPic(songInfo) {
+ return apis('bili').getPic(songInfo)
+ },
+ getMusicDetailPageUrl(songInfo) {
+ return `https://www.bilibili.com/video/${songInfo.songmid}`
+ },
+}
+
+export default bili
diff --git a/src/renderer/utils/musicSdk/bili/leaderboard.js b/src/renderer/utils/musicSdk/bili/leaderboard.js
new file mode 100644
index 0000000000..b7fb7bbf9b
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/leaderboard.js
@@ -0,0 +1,17 @@
+export default {
+ getList(bangid, page = 1, retryNum = 0) {
+ return Promise.resolve({
+ list: [],
+ total: 0,
+ limit: 30,
+ page: 1,
+ source: 'bili',
+ })
+ },
+ getBoards() {
+ return Promise.resolve({
+ list: [],
+ source: 'bili',
+ })
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/musicSearch.js b/src/renderer/utils/musicSdk/bili/musicSearch.js
new file mode 100644
index 0000000000..0dddfd3237
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/musicSearch.js
@@ -0,0 +1,77 @@
+import { httpFetch } from '../../request'
+import { sizeFormate } from '../../index'
+
+export default {
+ limit: 30,
+ total: 0,
+ page: 0,
+ allPage: 1,
+ successCode: 0,
+
+ async musicSearch(str, page, limit, retryNum = 0) {
+ if (retryNum > 2) throw new Error('搜索失败')
+
+ const searchRequest = httpFetch(`https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=${encodeURIComponent(str)}&page=${page}&page_size=${limit}`, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0',
+ Referer: 'https://www.bilibili.com/',
+ Cookie: 'SESSDATA=xxx',
+ },
+ })
+
+ return searchRequest.promise.then(({ body }) => {
+ console.log(body)
+ if (body.code !== this.successCode) return this.musicSearch(str, page, limit, ++retryNum)
+ return body
+ })
+ },
+
+ handleResult(rawList) {
+ const list = []
+ if (!rawList) return list
+ rawList.forEach(video => {
+ if (!video.bvid) return
+ const parts = video.duration.split(':')
+ const minutes = String(parts[0]).padStart(2, '0')
+ const seconds = String(parts[1]).padStart(2, '0')
+ const paddedDuration = `${minutes}:${seconds}`
+ list.push({
+ singer: video.author,
+ name: video.title.replace(/<[^>]+>/g, ''),
+ albumName: video.typename,
+ albumId: video.tid,
+ source: 'bili',
+ interval: paddedDuration,
+ songId: video.bvid,
+ songmid: video.bvid,
+ img: '//wsrv.nl/?url=' + video.pic + '&il',
+ types: [{ type: 'video', size: sizeFormate(video.play), url: `https://www.bilibili.com/video/${video.bvid}` }],
+ _types: { video: { size: sizeFormate(video.play) } },
+ typeUrl: {},
+ })
+ })
+ return list
+ },
+
+ async search(str, page = 1, limit) {
+ if (limit == null) limit = this.limit
+
+ const body = await this.musicSearch(str, page, limit)
+ if (!body.data.result || body.data.result.length === 0) {
+ return Promise.reject(new Error('EMPTY_RESULT'))
+ }
+ const list = this.handleResult(body.data.result)
+
+ this.total = body.data.numResults
+ this.page = page
+ this.allPage = Math.ceil(this.total / limit)
+
+ return {
+ list,
+ allPage: this.allPage,
+ limit,
+ total: this.total,
+ source: 'bili',
+ }
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/songList.js b/src/renderer/utils/musicSdk/bili/songList.js
new file mode 100644
index 0000000000..f025678cf8
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/songList.js
@@ -0,0 +1,86 @@
+import { httpFetch } from '../../request'
+
+export default {
+ limit_song: 20,
+ successCode: 0,
+
+ getList(sortId, tagId, page, tryNum = 0) {
+ return Promise.resolve({
+ list: [],
+ total: 0,
+ page: 1,
+ limit: 20,
+ source: 'bili',
+ })
+ },
+
+ async getListDetail(link, page = 1, limit = 20) {
+ const favIdMatch = link.match(/favlist\?fid=(\d+)/)
+ if (!favIdMatch) return Promise.reject(new Error('无效的Bilibili收藏夹链接'))
+
+ const media_id = favIdMatch[1]
+ const requestObj = httpFetch(
+ `https://api.bilibili.com/x/v3/fav/resource/list?media_id=${media_id}&pn=${page}&ps=${limit}&keyword=&order=mtime&type=0&tid=0&platform=web`,
+ { headers: { Referer: 'https://www.bilibili.com/', Cookie: 'SESSDATA=xxx' } },
+ )
+
+ const { body } = await requestObj.promise
+ if (body.code !== 0) throw new Error('获取收藏夹视频失败')
+
+ const info = body.data.info
+ const medias = body.data.medias || []
+
+ const list = medias.map(video => {
+ const time = video.duration
+ const minutes = Math.floor(time / 60)
+ const seconds = time % 60
+ const paddedDuration = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
+ return {
+ singer: video.upper.name,
+ name: video.title,
+ albumName: null,
+ albumId: null,
+ source: 'bili',
+ interval: paddedDuration,
+ songId: video.bvid,
+ songmid: video.bvid,
+ img: '//wsrv.nl/?url=' + video.cover + '&il', // proxied due to cors
+ types: [],
+ _types: {},
+ typeUrl: {},
+ }
+ })
+
+ return {
+ list,
+ page,
+ limit,
+ total: body.data.info.media_count,
+ source: 'bili',
+ info: {
+ name: info.title,
+ img: '//wsrv.nl/?url=' + info.cover + '&il',
+ desc: info.intro,
+ author: info.upper.name,
+ play_count: info.view_count,
+ },
+ }
+ },
+
+ getTags() {
+ return Promise.resolve({
+ tags: [],
+ hotTag: [],
+ source: 'bili',
+ })
+ },
+
+ search(text, page, limit = 20, retryNum = 0) {
+ return Promise.resolve({
+ list: [],
+ limit,
+ total: 0,
+ source: 'bili',
+ })
+ },
+}
diff --git a/src/renderer/utils/musicSdk/index.js b/src/renderer/utils/musicSdk/index.js
index 58f7568650..737ee22cd5 100644
--- a/src/renderer/utils/musicSdk/index.js
+++ b/src/renderer/utils/musicSdk/index.js
@@ -5,6 +5,7 @@ import wy from './wy/index'
import mg from './mg/index'
import bd from './bd/index'
import xm from './xm'
+import bili from './bili/index'
import { supportQuality } from './api-source'
@@ -34,6 +35,10 @@ const sources = {
name: '虾米音乐',
id: 'xm',
},
+ {
+ name: '哔哩哔哩',
+ id: 'bili',
+ },
// {
// name: '百度音乐',
// id: 'bd',
@@ -46,6 +51,7 @@ const sources = {
mg,
bd,
xm,
+ bili,
}
export default {
...sources,
@@ -109,7 +115,7 @@ export default {
return intv
}
const trimStr = str => typeof str == 'string' ? str.trim() : (str || '')
- const filterStr = str => typeof str == 'string' ? str.replace(/\s|'|\.|,|,|&|"|、|\(|\)|(|)|`|~|-|<|>|\||\/|\]|\[|!|!/g, '') : String(str || '')
+ const filterStr = str => typeof str == 'string' ? str.replace(/\s|'|\.,|,|&|"|、|\(|\)|(|)|`|~|-|<|>|\||\/|\]|\[|!|!/g, '') : String(str || '')
const fMusicName = filterStr(name).toLowerCase()
const fSinger = filterStr(sortSingle(singer)).toLowerCase()
const fAlbumName = filterStr(albumName).toLowerCase()
diff --git a/src/renderer/views/songList/List/components/OpenListModal.vue b/src/renderer/views/songList/List/components/OpenListModal.vue
index 11b5d995b5..6f407308c3 100644
--- a/src/renderer/views/songList/List/components/OpenListModal.vue
+++ b/src/renderer/views/songList/List/components/OpenListModal.vue
@@ -26,6 +26,7 @@
@click="openUrl('https://lyswhut.github.io/lx-music-doc/desktop/faq/cannot-open-songlist')"
>FAQ
+
{{ $t('songlist__import_input_tip_5') }}
{{ $t('songlist__import_input_btn_confirm') }}
From 62445a758ed5a12cc0552e72aadf8d38c6086b07 Mon Sep 17 00:00:00 2001
From: HittyGubby <3488704699@qq.com>
Date: Sat, 4 Oct 2025 15:54:35 +0800
Subject: [PATCH 2/4] bili api semi-integrated revised
---
publish/utils/compileAssets.js | 2 +-
src/lang/en-us.json | 5 +-
src/lang/zh-cn.json | 5 +-
src/lang/zh-tw.json | 5 +-
src/main/modules/userApi/renderer/preload.js | 6 +-
src/renderer/utils/musicSdk/bili/comment.js | 78 +++++++++++++++++
src/renderer/utils/musicSdk/bili/hotSearch.js | 29 +++++++
src/renderer/utils/musicSdk/bili/index.js | 30 +++++++
.../utils/musicSdk/bili/leaderboard.js | 17 ++++
.../utils/musicSdk/bili/musicSearch.js | 77 +++++++++++++++++
src/renderer/utils/musicSdk/bili/songList.js | 86 +++++++++++++++++++
src/renderer/utils/musicSdk/index.js | 6 ++
.../List/components/OpenListModal.vue | 1 +
13 files changed, 341 insertions(+), 6 deletions(-)
create mode 100644 src/renderer/utils/musicSdk/bili/comment.js
create mode 100644 src/renderer/utils/musicSdk/bili/hotSearch.js
create mode 100644 src/renderer/utils/musicSdk/bili/index.js
create mode 100644 src/renderer/utils/musicSdk/bili/leaderboard.js
create mode 100644 src/renderer/utils/musicSdk/bili/musicSearch.js
create mode 100644 src/renderer/utils/musicSdk/bili/songList.js
diff --git a/publish/utils/compileAssets.js b/publish/utils/compileAssets.js
index 8d6fd8df8d..0d2fbc1f83 100644
--- a/publish/utils/compileAssets.js
+++ b/publish/utils/compileAssets.js
@@ -18,7 +18,7 @@ module.exports = () => new Promise((resolve, reject) => {
resolve()
} else {
console.log(chalk.red('Asset compilation failed.'))
- reject()
+ reject(new Error('Asset compilation failed'))
}
})
})
diff --git a/src/lang/en-us.json b/src/lang/en-us.json
index f04971a59c..72cc9b1551 100644
--- a/src/lang/en-us.json
+++ b/src/lang/en-us.json
@@ -613,6 +613,7 @@
"songlist__import_input_tip_1": "Cross-service playlists are not supported. Please confirm whether the playlist to be opened corresponds to the current chosen service",
"songlist__import_input_tip_2": "If you encounter a playlist link that cannot be opened. Please send us your feedback",
"songlist__import_input_tip_3": "Unable to open Kugou playlist with playlist ID or link from lite edition, but support to open it with Kugou code or link from main edition",
+ "songlist__import_input_tip_5": "Captcha needed to view videos of uploader if not logged in, so only public Favlist is supported",
"songlist__import_input_tip_4": "NetEase Cloud Music's \"I Like\" playlist requires a token to open. For details, see ",
"songlist__import_input_title": "Open shared playlist",
"songlist__open_list": "Open \"{name}\" playlist",
@@ -624,6 +625,7 @@
"source_alias_mg": "MG Music",
"source_alias_tx": "TX Music",
"source_alias_wy": "WY Music",
+ "source_alias_bili": "Bilibili",
"source_alias_xm": "XM Music",
"source_all": "Aggregated",
"source_bd": "Baidu",
@@ -632,6 +634,7 @@
"source_mg": "Migu",
"source_tx": "Tencent",
"source_wy": "NetEase",
+ "source_bili": "Bilibili",
"source_xm": "Xiami",
"sync__auth_code_input_tip": "Please enter the connection code",
"sync__auth_code_title": "Need to enter the connection code",
@@ -745,4 +748,4 @@
"user_api_import_online__input_loading": "Importing...",
"user_api_import_online__input_tip": "Please enter an HTTP link",
"user_api_import_online__title": "Import Music API from network."
-}
+}
\ No newline at end of file
diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json
index c5a5242380..6ad8c3d7b7 100644
--- a/src/lang/zh-cn.json
+++ b/src/lang/zh-cn.json
@@ -614,6 +614,7 @@
"songlist__import_input_tip_2": "若遇到无法打开的歌单链接,欢迎反馈",
"songlist__import_input_tip_3": "酷狗源歌单不支持用歌单 ID 或概念版链接打开,但支持用普通版链接或酷狗码打开",
"songlist__import_input_tip_4": "网易源的「我喜欢」歌单需要 Token 才能打开,详情看 ",
+ "songlist__import_input_tip_5": "哔哩哔哩由于未登录状态需过人机验证才能获取 UP 主的上传视频,所以只支持导入公开的收藏夹链接",
"songlist__import_input_title": "打开分享的歌单",
"songlist__open_list": "打开「{name}」歌单",
"songlist__tag_info_hot_tag": "热门标签",
@@ -624,6 +625,7 @@
"source_alias_mg": "小蜜音乐",
"source_alias_tx": "小秋音乐",
"source_alias_wy": "小芸音乐",
+ "source_alias_bili": "哔哩哔哩",
"source_alias_xm": "小霞音乐",
"source_all": "聚合搜索",
"source_bd": "百度音乐",
@@ -632,6 +634,7 @@
"source_mg": "咪咕音乐",
"source_tx": "企鹅音乐",
"source_wy": "网易音乐",
+ "source_bili": "哔哩哔哩",
"source_xm": "虾米音乐",
"sync__auth_code_input_tip": "请输入连接码",
"sync__auth_code_title": "需要输入连接码",
@@ -745,4 +748,4 @@
"user_api_import_online__input_loading": "导入中...",
"user_api_import_online__input_tip": "请输入 HTTP 链接",
"user_api_import_online__title": "在线导入自定义源"
-}
+}
\ No newline at end of file
diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json
index 491563fa56..805e2ccdfd 100644
--- a/src/lang/zh-tw.json
+++ b/src/lang/zh-tw.json
@@ -613,6 +613,7 @@
"songlist__import_input_tip_1": "不支援跨平台開啟歌單,請確認要開啟的歌單與目前歌單的來源平台是否對應",
"songlist__import_input_tip_2": "若遇到無法開啟的歌單連結,歡迎回報",
"songlist__import_input_tip_3": "酷狗音樂歌單不支援用歌單 ID 與概念版連結開啟,但支援用普通版連結與酷狗碼開啟",
+ "songlist__import_input_tip_5": "嗶哩嗶哩由於未登入狀態需過人機驗證才能獲取 UP 主的上傳影片,所以只支援匯入公開的收藏夾連結",
"songlist__import_input_tip_4": "網易雲音樂的「我喜歡」歌單需要 Token 才能開啟,詳情看 ",
"songlist__import_input_title": "開啟分享的歌單",
"songlist__open_list": "開啟「{name}」歌單",
@@ -624,6 +625,7 @@
"source_alias_mg": "小蜜音樂",
"source_alias_tx": "小秋音樂",
"source_alias_wy": "小芸音樂",
+ "source_alias_bili": "嗶哩嗶哩",
"source_alias_xm": "小霞音樂",
"source_all": "聚合搜尋",
"source_bd": "百度音樂",
@@ -632,6 +634,7 @@
"source_mg": "咪咕音樂",
"source_tx": "企鵝音樂",
"source_wy": "網易音樂",
+ "source_bili": "嗶哩嗶哩",
"source_xm": "蝦米音樂",
"sync__auth_code_input_tip": "請輸入連線碼",
"sync__auth_code_title": "需要輸入連線碼",
@@ -745,4 +748,4 @@
"user_api_import_online__input_loading": "匯入中...",
"user_api_import_online__input_tip": "請輸入 HTTP 連結",
"user_api_import_online__title": "從線上匯入自訂來源 API"
-}
+}
\ No newline at end of file
diff --git a/src/main/modules/userApi/renderer/preload.js b/src/main/modules/userApi/renderer/preload.js
index b53ae92efb..c0bbcd945f 100644
--- a/src/main/modules/userApi/renderer/preload.js
+++ b/src/main/modules/userApi/renderer/preload.js
@@ -25,13 +25,14 @@ const eventNames = Object.values(EVENT_NAMES)
const events = {
request: null,
}
-const allSources = ['kw', 'kg', 'tx', 'wy', 'mg', 'local']
+const allSources = ['kw', 'kg', 'tx', 'wy', 'mg', 'bili', 'local']
const supportQualitys = {
kw: ['128k', '320k', 'flac', 'flac24bit'],
kg: ['128k', '320k', 'flac', 'flac24bit'],
tx: ['128k', '320k', 'flac', 'flac24bit'],
wy: ['128k', '320k', 'flac', 'flac24bit'],
mg: ['128k', '320k', 'flac', 'flac24bit'],
+ bili: [],
local: [],
}
const supportActions = {
@@ -41,6 +42,7 @@ const supportActions = {
wy: ['musicUrl'],
mg: ['musicUrl'],
xm: ['musicUrl'],
+ bili: ['musicUrl'],
local: ['musicUrl', 'lyric', 'pic'],
}
@@ -219,7 +221,7 @@ const initEnv = (userApi) => {
body = resp.body = resp.raw.toString()
try {
resp.body = JSON.parse(resp.body)
- } catch (_) {}
+ } catch (_) { }
body = resp.body
callback.call(this, err, {
statusCode: resp.statusCode,
diff --git a/src/renderer/utils/musicSdk/bili/comment.js b/src/renderer/utils/musicSdk/bili/comment.js
new file mode 100644
index 0000000000..5577b48139
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/comment.js
@@ -0,0 +1,78 @@
+import { httpFetch } from '../../request'
+import { dateFormat2 } from '../../index'
+
+export default {
+ async getComment(mInfo, page = 1, limit = 20) {
+ const bvid = mInfo.songmid
+ const url = `https://api.bilibili.com/x/v2/reply?type=1&oid=${bvid}&sort=2&ps=${limit}&pn=${page}`
+ const { body, statusCode } = await httpFetch(url, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.34 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.34',
+ Referer: `https://www.bilibili.com/video/${bvid}/`,
+ },
+ }).promise
+
+ if (statusCode !== 200 || body.code !== 0) throw new Error('获取评论失败')
+
+ return {
+ source: 'bili',
+ comments: this.filterComment(body.data.replies),
+ total: body.data.page.count,
+ page,
+ limit,
+ maxPage: body.data.page.num,
+ }// seems that sorting by time requires state validation but why, this consumes more server resource?
+ }, // you know what, this actually returns the exact same as getHotComment, but consider this scenario
+ // user turns on comment and see pitch blank or simply the same content, then they not even notice
+ // even if they notice, they may just think "lucky me, what are the odds of that", and move on
+
+ async getHotComment(mInfo, page = 1, limit = 20) {
+ const bvid = mInfo.songmid
+ const url = `https://api.bilibili.com/x/v2/reply?type=1&oid=${bvid}&sort=1&ps=${limit}&pn=${page}`
+ const { body, statusCode } = await httpFetch(url, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.34 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.34',
+ Referer: `https://www.bilibili.com/video/${bvid}/`,
+ },
+ }).promise
+
+ if (statusCode !== 200 || body.code !== 0) throw new Error('获取热门评论失败')
+
+ return {
+ source: 'bili',
+ comments: this.filterComment(body.data.replies),
+ total: body.data.page.count,
+ page,
+ limit,
+ maxPage: body.data.page.num,
+ }
+ },
+
+ filterComment(rawList) {
+ if (!rawList) return []
+
+ return rawList.map(item => {
+ return {
+ id: item.rpid,
+ rootId: item.rpid,
+ text: item.content.message.replace(/\\n/g, '\n'),
+ time: item.ctime * 1000,
+ timeStr: dateFormat2(item.ctime * 1000),
+ userName: item.member.uname,
+ avatar: '//wsrv.nl/?url=' + item.member.avatar + '&il',
+ userId: item.member.mid,
+ likedCount: item.like,
+ reply: item.replies ? item.replies.map(reply => ({
+ id: reply.rpid,
+ text: reply.content.message.replace(/\\n/g, '\n'),
+ time: reply.ctime * 1000,
+ timeStr: dateFormat2(reply.ctime * 1000),
+ userName: reply.member.uname,
+ avatar: '//wsrv.nl/?url=' + reply.member.avatar + '&il',
+ userId: reply.member.mid,
+ likedCount: reply.like,
+ })) : [],
+ }
+ })
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/hotSearch.js b/src/renderer/utils/musicSdk/bili/hotSearch.js
new file mode 100644
index 0000000000..3d8ad4f11e
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/hotSearch.js
@@ -0,0 +1,29 @@
+import { httpFetch } from '../../request'
+
+export default {
+ _requestObj: null,
+
+ async getList(retryNum = 0) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+ if (retryNum > 2) return Promise.reject(new Error('try max num'))
+
+ const _requestObj = httpFetch('https://s.search.bilibili.com/main/hotword', {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0',
+ Referer: 'https://www.bilibili.com/',
+ },
+ })
+
+ const { body, statusCode } = await _requestObj.promise
+ if (statusCode != 200 || body.code !== 0) throw new Error('获取热搜词失败')
+
+ return {
+ source: 'bili',
+ list: this.filterList(body.list),
+ }
+ },
+
+ filterList(rawList) {
+ return rawList.map(item => item.keyword).slice(0, 20)
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/index.js b/src/renderer/utils/musicSdk/bili/index.js
new file mode 100644
index 0000000000..ebd126ce8b
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/index.js
@@ -0,0 +1,30 @@
+import leaderboard from './leaderboard'
+import songList from './songList'
+import musicSearch from './musicSearch'
+import { apis } from '../api-source'
+import hotSearch from './hotSearch'
+import comment from './comment'
+
+const bili = {
+ leaderboard,
+ songList,
+ musicSearch,
+ hotSearch,
+ comment,
+
+ getMusicUrl(songInfo, type) {
+ return apis('bili').getMusicUrl(songInfo, type)
+ },
+ getLyric(songInfo) {
+ // ignoring
+ return Promise.resolve({ lyric: '', tlyric: '', rlyric: '', lxlyric: '' })
+ },
+ getPic(songInfo) {
+ return apis('bili').getPic(songInfo)
+ },
+ getMusicDetailPageUrl(songInfo) {
+ return `https://www.bilibili.com/video/${songInfo.songmid}`
+ },
+}
+
+export default bili
diff --git a/src/renderer/utils/musicSdk/bili/leaderboard.js b/src/renderer/utils/musicSdk/bili/leaderboard.js
new file mode 100644
index 0000000000..b7fb7bbf9b
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/leaderboard.js
@@ -0,0 +1,17 @@
+export default {
+ getList(bangid, page = 1, retryNum = 0) {
+ return Promise.resolve({
+ list: [],
+ total: 0,
+ limit: 30,
+ page: 1,
+ source: 'bili',
+ })
+ },
+ getBoards() {
+ return Promise.resolve({
+ list: [],
+ source: 'bili',
+ })
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/musicSearch.js b/src/renderer/utils/musicSdk/bili/musicSearch.js
new file mode 100644
index 0000000000..0dddfd3237
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/musicSearch.js
@@ -0,0 +1,77 @@
+import { httpFetch } from '../../request'
+import { sizeFormate } from '../../index'
+
+export default {
+ limit: 30,
+ total: 0,
+ page: 0,
+ allPage: 1,
+ successCode: 0,
+
+ async musicSearch(str, page, limit, retryNum = 0) {
+ if (retryNum > 2) throw new Error('搜索失败')
+
+ const searchRequest = httpFetch(`https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=${encodeURIComponent(str)}&page=${page}&page_size=${limit}`, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0',
+ Referer: 'https://www.bilibili.com/',
+ Cookie: 'SESSDATA=xxx',
+ },
+ })
+
+ return searchRequest.promise.then(({ body }) => {
+ console.log(body)
+ if (body.code !== this.successCode) return this.musicSearch(str, page, limit, ++retryNum)
+ return body
+ })
+ },
+
+ handleResult(rawList) {
+ const list = []
+ if (!rawList) return list
+ rawList.forEach(video => {
+ if (!video.bvid) return
+ const parts = video.duration.split(':')
+ const minutes = String(parts[0]).padStart(2, '0')
+ const seconds = String(parts[1]).padStart(2, '0')
+ const paddedDuration = `${minutes}:${seconds}`
+ list.push({
+ singer: video.author,
+ name: video.title.replace(/<[^>]+>/g, ''),
+ albumName: video.typename,
+ albumId: video.tid,
+ source: 'bili',
+ interval: paddedDuration,
+ songId: video.bvid,
+ songmid: video.bvid,
+ img: '//wsrv.nl/?url=' + video.pic + '&il',
+ types: [{ type: 'video', size: sizeFormate(video.play), url: `https://www.bilibili.com/video/${video.bvid}` }],
+ _types: { video: { size: sizeFormate(video.play) } },
+ typeUrl: {},
+ })
+ })
+ return list
+ },
+
+ async search(str, page = 1, limit) {
+ if (limit == null) limit = this.limit
+
+ const body = await this.musicSearch(str, page, limit)
+ if (!body.data.result || body.data.result.length === 0) {
+ return Promise.reject(new Error('EMPTY_RESULT'))
+ }
+ const list = this.handleResult(body.data.result)
+
+ this.total = body.data.numResults
+ this.page = page
+ this.allPage = Math.ceil(this.total / limit)
+
+ return {
+ list,
+ allPage: this.allPage,
+ limit,
+ total: this.total,
+ source: 'bili',
+ }
+ },
+}
diff --git a/src/renderer/utils/musicSdk/bili/songList.js b/src/renderer/utils/musicSdk/bili/songList.js
new file mode 100644
index 0000000000..f025678cf8
--- /dev/null
+++ b/src/renderer/utils/musicSdk/bili/songList.js
@@ -0,0 +1,86 @@
+import { httpFetch } from '../../request'
+
+export default {
+ limit_song: 20,
+ successCode: 0,
+
+ getList(sortId, tagId, page, tryNum = 0) {
+ return Promise.resolve({
+ list: [],
+ total: 0,
+ page: 1,
+ limit: 20,
+ source: 'bili',
+ })
+ },
+
+ async getListDetail(link, page = 1, limit = 20) {
+ const favIdMatch = link.match(/favlist\?fid=(\d+)/)
+ if (!favIdMatch) return Promise.reject(new Error('无效的Bilibili收藏夹链接'))
+
+ const media_id = favIdMatch[1]
+ const requestObj = httpFetch(
+ `https://api.bilibili.com/x/v3/fav/resource/list?media_id=${media_id}&pn=${page}&ps=${limit}&keyword=&order=mtime&type=0&tid=0&platform=web`,
+ { headers: { Referer: 'https://www.bilibili.com/', Cookie: 'SESSDATA=xxx' } },
+ )
+
+ const { body } = await requestObj.promise
+ if (body.code !== 0) throw new Error('获取收藏夹视频失败')
+
+ const info = body.data.info
+ const medias = body.data.medias || []
+
+ const list = medias.map(video => {
+ const time = video.duration
+ const minutes = Math.floor(time / 60)
+ const seconds = time % 60
+ const paddedDuration = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
+ return {
+ singer: video.upper.name,
+ name: video.title,
+ albumName: null,
+ albumId: null,
+ source: 'bili',
+ interval: paddedDuration,
+ songId: video.bvid,
+ songmid: video.bvid,
+ img: '//wsrv.nl/?url=' + video.cover + '&il', // proxied due to cors
+ types: [],
+ _types: {},
+ typeUrl: {},
+ }
+ })
+
+ return {
+ list,
+ page,
+ limit,
+ total: body.data.info.media_count,
+ source: 'bili',
+ info: {
+ name: info.title,
+ img: '//wsrv.nl/?url=' + info.cover + '&il',
+ desc: info.intro,
+ author: info.upper.name,
+ play_count: info.view_count,
+ },
+ }
+ },
+
+ getTags() {
+ return Promise.resolve({
+ tags: [],
+ hotTag: [],
+ source: 'bili',
+ })
+ },
+
+ search(text, page, limit = 20, retryNum = 0) {
+ return Promise.resolve({
+ list: [],
+ limit,
+ total: 0,
+ source: 'bili',
+ })
+ },
+}
diff --git a/src/renderer/utils/musicSdk/index.js b/src/renderer/utils/musicSdk/index.js
index 58f7568650..2248449891 100644
--- a/src/renderer/utils/musicSdk/index.js
+++ b/src/renderer/utils/musicSdk/index.js
@@ -5,6 +5,7 @@ import wy from './wy/index'
import mg from './mg/index'
import bd from './bd/index'
import xm from './xm'
+import bili from './bili/index'
import { supportQuality } from './api-source'
@@ -34,6 +35,10 @@ const sources = {
name: '虾米音乐',
id: 'xm',
},
+ {
+ name: '哔哩哔哩',
+ id: 'bili',
+ },
// {
// name: '百度音乐',
// id: 'bd',
@@ -46,6 +51,7 @@ const sources = {
mg,
bd,
xm,
+ bili,
}
export default {
...sources,
diff --git a/src/renderer/views/songList/List/components/OpenListModal.vue b/src/renderer/views/songList/List/components/OpenListModal.vue
index 11b5d995b5..6f407308c3 100644
--- a/src/renderer/views/songList/List/components/OpenListModal.vue
+++ b/src/renderer/views/songList/List/components/OpenListModal.vue
@@ -26,6 +26,7 @@
@click="openUrl('https://lyswhut.github.io/lx-music-doc/desktop/faq/cannot-open-songlist')"
>FAQ
+ {{ $t('songlist__import_input_tip_5') }}
{{ $t('songlist__import_input_btn_confirm') }}
From 3ee78e0afe5d99a71922a5c3e84365ac22370718 Mon Sep 17 00:00:00 2001
From: lyswhut
Date: Sat, 4 Oct 2025 16:42:23 +0800
Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=AD=8C=E5=8D=95?=
=?UTF-8?q?=E3=80=81=E6=8E=92=E8=A1=8C=E6=A6=9C=E6=95=B0=E6=8D=AE=E5=8A=A0?=
=?UTF-8?q?=E8=BD=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/renderer/utils/musicSdk/bili/index.js | 5 +----
src/renderer/utils/musicSdk/bili/leaderboard.js | 17 -----------------
src/renderer/utils/musicSdk/bili/songList.js | 10 +++++++++-
3 files changed, 10 insertions(+), 22 deletions(-)
delete mode 100644 src/renderer/utils/musicSdk/bili/leaderboard.js
diff --git a/src/renderer/utils/musicSdk/bili/index.js b/src/renderer/utils/musicSdk/bili/index.js
index ebd126ce8b..af1957823d 100644
--- a/src/renderer/utils/musicSdk/bili/index.js
+++ b/src/renderer/utils/musicSdk/bili/index.js
@@ -1,4 +1,3 @@
-import leaderboard from './leaderboard'
import songList from './songList'
import musicSearch from './musicSearch'
import { apis } from '../api-source'
@@ -6,7 +5,6 @@ import hotSearch from './hotSearch'
import comment from './comment'
const bili = {
- leaderboard,
songList,
musicSearch,
hotSearch,
@@ -16,8 +14,7 @@ const bili = {
return apis('bili').getMusicUrl(songInfo, type)
},
getLyric(songInfo) {
- // ignoring
- return Promise.resolve({ lyric: '', tlyric: '', rlyric: '', lxlyric: '' })
+ throw new Error('Bilibili暂无歌词接口')
},
getPic(songInfo) {
return apis('bili').getPic(songInfo)
diff --git a/src/renderer/utils/musicSdk/bili/leaderboard.js b/src/renderer/utils/musicSdk/bili/leaderboard.js
deleted file mode 100644
index b7fb7bbf9b..0000000000
--- a/src/renderer/utils/musicSdk/bili/leaderboard.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export default {
- getList(bangid, page = 1, retryNum = 0) {
- return Promise.resolve({
- list: [],
- total: 0,
- limit: 30,
- page: 1,
- source: 'bili',
- })
- },
- getBoards() {
- return Promise.resolve({
- list: [],
- source: 'bili',
- })
- },
-}
diff --git a/src/renderer/utils/musicSdk/bili/songList.js b/src/renderer/utils/musicSdk/bili/songList.js
index f025678cf8..95ba8f46e1 100644
--- a/src/renderer/utils/musicSdk/bili/songList.js
+++ b/src/renderer/utils/musicSdk/bili/songList.js
@@ -3,6 +3,12 @@ import { httpFetch } from '../../request'
export default {
limit_song: 20,
successCode: 0,
+ sortList: [
+ {
+ name: '默认',
+ id: '0',
+ },
+ ],
getList(sortId, tagId, page, tryNum = 0) {
return Promise.resolve({
@@ -70,7 +76,9 @@ export default {
getTags() {
return Promise.resolve({
tags: [],
- hotTag: [],
+ hotTag: [{
+ name: '全部', id: '0', source: 'bili',
+ }],
source: 'bili',
})
},
From 426990f0cdb495d66ac7ecb2a819d800be64570e Mon Sep 17 00:00:00 2001
From: HittyGubby <3488704699@qq.com>
Date: Sun, 5 Oct 2025 15:47:43 +0800
Subject: [PATCH 4/4] bili referer injection
---
src/main/modules/winMain/main.ts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/main/modules/winMain/main.ts b/src/main/modules/winMain/main.ts
index ca6d64ddf9..56f74d295a 100644
--- a/src/main/modules/winMain/main.ts
+++ b/src/main/modules/winMain/main.ts
@@ -70,6 +70,14 @@ export const createWindow = () => {
const proxy = getProxy()
setSesProxy(ses, proxy?.host, proxy?.port)
+ const filter = {
+ urls: ['*://*/*bili*/*']
+ }
+ ses.webRequest.onBeforeSendHeaders(filter, (details, callback) => {
+ details.requestHeaders.Referer = 'https://www.bilibili.com'
+ callback({ requestHeaders: details.requestHeaders })
+ })
+
/**
* Initial window options
*/