mirror of
https://github.com/the1812/Bilibili-Evolved.git
synced 2025-11-04 21:22:45 +08:00
Add danmaku segment
This commit is contained in:
parent
0c2eb23cb0
commit
9768468638
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -58,6 +58,7 @@
|
||||
"medialist",
|
||||
"overscroll",
|
||||
"pako",
|
||||
"protobuf",
|
||||
"qrcode",
|
||||
"reloadable",
|
||||
"reloadables",
|
||||
|
||||
@ -43,6 +43,8 @@
|
||||
| Fast.io | <1h | 快 | [安装](https://lunatic-kingdom.imfast.io/bilibili-evolved.user.js) | [安装](https://subterranean-rose.imfast.io/bilibili-evolved.preview.user.js) | [安装](https://lunatic-kingdom.imfast.io/bilibili-evolved.offline.user.js) | [安装](https://subterranean-rose.imfast.io/bilibili-evolved.preview-offline.user.js) |
|
||||
| GitHub | <1h | 慢 | [安装](https://github.com/the1812/Bilibili-Evolved/raw/master/bilibili-evolved.user.js) | [安装](https://github.com/the1812/Bilibili-Evolved/raw/preview/bilibili-evolved.preview.user.js) | [安装](https://github.com/the1812/Bilibili-Evolved/raw/master/bilibili-evolved.offline.user.js) | [安装](https://github.com/the1812/Bilibili-Evolved/raw/preview/bilibili-evolved.preview-offline.user.js) |
|
||||
|
||||
> Fast.io 年底将停止使用, 如果你在 2021 年看到我这里还没把 Fast.io 源删掉, 也请不要用 Fast.io 源进行安装.
|
||||
|
||||
## 推荐配置
|
||||
- 操作系统: 64-bit Windows 10 / macOS 10.15
|
||||
- 分辨率: 2K
|
||||
@ -82,6 +84,7 @@
|
||||
支持**最新版** Chrome, Edge (Chromium 内核), Firefox, Safari, 不保证脚本能在["套壳类浏览器"](https://www.jianshu.com/p/67d790a8f221)或者较长时间没更新的浏览器中完美运行.
|
||||
|
||||
UWP 版 Edge 已经不再支持了(就是 Windows 10 自带的那个), 请使用以上列出的浏览器, 或换用 [Chromium 内核的 Edge](https://www.microsoft.com/en-us/edge).
|
||||
> Windows 10 20H2 更新中好像完全替换掉了 UWP 版 Edge (R.I.P.) 自带浏览器变成了 Chromium 内核 Edge.
|
||||
|
||||
# 关于源码
|
||||
虽然本项目的源代码是公开的, 但是我并不推荐您花太多时间阅读这些代码. 因为这是我的第一个JavaScript项目, 它包含了从我初学JavaScript到如今形成一定风格以来写下的各种代码(各种祖传代码), 不同的几个模块可能风格差异会很大, 像是早期DOM操作经常使用jQuery到后期转向原生API和Vue, 4空格缩进变成2空格缩进等等. 一些比较复杂的模块里也是放飞自我.
|
||||
@ -133,6 +136,11 @@ UWP 版 Edge 已经不再支持了(就是 Windows 10 自带的那个), 请使用
|
||||
- [主页](https://s.xmcp.ml/pakkujs/)
|
||||
- [GitHub](https://github.com/xmcp/pakku.js)
|
||||
|
||||
## BLTH - Bilibili Live Tasks Helper
|
||||
作者: [andywang425](https://github.com/andywang425)
|
||||
- [GitHub](https://github.com/andywang425/BLTH)
|
||||
- [GreasyFork](https://greasyfork.org/zh-CN/scripts/406048-b%E7%AB%99%E7%9B%B4%E6%92%AD%E9%97%B4%E6%8C%82%E6%9C%BA%E5%8A%A9%E6%89%8B)
|
||||
|
||||
----
|
||||
|
||||
**喜欢的话就点个⭐Star吧(°∀°)ノ**
|
||||
|
||||
1
min/danmaku-segment.min.js
vendored
Normal file
1
min/danmaku-segment.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
(()=>(settings,resources)=>{const proto={nested:{DmWebViewReply:{fields:{state:{type:"int32",id:1},text:{type:"string",id:2},textSide:{type:"string",id:3},dmSge:{type:"DmSegConfig",id:4},flag:{type:"DanmakuFlagConfig",id:5},specialDms:{rule:"repeated",type:"string",id:6},checkBox:{type:"bool",id:7},count:{type:"int64",id:8},commandDms:{rule:"repeated",type:"CommandDm",id:9},dmSetting:{type:"DanmuWebPlayerConfig",id:10}}},CommandDm:{fields:{id:{type:"int64",id:1},oid:{type:"int64",id:2},mid:{type:"int64",id:3},command:{type:"string",id:4},content:{type:"string",id:5},progress:{type:"int32",id:6},ctime:{type:"string",id:7},mtime:{type:"string",id:8},extra:{type:"string",id:9},idStr:{type:"string",id:10}}},DmSegConfig:{fields:{pageSize:{type:"int64",id:1},total:{type:"int64",id:2}}},DanmakuFlagConfig:{fields:{recFlag:{type:"int32",id:1},recText:{type:"string",id:2},recSwitch:{type:"int32",id:3}}},DmSegMobileReply:{fields:{elems:{rule:"repeated",type:"DanmakuElem",id:1}}},DanmakuElem:{fields:{id:{type:"int64",id:1},progress:{type:"int32",id:2},mode:{type:"int32",id:3},fontsize:{type:"int32",id:4},color:{type:"uint32",id:5},midHash:{type:"string",id:6},content:{type:"string",id:7},ctime:{type:"int64",id:8},weight:{type:"int32",id:9},action:{type:"string",id:10},pool:{type:"int32",id:11},idStr:{type:"string",id:12},attr:{type:"int32",id:13}}},DanmuWebPlayerConfig:{fields:{dmSwitch:{type:"bool",id:1},aiSwitch:{type:"bool",id:2},aiLevel:{type:"int32",id:3},blocktop:{type:"bool",id:4},blockscroll:{type:"bool",id:5},blockbottom:{type:"bool",id:6},blockcolor:{type:"bool",id:7},blockspecial:{type:"bool",id:8},preventshade:{type:"bool",id:9},dmask:{type:"bool",id:10},opacity:{type:"float",id:11},dmarea:{type:"int32",id:12},speedplus:{type:"float",id:13},fontsize:{type:"float",id:14},screensync:{type:"bool",id:15},speedsync:{type:"bool",id:16},fontfamily:{type:"string",id:17},bold:{type:"bool",id:18},fontborder:{type:"int32",id:19},drawType:{type:"string",id:20}}}}};const decode=_.curry((async(type,blob,toastTitle="")=>{const buffer=new Uint8Array(await blob.arrayBuffer());if(!unsafeWindow.protobufPromise){unsafeWindow.protobufPromise=new Promise((async(resolve,reject)=>{const library=await Ajax.monkey({url:"https://cdn.jsdelivr.net/npm/protobufjs@6.10.1/dist/light/protobuf.min.js",method:"GET"}).catch((e=>logError(e)));if(!library){const e="加载依赖库失败, 请稍后重试.";Toast.error(e,toastTitle||"错误");reject(e)}eval(library);unsafeWindow.protobuf=window.protobuf;resolve(unsafeWindow.protobuf)}))}const protobuf=await unsafeWindow.protobufPromise;const root=protobuf.Root.fromJSON(proto);const reply=root.lookupType(type);const message=reply.decode(buffer);return reply.toObject(message)}));const decodeDanmakuSegment=decode("DmSegMobileReply");const decodeDanmakuView=decode("DmWebViewReply");return{export:{proto:proto,decodeDanmakuSegment:decodeDanmakuSegment,decodeDanmakuView:decodeDanmakuView,test:async e=>{const t=`https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=157340456&pid=92150659&segment_index=${e}`;const i=await Ajax.getBlob(t);const o=await decodeDanmakuSegment(i);console.log(o);unsafeWindow.testResult=o}}}})();
|
||||
311
src/video/danmaku-converter/segment/danmaku-segment.ts
Normal file
311
src/video/danmaku-converter/segment/danmaku-segment.ts
Normal file
@ -0,0 +1,311 @@
|
||||
export const proto = {
|
||||
nested: {
|
||||
DmWebViewReply: {
|
||||
fields: {
|
||||
state: {
|
||||
type: 'int32',
|
||||
id: 1
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
id: 2
|
||||
},
|
||||
textSide: {
|
||||
type: 'string',
|
||||
id: 3
|
||||
},
|
||||
dmSge: {
|
||||
type: 'DmSegConfig',
|
||||
id: 4
|
||||
},
|
||||
flag: {
|
||||
type: 'DanmakuFlagConfig',
|
||||
id: 5
|
||||
},
|
||||
specialDms: {
|
||||
rule: 'repeated',
|
||||
type: 'string',
|
||||
id: 6
|
||||
},
|
||||
checkBox: {
|
||||
type: 'bool',
|
||||
id: 7
|
||||
},
|
||||
count: {
|
||||
type: 'int64',
|
||||
id: 8
|
||||
},
|
||||
commandDms: {
|
||||
rule: 'repeated',
|
||||
type: 'CommandDm',
|
||||
id: 9
|
||||
},
|
||||
dmSetting: {
|
||||
type: 'DanmuWebPlayerConfig',
|
||||
id: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
CommandDm: {
|
||||
fields: {
|
||||
id: {
|
||||
type: 'int64',
|
||||
id: 1
|
||||
},
|
||||
oid: {
|
||||
type: 'int64',
|
||||
id: 2
|
||||
},
|
||||
mid: {
|
||||
type: 'int64',
|
||||
id: 3
|
||||
},
|
||||
command: {
|
||||
type: 'string',
|
||||
id: 4
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
id: 5
|
||||
},
|
||||
progress: {
|
||||
type: 'int32',
|
||||
id: 6
|
||||
},
|
||||
ctime: {
|
||||
type: 'string',
|
||||
id: 7
|
||||
},
|
||||
mtime: {
|
||||
type: 'string',
|
||||
id: 8
|
||||
},
|
||||
extra: {
|
||||
type: 'string',
|
||||
id: 9
|
||||
},
|
||||
idStr: {
|
||||
type: 'string',
|
||||
id: 10
|
||||
}
|
||||
}
|
||||
},
|
||||
DmSegConfig: {
|
||||
fields: {
|
||||
pageSize: {
|
||||
type: 'int64',
|
||||
id: 1
|
||||
},
|
||||
total: {
|
||||
type: 'int64',
|
||||
id: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
DanmakuFlagConfig: {
|
||||
fields: {
|
||||
recFlag: {
|
||||
type: 'int32',
|
||||
id: 1
|
||||
},
|
||||
recText: {
|
||||
type: 'string',
|
||||
id: 2
|
||||
},
|
||||
recSwitch: {
|
||||
type: 'int32',
|
||||
id: 3
|
||||
}
|
||||
}
|
||||
},
|
||||
DmSegMobileReply: {
|
||||
fields: {
|
||||
elems: {
|
||||
rule: 'repeated',
|
||||
type: 'DanmakuElem',
|
||||
id: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
DanmakuElem: {
|
||||
fields: {
|
||||
id: {
|
||||
type: 'int64',
|
||||
id: 1
|
||||
},
|
||||
progress: {
|
||||
type: 'int32',
|
||||
id: 2
|
||||
},
|
||||
mode: {
|
||||
type: 'int32',
|
||||
id: 3
|
||||
},
|
||||
fontsize: {
|
||||
type: 'int32',
|
||||
id: 4
|
||||
},
|
||||
color: {
|
||||
type: 'uint32',
|
||||
id: 5
|
||||
},
|
||||
midHash: {
|
||||
type: 'string',
|
||||
id: 6
|
||||
},
|
||||
content: {
|
||||
type: 'string',
|
||||
id: 7
|
||||
},
|
||||
ctime: {
|
||||
type: 'int64',
|
||||
id: 8
|
||||
},
|
||||
weight: {
|
||||
type: 'int32',
|
||||
id: 9
|
||||
},
|
||||
action: {
|
||||
type: 'string',
|
||||
id: 10
|
||||
},
|
||||
pool: {
|
||||
type: 'int32',
|
||||
id: 11
|
||||
},
|
||||
idStr: {
|
||||
type: 'string',
|
||||
id: 12
|
||||
},
|
||||
attr: {
|
||||
type: 'int32',
|
||||
id: 13
|
||||
}
|
||||
}
|
||||
},
|
||||
DanmuWebPlayerConfig: {
|
||||
fields: {
|
||||
dmSwitch: {
|
||||
type: 'bool',
|
||||
id: 1
|
||||
},
|
||||
aiSwitch: {
|
||||
type: 'bool',
|
||||
id: 2
|
||||
},
|
||||
aiLevel: {
|
||||
type: 'int32',
|
||||
id: 3
|
||||
},
|
||||
blocktop: {
|
||||
type: 'bool',
|
||||
id: 4
|
||||
},
|
||||
blockscroll: {
|
||||
type: 'bool',
|
||||
id: 5
|
||||
},
|
||||
blockbottom: {
|
||||
type: 'bool',
|
||||
id: 6
|
||||
},
|
||||
blockcolor: {
|
||||
type: 'bool',
|
||||
id: 7
|
||||
},
|
||||
blockspecial: {
|
||||
type: 'bool',
|
||||
id: 8
|
||||
},
|
||||
preventshade: {
|
||||
type: 'bool',
|
||||
id: 9
|
||||
},
|
||||
dmask: {
|
||||
type: 'bool',
|
||||
id: 10
|
||||
},
|
||||
opacity: {
|
||||
type: 'float',
|
||||
id: 11
|
||||
},
|
||||
dmarea: {
|
||||
type: 'int32',
|
||||
id: 12
|
||||
},
|
||||
speedplus: {
|
||||
type: 'float',
|
||||
id: 13
|
||||
},
|
||||
fontsize: {
|
||||
type: 'float',
|
||||
id: 14
|
||||
},
|
||||
screensync: {
|
||||
type: 'bool',
|
||||
id: 15
|
||||
},
|
||||
speedsync: {
|
||||
type: 'bool',
|
||||
id: 16
|
||||
},
|
||||
fontfamily: {
|
||||
type: 'string',
|
||||
id: 17
|
||||
},
|
||||
bold: {
|
||||
type: 'bool',
|
||||
id: 18
|
||||
},
|
||||
fontborder: {
|
||||
type: 'int32',
|
||||
id: 19
|
||||
},
|
||||
drawType: {
|
||||
type: 'string',
|
||||
id: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const decode = _.curry(async (type: string, blob: Blob, toastTitle = '') => {
|
||||
const buffer = new Uint8Array(await blob.arrayBuffer())
|
||||
if (!unsafeWindow.protobufPromise) {
|
||||
unsafeWindow.protobufPromise = new Promise(async (resolve, reject) => {
|
||||
const library = await Ajax.monkey({
|
||||
url: 'https://cdn.jsdelivr.net/npm/protobufjs@6.10.1/dist/light/protobuf.min.js',
|
||||
method: 'GET',
|
||||
}).catch(error => logError(error))
|
||||
if (!library) {
|
||||
const message = '加载依赖库失败, 请稍后重试.'
|
||||
Toast.error(message, toastTitle || '错误')
|
||||
reject(message)
|
||||
}
|
||||
eval(library)
|
||||
unsafeWindow.protobuf = window.protobuf
|
||||
resolve(unsafeWindow.protobuf)
|
||||
})
|
||||
}
|
||||
const protobuf = await unsafeWindow.protobufPromise
|
||||
const root = protobuf.Root.fromJSON(proto)
|
||||
const reply = root.lookupType(type)
|
||||
const message = reply.decode(buffer)
|
||||
return reply.toObject(message)
|
||||
})
|
||||
export const decodeDanmakuSegment = decode('DmSegMobileReply')
|
||||
export const decodeDanmakuView = decode('DmWebViewReply')
|
||||
export default {
|
||||
export: {
|
||||
proto,
|
||||
decodeDanmakuSegment,
|
||||
decodeDanmakuView,
|
||||
test: async (i: number) => {
|
||||
const url = `https://api.bilibili.com/x/v2/dm/web/seg.so?type=1&oid=157340456&pid=92150659&segment_index=${i}`
|
||||
const blob = await Ajax.getBlob(url)
|
||||
const result = await decodeDanmakuSegment(blob)
|
||||
console.log(result)
|
||||
unsafeWindow.testResult = result
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user