@dan-uni/dan-any 1.4.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -43
- package/dist/adapters.d.mts +2 -0
- package/dist/adapters.mjs +1 -0
- package/dist/chunk-0Lt9GpW0.mjs +1 -0
- package/dist/core/db/schema.d.mts +2 -0
- package/dist/core/db/schema.mjs +2 -0
- package/dist/core/db/schema.mjs.map +1 -0
- package/dist/core/db/utils.d.mts +1707 -0
- package/dist/core/db/utils.d.mts.map +1 -0
- package/dist/core/db/utils.mjs +1 -0
- package/dist/core-D7LMAB5h.mjs +2 -0
- package/dist/core-D7LMAB5h.mjs.map +1 -0
- package/dist/core.d.mts +2 -0
- package/dist/core.mjs +1 -0
- package/dist/db-DWWzkRBb.mjs +41 -0
- package/dist/db-DWWzkRBb.mjs.map +1 -0
- package/dist/dm-extra-DrAQCrFv.d.mts +135 -0
- package/dist/dm-extra-DrAQCrFv.d.mts.map +1 -0
- package/dist/dm-tkTdR_W6.mjs +2 -0
- package/dist/dm-tkTdR_W6.mjs.map +1 -0
- package/dist/index-vAs4qV9A.d.mts +6195 -0
- package/dist/index-vAs4qV9A.d.mts.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +1 -0
- package/dist/isSame-D4G9eoE4.mjs +2 -0
- package/dist/isSame-D4G9eoE4.mjs.map +1 -0
- package/dist/plugins.d.mts +105 -0
- package/dist/plugins.d.mts.map +1 -0
- package/dist/plugins.mjs +2 -0
- package/dist/plugins.mjs.map +1 -0
- package/dist/schema-BuenbDx9.d.mts +1619 -0
- package/dist/schema-BuenbDx9.d.mts.map +1 -0
- package/dist/utils.d.mts +25 -0
- package/dist/utils.d.mts.map +1 -0
- package/dist/utils.mjs +2 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +65 -37
- package/.babelrc.json +0 -12
- package/buf.gen.yaml +0 -10
- package/buf.yaml +0 -12
- package/dist/browser/1~rslib-runtime.min.js +0 -49
- package/dist/browser/index.min.js +0 -13523
- package/dist/browser/index.min.js.LICENSE.txt +0 -17
- package/dist/browser/plugins/bili.min.js +0 -1
- package/dist/browser/plugins/index.min.js +0 -2
- package/dist/browser/plugins/stats.min.js +0 -10
- package/dist/browser/src/ass-gen/__tests__/canvas.test.d.ts +0 -1
- package/dist/browser/src/ass-gen/__tests__/generate.test.d.ts +0 -1
- package/dist/browser/src/ass-gen/ass/create.d.ts +0 -4
- package/dist/browser/src/ass-gen/ass/dialogue.d.ts +0 -16
- package/dist/browser/src/ass-gen/ass/event.d.ts +0 -2
- package/dist/browser/src/ass-gen/ass/info.d.ts +0 -8
- package/dist/browser/src/ass-gen/ass/raw.d.ts +0 -14
- package/dist/browser/src/ass-gen/ass/style.d.ts +0 -2
- package/dist/browser/src/ass-gen/config.d.ts +0 -2
- package/dist/browser/src/ass-gen/index.d.ts +0 -30
- package/dist/browser/src/ass-gen/types.d.ts +0 -71
- package/dist/browser/src/ass-gen/util/color.d.ts +0 -18
- package/dist/browser/src/ass-gen/util/danconvert.d.ts +0 -5
- package/dist/browser/src/ass-gen/util/index.d.ts +0 -4
- package/dist/browser/src/ass-gen/util/lang.d.ts +0 -3
- package/dist/browser/src/ass-gen/util/layout.d.ts +0 -4
- package/dist/browser/src/index.d.ts +0 -283
- package/dist/browser/src/index.test.d.ts +0 -1
- package/dist/browser/src/plugins/bili/dedupe.d.ts +0 -3
- package/dist/browser/src/plugins/bili/history-danmaku-fast-forward.d.ts +0 -18
- package/dist/browser/src/plugins/bili/index.d.ts +0 -2
- package/dist/browser/src/plugins/bili/index.test.d.ts +0 -1
- package/dist/browser/src/plugins/index.d.ts +0 -2
- package/dist/browser/src/plugins/stats/getLatestDan.d.ts +0 -6
- package/dist/browser/src/plugins/stats/index.d.ts +0 -1
- package/dist/browser/src/plugins/stats/index.test.d.ts +0 -1
- package/dist/browser/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.d.ts +0 -3426
- package/dist/browser/src/proto/gen/danuni/danmaku/v1/danmaku_pb.d.ts +0 -176
- package/dist/browser/src/utils/dm-gen.d.ts +0 -309
- package/dist/browser/src/utils/dm-gen.test.d.ts +0 -1
- package/dist/browser/src/utils/fileParser.d.ts +0 -3
- package/dist/browser/src/utils/id-gen.d.ts +0 -50
- package/dist/browser/src/utils/platform.d.ts +0 -24
- package/dist/node/0~rslib-runtime.js +0 -23
- package/dist/node/index.js +0 -2099
- package/dist/node/plugins/bili.js +0 -1
- package/dist/node/plugins/index.js +0 -2
- package/dist/node/plugins/stats.js +0 -10
- package/dist/node/src/ass-gen/__tests__/canvas.test.d.ts +0 -1
- package/dist/node/src/ass-gen/__tests__/generate.test.d.ts +0 -1
- package/dist/node/src/ass-gen/ass/create.d.ts +0 -4
- package/dist/node/src/ass-gen/ass/dialogue.d.ts +0 -16
- package/dist/node/src/ass-gen/ass/event.d.ts +0 -2
- package/dist/node/src/ass-gen/ass/info.d.ts +0 -8
- package/dist/node/src/ass-gen/ass/raw.d.ts +0 -14
- package/dist/node/src/ass-gen/ass/style.d.ts +0 -2
- package/dist/node/src/ass-gen/config.d.ts +0 -2
- package/dist/node/src/ass-gen/index.d.ts +0 -30
- package/dist/node/src/ass-gen/types.d.ts +0 -71
- package/dist/node/src/ass-gen/util/color.d.ts +0 -18
- package/dist/node/src/ass-gen/util/danconvert.d.ts +0 -5
- package/dist/node/src/ass-gen/util/index.d.ts +0 -4
- package/dist/node/src/ass-gen/util/lang.d.ts +0 -3
- package/dist/node/src/ass-gen/util/layout.d.ts +0 -4
- package/dist/node/src/index.d.ts +0 -283
- package/dist/node/src/index.test.d.ts +0 -1
- package/dist/node/src/plugins/bili/dedupe.d.ts +0 -3
- package/dist/node/src/plugins/bili/history-danmaku-fast-forward.d.ts +0 -18
- package/dist/node/src/plugins/bili/index.d.ts +0 -2
- package/dist/node/src/plugins/bili/index.test.d.ts +0 -1
- package/dist/node/src/plugins/index.d.ts +0 -2
- package/dist/node/src/plugins/stats/getLatestDan.d.ts +0 -6
- package/dist/node/src/plugins/stats/index.d.ts +0 -1
- package/dist/node/src/plugins/stats/index.test.d.ts +0 -1
- package/dist/node/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.d.ts +0 -3426
- package/dist/node/src/proto/gen/danuni/danmaku/v1/danmaku_pb.d.ts +0 -176
- package/dist/node/src/utils/dm-gen.d.ts +0 -309
- package/dist/node/src/utils/dm-gen.test.d.ts +0 -1
- package/dist/node/src/utils/fileParser.d.ts +0 -3
- package/dist/node/src/utils/id-gen.d.ts +0 -50
- package/dist/node/src/utils/platform.d.ts +0 -24
- package/dist/umd/index.umd.min.js +0 -32093
- package/dist/umd/index.umd.min.js.LICENSE.txt +0 -34
- package/dist/umd/plugins/bili.umd.min.js +0 -32004
- package/dist/umd/plugins/bili.umd.min.js.LICENSE.txt +0 -34
- package/dist/umd/plugins/index.umd.min.js +0 -32020
- package/dist/umd/plugins/index.umd.min.js.LICENSE.txt +0 -34
- package/dist/umd/plugins/stats.umd.min.js +0 -39
- package/dist/umd/src/ass-gen/__tests__/canvas.test.d.ts +0 -1
- package/dist/umd/src/ass-gen/__tests__/generate.test.d.ts +0 -1
- package/dist/umd/src/ass-gen/ass/create.d.ts +0 -4
- package/dist/umd/src/ass-gen/ass/dialogue.d.ts +0 -16
- package/dist/umd/src/ass-gen/ass/event.d.ts +0 -2
- package/dist/umd/src/ass-gen/ass/info.d.ts +0 -8
- package/dist/umd/src/ass-gen/ass/raw.d.ts +0 -14
- package/dist/umd/src/ass-gen/ass/style.d.ts +0 -2
- package/dist/umd/src/ass-gen/config.d.ts +0 -2
- package/dist/umd/src/ass-gen/index.d.ts +0 -30
- package/dist/umd/src/ass-gen/types.d.ts +0 -71
- package/dist/umd/src/ass-gen/util/color.d.ts +0 -18
- package/dist/umd/src/ass-gen/util/danconvert.d.ts +0 -5
- package/dist/umd/src/ass-gen/util/index.d.ts +0 -4
- package/dist/umd/src/ass-gen/util/lang.d.ts +0 -3
- package/dist/umd/src/ass-gen/util/layout.d.ts +0 -4
- package/dist/umd/src/index.d.ts +0 -283
- package/dist/umd/src/index.test.d.ts +0 -1
- package/dist/umd/src/plugins/bili/dedupe.d.ts +0 -3
- package/dist/umd/src/plugins/bili/history-danmaku-fast-forward.d.ts +0 -18
- package/dist/umd/src/plugins/bili/index.d.ts +0 -2
- package/dist/umd/src/plugins/bili/index.test.d.ts +0 -1
- package/dist/umd/src/plugins/index.d.ts +0 -2
- package/dist/umd/src/plugins/stats/getLatestDan.d.ts +0 -6
- package/dist/umd/src/plugins/stats/index.d.ts +0 -1
- package/dist/umd/src/plugins/stats/index.test.d.ts +0 -1
- package/dist/umd/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.d.ts +0 -3426
- package/dist/umd/src/proto/gen/danuni/danmaku/v1/danmaku_pb.d.ts +0 -176
- package/dist/umd/src/utils/dm-gen.d.ts +0 -309
- package/dist/umd/src/utils/dm-gen.test.d.ts +0 -1
- package/dist/umd/src/utils/fileParser.d.ts +0 -3
- package/dist/umd/src/utils/id-gen.d.ts +0 -50
- package/dist/umd/src/utils/platform.d.ts +0 -24
- package/plugins/package.json +0 -6
- package/rslib.config.ts +0 -101
- package/src/ass-gen/__tests__/898651903.xml +0 -1619
- package/src/ass-gen/__tests__/898651903.xml.ass +0 -1516
- package/src/ass-gen/__tests__/canvas.test.ts +0 -15
- package/src/ass-gen/__tests__/generate.test.ts +0 -26
- package/src/ass-gen/ass/create.ts +0 -37
- package/src/ass-gen/ass/dialogue.ts +0 -90
- package/src/ass-gen/ass/event.ts +0 -57
- package/src/ass-gen/ass/info.ts +0 -27
- package/src/ass-gen/ass/raw.ts +0 -78
- package/src/ass-gen/ass/style.ts +0 -66
- package/src/ass-gen/config.ts +0 -45
- package/src/ass-gen/index.ts +0 -73
- package/src/ass-gen/types.ts +0 -76
- package/src/ass-gen/util/color.ts +0 -55
- package/src/ass-gen/util/danconvert.ts +0 -43
- package/src/ass-gen/util/index.ts +0 -10
- package/src/ass-gen/util/lang.ts +0 -35
- package/src/ass-gen/util/layout.ts +0 -242
- package/src/index.test.ts +0 -157
- package/src/index.ts +0 -1144
- package/src/plugins/bili/README.md +0 -87
- package/src/plugins/bili/dedupe.ts +0 -29
- package/src/plugins/bili/history-danmaku-fast-forward.ts +0 -86
- package/src/plugins/bili/index.test.ts +0 -129
- package/src/plugins/bili/index.ts +0 -2
- package/src/plugins/index.ts +0 -2
- package/src/plugins/stats/README.md +0 -44
- package/src/plugins/stats/getLatestDan.ts +0 -13
- package/src/plugins/stats/index.test.ts +0 -39
- package/src/plugins/stats/index.ts +0 -1
- package/src/proto/gen/bilibili/community/service/dm/v1/dm_pb.ts +0 -4072
- package/src/proto/gen/danuni/danmaku/v1/danmaku_pb.ts +0 -223
- package/src/proto/src/bilibili/community/service/dm/v1/dm.proto +0 -1095
- package/src/proto/src/danuni/danmaku/v1/danmaku.proto +0 -52
- package/src/utils/dm-gen.test.ts +0 -129
- package/src/utils/dm-gen.ts +0 -1082
- package/src/utils/fileParser.ts +0 -37
- package/src/utils/id-gen.ts +0 -73
- package/src/utils/platform.ts +0 -38
- package/tsconfig.json +0 -108
- package/types/tsconfig.tsbuildinfo +0 -1
package/src/index.ts
DELETED
|
@@ -1,1144 +0,0 @@
|
|
|
1
|
-
import 'reflect-metadata/lite'
|
|
2
|
-
|
|
3
|
-
import { isJSON, isString } from 'class-validator'
|
|
4
|
-
import { XMLBuilder, XMLParser } from 'fast-xml-parser'
|
|
5
|
-
import JSONbig from 'json-bigint'
|
|
6
|
-
import type { Options as AssGenOptions, CanvasCtx } from './ass-gen'
|
|
7
|
-
import type { CommandDm as DM_JSON_BiliCommandGrpc } from './proto/gen/bilibili/community/service/dm/v1/dm_pb'
|
|
8
|
-
import type { Danmaku } from './proto/gen/danuni/danmaku/v1/danmaku_pb'
|
|
9
|
-
|
|
10
|
-
import { create, fromBinary, toBinary } from '@bufbuild/protobuf'
|
|
11
|
-
import {
|
|
12
|
-
timestampDate,
|
|
13
|
-
timestampFromDate,
|
|
14
|
-
timestampNow,
|
|
15
|
-
} from '@bufbuild/protobuf/wkt'
|
|
16
|
-
|
|
17
|
-
import pkg from '../package.json'
|
|
18
|
-
import { generateASS, parseAssRawField } from './ass-gen'
|
|
19
|
-
import {
|
|
20
|
-
// DanmakuElem as DM_JSON_BiliGrpc,
|
|
21
|
-
DmSegMobileReplySchema,
|
|
22
|
-
DmWebViewReplySchema,
|
|
23
|
-
} from './proto/gen/bilibili/community/service/dm/v1/dm_pb'
|
|
24
|
-
import { ListDanResponseSchema } from './proto/gen/danuni/danmaku/v1/danmaku_pb'
|
|
25
|
-
// import type * as UniIDType from './utils/id-gen'
|
|
26
|
-
|
|
27
|
-
import { UniDM } from './utils/dm-gen'
|
|
28
|
-
import * as UniDMTools from './utils/dm-gen'
|
|
29
|
-
import { fileParser } from './utils/fileParser'
|
|
30
|
-
import { UniID as ID } from './utils/id-gen'
|
|
31
|
-
import * as UniIDTools from './utils/id-gen'
|
|
32
|
-
import * as platform from './utils/platform'
|
|
33
|
-
|
|
34
|
-
const JSON = JSONbig({
|
|
35
|
-
useNativeBigInt: true,
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
const DanUniConvertTipTemplate: DanUniConvertTip = {
|
|
39
|
-
meassage: 'Converted by DanUni!',
|
|
40
|
-
version: `JS/TS ${pkg.name} (v${pkg.version})`,
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
interface DanUniConvertTip {
|
|
44
|
-
meassage: string
|
|
45
|
-
version: string
|
|
46
|
-
data?: string
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export type DM_JSON_DanuniMin = Partial<UniDMTools.UniDMObj>[]
|
|
50
|
-
|
|
51
|
-
export interface DM_XML_Bili {
|
|
52
|
-
i: {
|
|
53
|
-
chatserver: string
|
|
54
|
-
chatid: bigint
|
|
55
|
-
mission: number
|
|
56
|
-
maxlimit: number
|
|
57
|
-
state: number
|
|
58
|
-
real_name: number
|
|
59
|
-
source: string
|
|
60
|
-
d: {
|
|
61
|
-
'#text': string
|
|
62
|
-
'@_p': string
|
|
63
|
-
}[]
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
export interface DM_JSON_BiliUp {
|
|
67
|
-
/** 接口状态码,0 表示成功 */
|
|
68
|
-
code: number
|
|
69
|
-
/** 文本形式的状态码,约定为字符串 "0" */
|
|
70
|
-
message: string
|
|
71
|
-
/** TTL(time to live) 标识,本接口常量为 1 */
|
|
72
|
-
ttl: number
|
|
73
|
-
data: {
|
|
74
|
-
/** 分页元信息 */
|
|
75
|
-
page: {
|
|
76
|
-
/** 当前页序号,从 1 开始 */
|
|
77
|
-
num: number
|
|
78
|
-
/** 每页返回的弹幕条数 */
|
|
79
|
-
size: number
|
|
80
|
-
/** 总页数 */
|
|
81
|
-
total: number
|
|
82
|
-
}
|
|
83
|
-
result: {
|
|
84
|
-
/** 弹幕 ID,int64 */
|
|
85
|
-
id: bigint
|
|
86
|
-
/** 弹幕 ID 字符串形式 */
|
|
87
|
-
id_str: string
|
|
88
|
-
/** 弹幕类型:1 表示视频弹幕(当前接口恒为 1) */
|
|
89
|
-
type: number
|
|
90
|
-
aid: bigint
|
|
91
|
-
bvid: string
|
|
92
|
-
oid: bigint
|
|
93
|
-
mid: bigint
|
|
94
|
-
/** 发送者 mid 的 CRC 哈希(正常接口里用的是这个,保护隐私) */
|
|
95
|
-
mid_hash: string
|
|
96
|
-
/** 弹幕池 */
|
|
97
|
-
pool: number
|
|
98
|
-
/** 属性位字符串,逗号分隔的数字列表,对应 attr 二进制位 */
|
|
99
|
-
attrs: string
|
|
100
|
-
/** 弹幕出现时间,单位毫秒(注意,此处与protobuf接口保持一致,但xml中progress是秒) */
|
|
101
|
-
progress: number
|
|
102
|
-
mode: number
|
|
103
|
-
/** 弹幕内容, content */
|
|
104
|
-
msg: string
|
|
105
|
-
state: number // ?
|
|
106
|
-
fontsize: number
|
|
107
|
-
/** 弹幕颜色,需将16进制转化为普通弹幕的10进制,示例:"ffffff" */
|
|
108
|
-
color: string
|
|
109
|
-
/** 发送时间戳,单位秒 */
|
|
110
|
-
ctime: number
|
|
111
|
-
/** 发送者昵称 */
|
|
112
|
-
uname: string
|
|
113
|
-
/** 发送者头像链接 */
|
|
114
|
-
uface: string
|
|
115
|
-
/** 视频主标题 */
|
|
116
|
-
title: string
|
|
117
|
-
self_seen: boolean // 尽自己可见?
|
|
118
|
-
/** 弹幕点赞数 */
|
|
119
|
-
like_count: number
|
|
120
|
-
user_like: number // ?
|
|
121
|
-
/** 分 P 标题 */
|
|
122
|
-
p_title: string
|
|
123
|
-
/** 视频封面链接 */
|
|
124
|
-
cover: string
|
|
125
|
-
is_charge: boolean // 该up是否开通充电计划?
|
|
126
|
-
is_charge_plus: boolean // 该up是否开通高级充电计划?
|
|
127
|
-
following: boolean // 当前登录用户是否关注该发送者?
|
|
128
|
-
extra_cps: null // ?
|
|
129
|
-
}[]
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
export interface DM_JSON_Dplayer {
|
|
133
|
-
code: number
|
|
134
|
-
/**
|
|
135
|
-
* progress,mode,color,midHash,content
|
|
136
|
-
*/
|
|
137
|
-
data: [number, number, number, string, string][]
|
|
138
|
-
}
|
|
139
|
-
export interface DM_JSON_Artplayer {
|
|
140
|
-
danmuku: {
|
|
141
|
-
text: string // 弹幕文本
|
|
142
|
-
time?: number // 弹幕时间,默认为当前播放器时间
|
|
143
|
-
mode?: number // 弹幕模式:0: 滚动 (默认),1: 顶部,2: 底部
|
|
144
|
-
color?: string // 弹幕颜色,默认为白色
|
|
145
|
-
border?: boolean // 弹幕是否有描边,默认为 false
|
|
146
|
-
style?: {} // 弹幕自定义样式,默认为空对象
|
|
147
|
-
}[]
|
|
148
|
-
}
|
|
149
|
-
export interface DM_JSON_DDPlay {
|
|
150
|
-
count: number | string
|
|
151
|
-
comments: {
|
|
152
|
-
cid: bigint
|
|
153
|
-
p: string
|
|
154
|
-
m: string
|
|
155
|
-
}[]
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export enum DM_format {
|
|
159
|
-
DanuniJson = 'danuni.json',
|
|
160
|
-
DanuniMinJson = 'danuni.min.json',
|
|
161
|
-
DanuniPbBin = 'danuni.binpb',
|
|
162
|
-
BiliXml = 'bili.xml',
|
|
163
|
-
BiliPbBin = 'bili.binpb',
|
|
164
|
-
BiliCmdPbBin = 'bili.cmd.binpb',
|
|
165
|
-
BiliUpJson = 'bili.up.json',
|
|
166
|
-
DplayerJson = 'dplayer.json',
|
|
167
|
-
ArtplayerJson = 'artplayer.json',
|
|
168
|
-
DDPlayJson = 'ddplay.json',
|
|
169
|
-
CommonAss = 'common.ass',
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
type shareItems = Partial<
|
|
173
|
-
Pick<
|
|
174
|
-
UniDMTools.UniDMObj,
|
|
175
|
-
'SOID' | 'senderID' | 'platform' | 'SOID' | 'pool' | 'mode' | 'color'
|
|
176
|
-
>
|
|
177
|
-
>
|
|
178
|
-
type statItems = Partial<
|
|
179
|
-
Pick<
|
|
180
|
-
UniDMTools.UniDMObj,
|
|
181
|
-
| 'SOID'
|
|
182
|
-
| 'mode'
|
|
183
|
-
| 'fontsize'
|
|
184
|
-
| 'color'
|
|
185
|
-
| 'senderID'
|
|
186
|
-
| 'content'
|
|
187
|
-
| 'weight'
|
|
188
|
-
| 'pool'
|
|
189
|
-
| 'platform'
|
|
190
|
-
>
|
|
191
|
-
>
|
|
192
|
-
type Stats<T extends keyof statItems> = Map<statItems[T], number>
|
|
193
|
-
|
|
194
|
-
export interface Options {
|
|
195
|
-
dedupe?: boolean
|
|
196
|
-
/**
|
|
197
|
-
* @description
|
|
198
|
-
* 当为`false`时,关闭DMID生成; 当为正整数时,表示生成DMID的截取位数; 或可传入一个DMID生成器实例
|
|
199
|
-
*/
|
|
200
|
-
dmid?: boolean | number | UniIDTools.DMIDGenerator
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export const convert2Formats = [
|
|
204
|
-
DM_format.DanuniJson,
|
|
205
|
-
DM_format.DanuniMinJson,
|
|
206
|
-
DM_format.DanuniPbBin,
|
|
207
|
-
DM_format.BiliXml,
|
|
208
|
-
DM_format.DplayerJson,
|
|
209
|
-
DM_format.ArtplayerJson,
|
|
210
|
-
DM_format.DDPlayJson,
|
|
211
|
-
] as const
|
|
212
|
-
export type Convert2Formats =
|
|
213
|
-
| DM_format.DanuniJson
|
|
214
|
-
| DM_format.DanuniMinJson
|
|
215
|
-
| DM_format.DanuniPbBin
|
|
216
|
-
| DM_format.BiliXml
|
|
217
|
-
| DM_format.DplayerJson
|
|
218
|
-
| DM_format.ArtplayerJson
|
|
219
|
-
| DM_format.DDPlayJson
|
|
220
|
-
type Convert2ResultMap = {
|
|
221
|
-
[DM_format.DanuniJson]: UniDM[]
|
|
222
|
-
[DM_format.DanuniMinJson]: DM_JSON_DanuniMin
|
|
223
|
-
[DM_format.DanuniPbBin]: Uint8Array
|
|
224
|
-
[DM_format.BiliXml]: string
|
|
225
|
-
[DM_format.DplayerJson]: DM_JSON_Dplayer & { danuni?: DanUniConvertTip }
|
|
226
|
-
[DM_format.ArtplayerJson]: DM_JSON_Artplayer & { danuni?: DanUniConvertTip }
|
|
227
|
-
[DM_format.DDPlayJson]: DM_JSON_DDPlay & { danuni?: DanUniConvertTip }
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export class UniPool {
|
|
231
|
-
constructor(
|
|
232
|
-
public dans: UniDM[],
|
|
233
|
-
public options: Options = {},
|
|
234
|
-
public info = {
|
|
235
|
-
/**
|
|
236
|
-
* 是否从已被转换过的第三方格式弹幕再次转换而来
|
|
237
|
-
*/
|
|
238
|
-
fromConverted: false,
|
|
239
|
-
},
|
|
240
|
-
) {
|
|
241
|
-
if (options.dedupe !== false) options.dedupe = true
|
|
242
|
-
if (this.options.dedupe) this.dedupe()
|
|
243
|
-
}
|
|
244
|
-
pipe<T extends (...args: any) => any>(fn: T): ReturnType<T> {
|
|
245
|
-
return fn(this)
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* @deprecated 使用 `getShared` 代替
|
|
249
|
-
*/
|
|
250
|
-
get shared(): shareItems {
|
|
251
|
-
if (this.dans.length === 0) return {}
|
|
252
|
-
const keys: (keyof shareItems)[] = [
|
|
253
|
-
'SOID',
|
|
254
|
-
'senderID',
|
|
255
|
-
'platform',
|
|
256
|
-
'pool',
|
|
257
|
-
'mode',
|
|
258
|
-
'color',
|
|
259
|
-
]
|
|
260
|
-
const result: shareItems = {} as shareItems
|
|
261
|
-
for (const key of keys) {
|
|
262
|
-
const sharedVal = this.getShared(key)
|
|
263
|
-
if (sharedVal !== undefined) {
|
|
264
|
-
result[key] = sharedVal as any
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return result
|
|
268
|
-
}
|
|
269
|
-
getShared<K extends keyof shareItems>(key: K): shareItems[K] {
|
|
270
|
-
if (this.dans.length === 0) return undefined
|
|
271
|
-
const firstVal = this.dans[0][key]
|
|
272
|
-
for (let i = 1; i < this.dans.length; i++) {
|
|
273
|
-
if (this.dans[i][key] !== firstVal) {
|
|
274
|
-
return undefined
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return firstVal
|
|
278
|
-
}
|
|
279
|
-
getStat<K extends keyof statItems>(key: K): Stats<K> {
|
|
280
|
-
const statMap = new Map<statItems[K], number>()
|
|
281
|
-
for (const dan of this.dans) {
|
|
282
|
-
const val = dan[key]
|
|
283
|
-
statMap.set(val, (statMap.get(val) || 0) + 1)
|
|
284
|
-
}
|
|
285
|
-
return statMap
|
|
286
|
-
}
|
|
287
|
-
getMost<K extends keyof statItems>(key: K) {
|
|
288
|
-
const stats = this.getStat(key)
|
|
289
|
-
if (stats.size === 0) return { val: undefined, count: 0 }
|
|
290
|
-
let mostVal: statItems[K] | undefined
|
|
291
|
-
let maxCount = 0
|
|
292
|
-
for (const [val, count] of stats.entries()) {
|
|
293
|
-
if (count > maxCount) {
|
|
294
|
-
maxCount = count
|
|
295
|
-
mostVal = val
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return { val: mostVal, count: maxCount }
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* @deprecated 使用 `getMost` 代替
|
|
302
|
-
*/
|
|
303
|
-
get most() {
|
|
304
|
-
const keys: (keyof statItems)[] = [
|
|
305
|
-
'mode',
|
|
306
|
-
'fontsize',
|
|
307
|
-
'color',
|
|
308
|
-
'senderID',
|
|
309
|
-
'content',
|
|
310
|
-
'weight',
|
|
311
|
-
'pool',
|
|
312
|
-
'platform',
|
|
313
|
-
]
|
|
314
|
-
const statMaps = new Map<
|
|
315
|
-
keyof statItems,
|
|
316
|
-
Map<statItems[keyof statItems], number>
|
|
317
|
-
>()
|
|
318
|
-
for (const dan of this.dans) {
|
|
319
|
-
for (const key of keys) {
|
|
320
|
-
if (!statMaps.has(key)) {
|
|
321
|
-
statMaps.set(key, new Map())
|
|
322
|
-
}
|
|
323
|
-
const statMap = statMaps.get(key)!
|
|
324
|
-
const val = dan[key]
|
|
325
|
-
statMap.set(val, (statMap.get(val) || 0) + 1)
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
const result: Record<string, any> = {}
|
|
329
|
-
for (const key of keys) {
|
|
330
|
-
const statMap = statMaps.get(key)!
|
|
331
|
-
let mostVal: statItems[keyof statItems] | undefined
|
|
332
|
-
let maxCount = 0
|
|
333
|
-
for (const [val, count] of statMap.entries()) {
|
|
334
|
-
if (count > maxCount) {
|
|
335
|
-
maxCount = count
|
|
336
|
-
mostVal = val
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
result[key] = mostVal
|
|
340
|
-
}
|
|
341
|
-
return {
|
|
342
|
-
mode: result.mode as UniDMTools.Modes,
|
|
343
|
-
fontsize: result.fontsize as number,
|
|
344
|
-
color: result.color as number,
|
|
345
|
-
senderID: result.senderID as string,
|
|
346
|
-
content: result.content as string,
|
|
347
|
-
weight: result.weight as number,
|
|
348
|
-
pool: result.pool as UniDMTools.Pools,
|
|
349
|
-
platform: result.platform as string | undefined,
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
static create(options?: Options) {
|
|
353
|
-
return new UniPool([], options)
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* 合并弹幕/弹幕库
|
|
357
|
-
*/
|
|
358
|
-
assign(dans: UniPool | UniDM | UniDM[]) {
|
|
359
|
-
if (dans instanceof UniPool) {
|
|
360
|
-
return new UniPool(
|
|
361
|
-
[...this.dans, ...dans.dans],
|
|
362
|
-
{ ...this.options, ...dans.options },
|
|
363
|
-
{ ...this.info, ...dans.info },
|
|
364
|
-
)
|
|
365
|
-
} else if (dans instanceof UniDM) {
|
|
366
|
-
return new UniPool([...this.dans, dans], this.options, this.info)
|
|
367
|
-
} else if (Array.isArray(dans) && dans.every((d) => d instanceof UniDM)) {
|
|
368
|
-
return new UniPool([...this.dans, ...dans], this.options, this.info)
|
|
369
|
-
} else return this
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* 按共通属性拆分弹幕库
|
|
373
|
-
*/
|
|
374
|
-
split(key: keyof shareItems) {
|
|
375
|
-
if (this.getShared(key)) return [this]
|
|
376
|
-
const set = new Set(this.dans.map((d) => d[key]))
|
|
377
|
-
return [...set].map((v) => {
|
|
378
|
-
return new UniPool(
|
|
379
|
-
this.dans.filter((d) => d[key] === v),
|
|
380
|
-
{ ...this.options, dedupe: false },
|
|
381
|
-
this.info,
|
|
382
|
-
)
|
|
383
|
-
})
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* 基于DMID的基本去重功能,用于解决该class下dans为array而非Set的问题
|
|
387
|
-
*/
|
|
388
|
-
private dedupe() {
|
|
389
|
-
// 这里基本上没有性能瓶颈(大文件测试与AI优化下无明显区别)
|
|
390
|
-
if (this.options.dmid !== false) {
|
|
391
|
-
const map = new Map()
|
|
392
|
-
this.dans.forEach((d) => map.set(d.DMID || d.toDMID(), d))
|
|
393
|
-
this.dans = [...map.values()]
|
|
394
|
-
}
|
|
395
|
-
this.options.dedupe = false
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* 合并一定时间段内的重复弹幕,防止同屏出现过多
|
|
399
|
-
* @param lifetime 查重时间区段,单位秒 (默认为 0,表示不查重)
|
|
400
|
-
*/
|
|
401
|
-
merge(lifetime = 0) {
|
|
402
|
-
if (!this.getShared('SOID')) {
|
|
403
|
-
console.error(
|
|
404
|
-
"本功能仅支持同弹幕库内使用,可先 .split('SOID') 在分别使用",
|
|
405
|
-
)
|
|
406
|
-
return this
|
|
407
|
-
}
|
|
408
|
-
if (lifetime <= 0) return this
|
|
409
|
-
const result: UniDM[] = []
|
|
410
|
-
const cache: Record<string, UniDM> = {}
|
|
411
|
-
const mergeObj: Record<string, UniDMTools.ExtraDanUniMerge> = {}
|
|
412
|
-
// 第一遍:合并弹幕
|
|
413
|
-
for (const danmaku of this.dans) {
|
|
414
|
-
const key = `${danmaku.content}|${danmaku.mode}|${danmaku.pool}|${danmaku.platform}`
|
|
415
|
-
const cached = cache[key]
|
|
416
|
-
|
|
417
|
-
if (
|
|
418
|
-
cached &&
|
|
419
|
-
danmaku.progress - cached.progress <= lifetime &&
|
|
420
|
-
danmaku.isSameAs(cached, { skipDanuniMerge: true })
|
|
421
|
-
) {
|
|
422
|
-
// 更新已存在的弹幕
|
|
423
|
-
mergeObj[key].senders.push(danmaku.senderID)
|
|
424
|
-
mergeObj[key].count = mergeObj[key].senders.length
|
|
425
|
-
mergeObj[key].taolu_count = mergeObj[key].count
|
|
426
|
-
mergeObj[key].taolu_senders = mergeObj[key].senders
|
|
427
|
-
mergeObj[key].duration = Number.parseFloat(
|
|
428
|
-
(danmaku.progress - cached.progress).toFixed(3),
|
|
429
|
-
)
|
|
430
|
-
cache[key] = danmaku
|
|
431
|
-
} else {
|
|
432
|
-
// 新弹幕
|
|
433
|
-
mergeObj[key] = {
|
|
434
|
-
count: 1,
|
|
435
|
-
duration: 0,
|
|
436
|
-
senders: [danmaku.senderID],
|
|
437
|
-
taolu_count: 1,
|
|
438
|
-
taolu_senders: [danmaku.senderID],
|
|
439
|
-
}
|
|
440
|
-
cache[key] = danmaku
|
|
441
|
-
result.push(danmaku)
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
// 第二遍:更新 extraStr
|
|
445
|
-
for (const danmaku of result) {
|
|
446
|
-
const key = `${danmaku.content}|${danmaku.mode}|${danmaku.pool}|${danmaku.platform}`
|
|
447
|
-
const mergeData = mergeObj[key]
|
|
448
|
-
const extra = danmaku.extra
|
|
449
|
-
if (mergeData.count > 1) {
|
|
450
|
-
// 多个发送者:设置为机器人并添加保护标记
|
|
451
|
-
danmaku.senderID = 'merge[bot]@dan-any'
|
|
452
|
-
if (!danmaku.attr) {
|
|
453
|
-
danmaku.attr = [UniDMTools.DMAttr.Protect]
|
|
454
|
-
} else if (!danmaku.attr.includes(UniDMTools.DMAttr.Protect)) {
|
|
455
|
-
danmaku.attr.push(UniDMTools.DMAttr.Protect)
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
extra.danuni = extra.danuni || {}
|
|
459
|
-
extra.danuni.merge = mergeData
|
|
460
|
-
danmaku.extraStr = JSON.stringify(extra)
|
|
461
|
-
} else {
|
|
462
|
-
// 单个发送者:清理 merge 字段
|
|
463
|
-
if (extra.danuni?.merge) {
|
|
464
|
-
delete extra.danuni.merge
|
|
465
|
-
if (Object.keys(extra.danuni).length === 0) {
|
|
466
|
-
delete extra.danuni
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
danmaku.extraStr =
|
|
470
|
-
Object.keys(extra).length > 0 ? JSON.stringify(extra) : undefined
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
return new UniPool(result, this.options, this.info)
|
|
474
|
-
}
|
|
475
|
-
static import(
|
|
476
|
-
file: unknown,
|
|
477
|
-
options?: Options,
|
|
478
|
-
/**
|
|
479
|
-
* 加载指定解析模块,为空则全选,为字符串则视为文件名解析加载模块
|
|
480
|
-
*/
|
|
481
|
-
mod?: string | ('json' | 'str' | 'bin')[],
|
|
482
|
-
): { pool: UniPool; fmt: DM_format } {
|
|
483
|
-
const handlers = {
|
|
484
|
-
[DM_format.DanuniJson]: (json: UniDM[]) => ({
|
|
485
|
-
pool: new UniPool(json, options),
|
|
486
|
-
fmt: DM_format.DanuniJson,
|
|
487
|
-
}),
|
|
488
|
-
[DM_format.DanuniMinJson]: (json: DM_JSON_DanuniMin) => ({
|
|
489
|
-
pool: this.fromMin(json, options),
|
|
490
|
-
fmt: DM_format.DanuniMinJson,
|
|
491
|
-
}),
|
|
492
|
-
[DM_format.DanuniPbBin]: (
|
|
493
|
-
file: ArrayBuffer | Uint8Array<ArrayBufferLike>,
|
|
494
|
-
) => ({
|
|
495
|
-
pool: this.fromPb(file),
|
|
496
|
-
fmt: DM_format.DanuniPbBin,
|
|
497
|
-
}),
|
|
498
|
-
[DM_format.BiliXml]: (file: string) => ({
|
|
499
|
-
pool: this.fromBiliXML(file, options),
|
|
500
|
-
fmt: DM_format.BiliXml,
|
|
501
|
-
}),
|
|
502
|
-
[DM_format.BiliPbBin]: (
|
|
503
|
-
file: ArrayBuffer | Uint8Array<ArrayBufferLike>,
|
|
504
|
-
) => ({
|
|
505
|
-
pool: this.fromBiliGrpc(file),
|
|
506
|
-
fmt: DM_format.BiliPbBin,
|
|
507
|
-
}),
|
|
508
|
-
[DM_format.BiliCmdPbBin]: (
|
|
509
|
-
file: ArrayBuffer | Uint8Array<ArrayBufferLike>,
|
|
510
|
-
) => ({
|
|
511
|
-
pool: this.fromBiliCommandGrpc(file),
|
|
512
|
-
fmt: DM_format.BiliCmdPbBin,
|
|
513
|
-
}),
|
|
514
|
-
[DM_format.BiliUpJson]: (json: DM_JSON_BiliUp) => ({
|
|
515
|
-
pool: this.fromBiliUp(json, options),
|
|
516
|
-
fmt: DM_format.BiliUpJson,
|
|
517
|
-
}),
|
|
518
|
-
[DM_format.DplayerJson]: (
|
|
519
|
-
json: DM_JSON_Dplayer & {
|
|
520
|
-
danuni?: DanUniConvertTip
|
|
521
|
-
},
|
|
522
|
-
) => ({
|
|
523
|
-
pool: this.fromDplayer(
|
|
524
|
-
json,
|
|
525
|
-
json.danuni?.data ?? '',
|
|
526
|
-
undefined,
|
|
527
|
-
options,
|
|
528
|
-
),
|
|
529
|
-
fmt: DM_format.DplayerJson,
|
|
530
|
-
}),
|
|
531
|
-
[DM_format.ArtplayerJson]: (
|
|
532
|
-
json: DM_JSON_Artplayer & {
|
|
533
|
-
danuni?: DanUniConvertTip
|
|
534
|
-
},
|
|
535
|
-
) => ({
|
|
536
|
-
pool: this.fromArtplayer(
|
|
537
|
-
json,
|
|
538
|
-
json.danuni?.data ?? '',
|
|
539
|
-
undefined,
|
|
540
|
-
options,
|
|
541
|
-
),
|
|
542
|
-
fmt: DM_format.ArtplayerJson,
|
|
543
|
-
}),
|
|
544
|
-
[DM_format.DDPlayJson]: (
|
|
545
|
-
json: DM_JSON_DDPlay & {
|
|
546
|
-
danuni?: DanUniConvertTip
|
|
547
|
-
},
|
|
548
|
-
) => ({
|
|
549
|
-
pool: this.fromDDPlay(json, json.danuni?.data ?? '', options),
|
|
550
|
-
fmt: DM_format.DDPlayJson,
|
|
551
|
-
}),
|
|
552
|
-
[DM_format.CommonAss]: (file: string) => ({
|
|
553
|
-
pool: this.fromASS(file, options),
|
|
554
|
-
fmt: DM_format.CommonAss,
|
|
555
|
-
}),
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
if (typeof mod === 'string') {
|
|
559
|
-
const fn = mod
|
|
560
|
-
// 直接按照默认模式处理匹配后缀的文件
|
|
561
|
-
try {
|
|
562
|
-
if (fn.endsWith(DM_format.DanuniJson)) {
|
|
563
|
-
return handlers[DM_format.DanuniJson](fileParser(file, 'json'))
|
|
564
|
-
} else if (fn.endsWith(DM_format.DanuniMinJson))
|
|
565
|
-
return handlers[DM_format.DanuniMinJson](fileParser(file, 'json'))
|
|
566
|
-
else if (fn.endsWith(DM_format.DanuniPbBin))
|
|
567
|
-
return handlers[DM_format.DanuniPbBin](fileParser(file, 'bin'))
|
|
568
|
-
else if (fn.endsWith(DM_format.BiliXml))
|
|
569
|
-
return handlers[DM_format.BiliXml](fileParser(file, 'string'))
|
|
570
|
-
else if (fn.endsWith(DM_format.BiliPbBin))
|
|
571
|
-
return handlers[DM_format.BiliPbBin](fileParser(file, 'bin'))
|
|
572
|
-
else if (fn.endsWith(DM_format.BiliCmdPbBin))
|
|
573
|
-
return handlers[DM_format.BiliCmdPbBin](fileParser(file, 'bin'))
|
|
574
|
-
else if (fn.endsWith(DM_format.BiliUpJson))
|
|
575
|
-
return handlers[DM_format.BiliUpJson](fileParser(file, 'json'))
|
|
576
|
-
else if (fn.endsWith(DM_format.DplayerJson))
|
|
577
|
-
return handlers[DM_format.DplayerJson](fileParser(file, 'json'))
|
|
578
|
-
else if (fn.endsWith(DM_format.ArtplayerJson))
|
|
579
|
-
return handlers[DM_format.ArtplayerJson](fileParser(file, 'json'))
|
|
580
|
-
else if (fn.endsWith(DM_format.DDPlayJson))
|
|
581
|
-
return handlers[DM_format.DDPlayJson](fileParser(file, 'json'))
|
|
582
|
-
else if (fn.endsWith(DM_format.CommonAss))
|
|
583
|
-
return handlers[DM_format.CommonAss](fileParser(file, 'string'))
|
|
584
|
-
} catch {}
|
|
585
|
-
// 按照后缀设定启用模块
|
|
586
|
-
const ext = fn.split('.').pop()?.toLowerCase()
|
|
587
|
-
if (ext) {
|
|
588
|
-
if (ext === 'json') mod = ['json']
|
|
589
|
-
else if (['xml', 'ass'].includes(ext)) mod = ['str']
|
|
590
|
-
else if (['binpb', 'bin', 'so'].includes(ext)) mod = ['bin']
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
if (!mod) mod = ['json', 'str', 'bin']
|
|
594
|
-
const err = '无法识别该文件,请手动指定格式!'
|
|
595
|
-
const parseJSON = (
|
|
596
|
-
json: DM_JSON_Artplayer &
|
|
597
|
-
DM_JSON_DDPlay &
|
|
598
|
-
DM_JSON_Dplayer &
|
|
599
|
-
DM_JSON_BiliUp & { danuni?: DanUniConvertTip },
|
|
600
|
-
): { pool: UniPool; fmt: DM_format } | undefined => {
|
|
601
|
-
try {
|
|
602
|
-
if (Array.isArray(json) && json.every((d) => d.SOID)) {
|
|
603
|
-
return handlers[DM_format.DanuniMinJson](json) // 使用兼容性参数,danuni.min.json解析器可以解析danuni.json
|
|
604
|
-
} else if (json.danmuku && json.danmuku.every((d) => d.text)) {
|
|
605
|
-
return handlers[DM_format.ArtplayerJson](json)
|
|
606
|
-
} else if (
|
|
607
|
-
json.count &&
|
|
608
|
-
json.comments &&
|
|
609
|
-
Array.isArray(json.comments) &&
|
|
610
|
-
json.comments.every((d) => d.m)
|
|
611
|
-
) {
|
|
612
|
-
return handlers[DM_format.DDPlayJson](json)
|
|
613
|
-
} else if (
|
|
614
|
-
json.code == 0 &&
|
|
615
|
-
json.data &&
|
|
616
|
-
Array.isArray(json.data) &&
|
|
617
|
-
json.data.every((d) => Array.isArray(d))
|
|
618
|
-
) {
|
|
619
|
-
return handlers[DM_format.DplayerJson](json)
|
|
620
|
-
} else if (
|
|
621
|
-
json.code == 0 &&
|
|
622
|
-
json.message == '0' &&
|
|
623
|
-
json.data &&
|
|
624
|
-
json.data.page &&
|
|
625
|
-
json.data.result &&
|
|
626
|
-
Array.isArray(json.data.result) &&
|
|
627
|
-
json.data.result.every((d) => d.id && d.oid)
|
|
628
|
-
) {
|
|
629
|
-
return handlers[DM_format.BiliUpJson](json)
|
|
630
|
-
}
|
|
631
|
-
} catch {}
|
|
632
|
-
}
|
|
633
|
-
const parseStr = (
|
|
634
|
-
file: string,
|
|
635
|
-
): { pool: UniPool; fmt: DM_format } | undefined => {
|
|
636
|
-
// json-str
|
|
637
|
-
if (mod.includes('json'))
|
|
638
|
-
try {
|
|
639
|
-
if (isJSON(file)) {
|
|
640
|
-
const json = JSON.parse(file)
|
|
641
|
-
return parseJSON(json)
|
|
642
|
-
}
|
|
643
|
-
} catch {}
|
|
644
|
-
// pure-str (xml/ass)
|
|
645
|
-
if (mod.includes('str')) {
|
|
646
|
-
try {
|
|
647
|
-
const xmlParser = new XMLParser({ ignoreAttributes: false })
|
|
648
|
-
const xml = xmlParser.parse(file)
|
|
649
|
-
if (xml?.i?.d) return handlers[DM_format.BiliXml](file)
|
|
650
|
-
} catch {}
|
|
651
|
-
try {
|
|
652
|
-
return handlers[DM_format.CommonAss](file)
|
|
653
|
-
} catch {}
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
let errmesg
|
|
657
|
-
if (typeof file === 'object' || Array.isArray(file)) {
|
|
658
|
-
if (file instanceof ArrayBuffer || file instanceof Uint8Array) {
|
|
659
|
-
// pure-bin (pb)
|
|
660
|
-
if (mod.includes('bin')) {
|
|
661
|
-
try {
|
|
662
|
-
return handlers[DM_format.DanuniPbBin](file)
|
|
663
|
-
} catch {}
|
|
664
|
-
try {
|
|
665
|
-
return handlers[DM_format.BiliPbBin](file)
|
|
666
|
-
} catch {}
|
|
667
|
-
try {
|
|
668
|
-
return handlers[DM_format.BiliCmdPbBin](file)
|
|
669
|
-
} catch {}
|
|
670
|
-
}
|
|
671
|
-
// str-bin (pure-str + json-str)
|
|
672
|
-
|
|
673
|
-
try {
|
|
674
|
-
const fileStr = new TextDecoder().decode(file)
|
|
675
|
-
const prStr = parseStr(fileStr)
|
|
676
|
-
if (prStr) {
|
|
677
|
-
return prStr
|
|
678
|
-
} else {
|
|
679
|
-
errmesg = `${err}(定位: bin->string)`
|
|
680
|
-
}
|
|
681
|
-
} catch {}
|
|
682
|
-
} else if (mod.includes('json')) {
|
|
683
|
-
// pure-json
|
|
684
|
-
const prJSON = parseJSON(file as any)
|
|
685
|
-
if (!prJSON) throw new Error(`${err}(定位: json)`)
|
|
686
|
-
return prJSON
|
|
687
|
-
}
|
|
688
|
-
} else if (isString(file)) {
|
|
689
|
-
// pure-str + json-str
|
|
690
|
-
const prStr = parseStr(file)
|
|
691
|
-
if (!prStr) throw new Error(`${err}(定位: string)`)
|
|
692
|
-
return prStr
|
|
693
|
-
}
|
|
694
|
-
throw new Error(errmesg ?? err)
|
|
695
|
-
}
|
|
696
|
-
convert2<T extends Convert2Formats>(
|
|
697
|
-
format: T,
|
|
698
|
-
file_wrapper: true,
|
|
699
|
-
continue_on_error?: boolean,
|
|
700
|
-
): File
|
|
701
|
-
convert2<T extends Convert2Formats>(
|
|
702
|
-
format: T,
|
|
703
|
-
file_wrapper?: false,
|
|
704
|
-
continue_on_error?: boolean,
|
|
705
|
-
): Convert2ResultMap[T]
|
|
706
|
-
convert2(
|
|
707
|
-
format: DM_format,
|
|
708
|
-
file_wrapper = false,
|
|
709
|
-
continue_on_error = false,
|
|
710
|
-
): File | Convert2ResultMap[Convert2Formats] {
|
|
711
|
-
switch (format) {
|
|
712
|
-
case DM_format.DanuniJson:
|
|
713
|
-
if (file_wrapper)
|
|
714
|
-
return new File([JSON.stringify(this.dans)], DM_format.DanuniJson, {
|
|
715
|
-
type: 'application/json',
|
|
716
|
-
})
|
|
717
|
-
else return this.dans
|
|
718
|
-
case DM_format.DanuniMinJson:
|
|
719
|
-
if (file_wrapper)
|
|
720
|
-
return new File(
|
|
721
|
-
[JSON.stringify(this.minify())],
|
|
722
|
-
DM_format.DanuniMinJson,
|
|
723
|
-
{
|
|
724
|
-
type: 'application/json',
|
|
725
|
-
},
|
|
726
|
-
)
|
|
727
|
-
else return this.minify()
|
|
728
|
-
case DM_format.DanuniPbBin:
|
|
729
|
-
if (file_wrapper)
|
|
730
|
-
return new File([this.toPb()], DM_format.DanuniPbBin, {
|
|
731
|
-
type: 'application/protobuf',
|
|
732
|
-
})
|
|
733
|
-
else return this.toPb()
|
|
734
|
-
case DM_format.BiliXml:
|
|
735
|
-
if (file_wrapper)
|
|
736
|
-
return new File([this.toBiliXML()], DM_format.BiliXml, {
|
|
737
|
-
type: 'application/xml',
|
|
738
|
-
})
|
|
739
|
-
else return this.toBiliXML()
|
|
740
|
-
// case DM_format.BiliPbBin:
|
|
741
|
-
// return this.toBiliBin()
|
|
742
|
-
// case DM_format.BiliCmdPbBin:
|
|
743
|
-
// return this.toBiliCmdBin()
|
|
744
|
-
// case DM_format.BiliUpJson:
|
|
745
|
-
// return this.toBiliUp()
|
|
746
|
-
case DM_format.DplayerJson:
|
|
747
|
-
if (file_wrapper)
|
|
748
|
-
return new File(
|
|
749
|
-
[JSON.stringify(this.toDplayer())],
|
|
750
|
-
DM_format.DplayerJson,
|
|
751
|
-
{
|
|
752
|
-
type: 'application/json',
|
|
753
|
-
},
|
|
754
|
-
)
|
|
755
|
-
return this.toDplayer()
|
|
756
|
-
case DM_format.ArtplayerJson:
|
|
757
|
-
if (file_wrapper)
|
|
758
|
-
return new File(
|
|
759
|
-
[JSON.stringify(this.toArtplayer())],
|
|
760
|
-
DM_format.ArtplayerJson,
|
|
761
|
-
{
|
|
762
|
-
type: 'application/json',
|
|
763
|
-
},
|
|
764
|
-
)
|
|
765
|
-
return this.toArtplayer()
|
|
766
|
-
case DM_format.DDPlayJson:
|
|
767
|
-
if (file_wrapper)
|
|
768
|
-
return new File(
|
|
769
|
-
[JSON.stringify(this.toDDPlay())],
|
|
770
|
-
DM_format.DDPlayJson,
|
|
771
|
-
{
|
|
772
|
-
type: 'application/json',
|
|
773
|
-
},
|
|
774
|
-
)
|
|
775
|
-
return this.toDDPlay()
|
|
776
|
-
// case DM_format.CommonAss:
|
|
777
|
-
// return this.toASS()
|
|
778
|
-
default: {
|
|
779
|
-
const message = '(err) Unknown format or unsupported now!'
|
|
780
|
-
if (continue_on_error) return message
|
|
781
|
-
else throw new Error(message)
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
minify() {
|
|
786
|
-
return this.dans.map((d) => d.minify())
|
|
787
|
-
}
|
|
788
|
-
static fromMin(json: DM_JSON_DanuniMin, options?: Options) {
|
|
789
|
-
return new UniPool(json.map((d: any) => UniDM.create(d, options)))
|
|
790
|
-
}
|
|
791
|
-
static fromPb(bin: Uint8Array | ArrayBuffer, options?: Options) {
|
|
792
|
-
const data = fromBinary(ListDanResponseSchema, new Uint8Array(bin))
|
|
793
|
-
return new UniPool(
|
|
794
|
-
data.danmakus.map((d) =>
|
|
795
|
-
UniDM.create(
|
|
796
|
-
{
|
|
797
|
-
...d,
|
|
798
|
-
SOID: d.soid,
|
|
799
|
-
DMID: d.dmid,
|
|
800
|
-
progress: d.progress / 1000,
|
|
801
|
-
mode: d.mode as number,
|
|
802
|
-
senderID: d.senderId,
|
|
803
|
-
ctime: timestampDate(d.ctime || timestampNow()),
|
|
804
|
-
pool: d.pool as number,
|
|
805
|
-
attr: d.attr as UniDMTools.DMAttr[],
|
|
806
|
-
extra: undefined,
|
|
807
|
-
extraStr: d.extra,
|
|
808
|
-
},
|
|
809
|
-
options,
|
|
810
|
-
),
|
|
811
|
-
),
|
|
812
|
-
options,
|
|
813
|
-
)
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* 转为 protobuf 二进制
|
|
817
|
-
*/
|
|
818
|
-
toPb() {
|
|
819
|
-
return toBinary(
|
|
820
|
-
ListDanResponseSchema,
|
|
821
|
-
create(ListDanResponseSchema, {
|
|
822
|
-
danmakus: this.dans.map((d) => {
|
|
823
|
-
return {
|
|
824
|
-
soid: d.SOID,
|
|
825
|
-
dmid: d.DMID ?? '',
|
|
826
|
-
progress: Math.round(d.progress * 1000),
|
|
827
|
-
mode: d.mode as number,
|
|
828
|
-
fontsize: d.fontsize,
|
|
829
|
-
color: d.color,
|
|
830
|
-
senderId: d.senderID,
|
|
831
|
-
content: d.content,
|
|
832
|
-
ctime: timestampFromDate(d.ctime),
|
|
833
|
-
weight: d.weight,
|
|
834
|
-
pool: d.pool as number,
|
|
835
|
-
attr: d.attr,
|
|
836
|
-
platform: d.platform,
|
|
837
|
-
extra: d.extraStr,
|
|
838
|
-
} satisfies Omit<Danmaku, '$typeName'>
|
|
839
|
-
}),
|
|
840
|
-
}),
|
|
841
|
-
)
|
|
842
|
-
}
|
|
843
|
-
static fromBiliXML(xml: string, options?: Options) {
|
|
844
|
-
const parser = new XMLParser({
|
|
845
|
-
ignoreAttributes: false,
|
|
846
|
-
isArray: (_name, jpath, _isLeafNode, _isAttribute) => {
|
|
847
|
-
if (jpath === 'i.d') return true
|
|
848
|
-
return false
|
|
849
|
-
},
|
|
850
|
-
})
|
|
851
|
-
const oriData: DM_XML_Bili & { i: { danuni?: DanUniConvertTip } } =
|
|
852
|
-
parser.parse(xml)
|
|
853
|
-
const dans = oriData.i.d
|
|
854
|
-
const fromConverted = !!oriData.i.danuni
|
|
855
|
-
const cid = BigInt(oriData.i.chatid)
|
|
856
|
-
return new UniPool(
|
|
857
|
-
dans
|
|
858
|
-
.map((d) => {
|
|
859
|
-
return UniDM.fromBili(
|
|
860
|
-
UniDM.parseBiliSingle(d['@_p'], d['#text']),
|
|
861
|
-
cid,
|
|
862
|
-
options,
|
|
863
|
-
fromConverted ? oriData.i.danuni?.data : undefined,
|
|
864
|
-
)
|
|
865
|
-
})
|
|
866
|
-
.filter((d) => d !== null),
|
|
867
|
-
options,
|
|
868
|
-
{ fromConverted },
|
|
869
|
-
)
|
|
870
|
-
}
|
|
871
|
-
toBiliXML(options?: {
|
|
872
|
-
/**
|
|
873
|
-
* 当SOID非来源bili时,若此处指定则使用该值为cid,否则使用SOID
|
|
874
|
-
*/
|
|
875
|
-
cid?: bigint
|
|
876
|
-
/**
|
|
877
|
-
* 跳过command类型的特殊弹幕
|
|
878
|
-
*/
|
|
879
|
-
skipBiliCommand?: boolean
|
|
880
|
-
/**
|
|
881
|
-
* 当仅含有来自bili的弹幕时,启用将保持发送者标识不含`@`
|
|
882
|
-
* @description
|
|
883
|
-
* bili的弹幕含midHash(crc),不启用该处使用senderID填充,启用则去除`@bili`部分,提高兼容性
|
|
884
|
-
*/
|
|
885
|
-
avoidSenderIDWithAt?: boolean
|
|
886
|
-
}): string {
|
|
887
|
-
const genCID = (id?: string) => {
|
|
888
|
-
if (id) {
|
|
889
|
-
const UniID = ID.fromString(id)
|
|
890
|
-
if (UniID.domain === platform.PlatformVideoSource.Bilibili) {
|
|
891
|
-
const cid = UniID.id.replaceAll(
|
|
892
|
-
`def_${platform.PlatformVideoSource.Bilibili}+`,
|
|
893
|
-
'',
|
|
894
|
-
)
|
|
895
|
-
if (cid) return cid
|
|
896
|
-
}
|
|
897
|
-
return options?.cid || id
|
|
898
|
-
} else return options?.cid || ID.fromNull().toString()
|
|
899
|
-
}
|
|
900
|
-
if (options?.avoidSenderIDWithAt) {
|
|
901
|
-
const ok = this.dans.every((d) =>
|
|
902
|
-
d.senderID.endsWith(`@${platform.PlatformVideoSource.Bilibili}`),
|
|
903
|
-
)
|
|
904
|
-
if (!ok) throw new Error('存在其他来源的senderID,请关闭该功能再试!')
|
|
905
|
-
}
|
|
906
|
-
let ds = this.dans.map((dan) => dan.toBiliXML(options))
|
|
907
|
-
if (options?.skipBiliCommand) ds = ds.filter((d) => d !== null)
|
|
908
|
-
const builder = new XMLBuilder({ ignoreAttributes: false })
|
|
909
|
-
return builder.build({
|
|
910
|
-
'?xml': {
|
|
911
|
-
'@_version': '1.0',
|
|
912
|
-
// eslint-disable-next-line unicorn/text-encoding-identifier-case
|
|
913
|
-
'@_encoding': 'UTF-8',
|
|
914
|
-
},
|
|
915
|
-
i: {
|
|
916
|
-
chatserver: 'chat.bilibili.com',
|
|
917
|
-
chatid: genCID(this.dans[0]?.SOID),
|
|
918
|
-
mission: 0,
|
|
919
|
-
maxlimit: this.dans.length,
|
|
920
|
-
state: 0,
|
|
921
|
-
real_name: 0,
|
|
922
|
-
source: 'k-v',
|
|
923
|
-
danuni: { ...DanUniConvertTipTemplate, data: this.getShared('SOID') },
|
|
924
|
-
d: ds,
|
|
925
|
-
},
|
|
926
|
-
})
|
|
927
|
-
}
|
|
928
|
-
static fromBiliGrpc(bin: Uint8Array | ArrayBuffer, options?: Options) {
|
|
929
|
-
const data = fromBinary(DmSegMobileReplySchema, new Uint8Array(bin))
|
|
930
|
-
const json = data.elems
|
|
931
|
-
return new UniPool(
|
|
932
|
-
json.map((d) => {
|
|
933
|
-
return UniDM.fromBili(
|
|
934
|
-
{ ...d, progress: d.progress / 1000 },
|
|
935
|
-
d.oid,
|
|
936
|
-
options,
|
|
937
|
-
)
|
|
938
|
-
}),
|
|
939
|
-
options,
|
|
940
|
-
)
|
|
941
|
-
}
|
|
942
|
-
/**
|
|
943
|
-
* @param bin 符合`DmWebViewReplySchema`(bili视频meta)的protobuf二进制
|
|
944
|
-
*/
|
|
945
|
-
static fromBiliCommandGrpc(bin: Uint8Array | ArrayBuffer, options?: Options) {
|
|
946
|
-
const data = fromBinary(DmWebViewReplySchema, new Uint8Array(bin))
|
|
947
|
-
const json = data.commandDms
|
|
948
|
-
return new UniPool(
|
|
949
|
-
json.map((d) => {
|
|
950
|
-
return UniDM.fromBiliCommand(d, d.oid, options)
|
|
951
|
-
}),
|
|
952
|
-
options,
|
|
953
|
-
)
|
|
954
|
-
}
|
|
955
|
-
static fromBiliUp(json: DM_JSON_BiliUp, options?: Options) {
|
|
956
|
-
return new UniPool(
|
|
957
|
-
json.data.result.map((d) => {
|
|
958
|
-
// 处理 attrs 字符串转换为 attr 二进制
|
|
959
|
-
// attrs 格式如 "1,13,21",每个数字对应二进制位
|
|
960
|
-
const attrBin = d.attrs
|
|
961
|
-
? d.attrs
|
|
962
|
-
.split(',')
|
|
963
|
-
.map(Number)
|
|
964
|
-
.reduce((bin, bitPosition) => bin | (1 << (bitPosition - 1)), 0)
|
|
965
|
-
: 0
|
|
966
|
-
|
|
967
|
-
return UniDM.fromBili(
|
|
968
|
-
{
|
|
969
|
-
id: BigInt(d.id_str || d.id),
|
|
970
|
-
progress: d.progress / 1000, // 毫秒转秒
|
|
971
|
-
mode: d.mode,
|
|
972
|
-
fontsize: d.fontsize,
|
|
973
|
-
color: Number.parseInt(d.color, 16),
|
|
974
|
-
mid: d.mid,
|
|
975
|
-
midHash: d.mid_hash,
|
|
976
|
-
content: d.msg,
|
|
977
|
-
ctime: BigInt(d.ctime),
|
|
978
|
-
pool: d.pool,
|
|
979
|
-
// idStr: d.id_str,
|
|
980
|
-
attr: attrBin,
|
|
981
|
-
oid: BigInt(d.oid),
|
|
982
|
-
},
|
|
983
|
-
BigInt(d.oid),
|
|
984
|
-
options,
|
|
985
|
-
)
|
|
986
|
-
}),
|
|
987
|
-
options,
|
|
988
|
-
)
|
|
989
|
-
}
|
|
990
|
-
static fromDplayer(
|
|
991
|
-
json: DM_JSON_Dplayer & { danuni?: DanUniConvertTip },
|
|
992
|
-
playerID: string,
|
|
993
|
-
domain = 'other',
|
|
994
|
-
options?: Options,
|
|
995
|
-
) {
|
|
996
|
-
return new UniPool(
|
|
997
|
-
json.data.map((d) => {
|
|
998
|
-
return UniDM.fromDplayer(
|
|
999
|
-
{
|
|
1000
|
-
content: d[4],
|
|
1001
|
-
progress: d[0],
|
|
1002
|
-
mode: d[1],
|
|
1003
|
-
color: d[2],
|
|
1004
|
-
midHash: d[3],
|
|
1005
|
-
},
|
|
1006
|
-
playerID,
|
|
1007
|
-
domain,
|
|
1008
|
-
options,
|
|
1009
|
-
)
|
|
1010
|
-
}),
|
|
1011
|
-
options,
|
|
1012
|
-
{ fromConverted: !!json.danuni },
|
|
1013
|
-
)
|
|
1014
|
-
}
|
|
1015
|
-
toDplayer(): DM_JSON_Dplayer & { danuni?: DanUniConvertTip } {
|
|
1016
|
-
return {
|
|
1017
|
-
code: 0,
|
|
1018
|
-
danuni: {
|
|
1019
|
-
...DanUniConvertTipTemplate,
|
|
1020
|
-
data: this.dans[0]?.SOID.split('@')[0],
|
|
1021
|
-
},
|
|
1022
|
-
data: this.dans.map((dan) => {
|
|
1023
|
-
const d = dan.toDplayer()
|
|
1024
|
-
return [d.progress, d.mode, d.color, d.midHash, d.content]
|
|
1025
|
-
}),
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
static fromArtplayer(
|
|
1029
|
-
json: DM_JSON_Artplayer & { danuni?: DanUniConvertTip },
|
|
1030
|
-
playerID: string,
|
|
1031
|
-
domain = 'other',
|
|
1032
|
-
options?: Options,
|
|
1033
|
-
) {
|
|
1034
|
-
return new UniPool(
|
|
1035
|
-
json.danmuku.map((d) => {
|
|
1036
|
-
return UniDM.fromArtplayer(
|
|
1037
|
-
{
|
|
1038
|
-
content: d.text,
|
|
1039
|
-
progress: d.time || 0,
|
|
1040
|
-
mode: d.mode || 0,
|
|
1041
|
-
color: Number((d.color || 'FFFFFF').replace('#', '0x')),
|
|
1042
|
-
style: d.style,
|
|
1043
|
-
},
|
|
1044
|
-
playerID,
|
|
1045
|
-
domain,
|
|
1046
|
-
options,
|
|
1047
|
-
)
|
|
1048
|
-
}),
|
|
1049
|
-
options,
|
|
1050
|
-
{ fromConverted: !!json.danuni },
|
|
1051
|
-
)
|
|
1052
|
-
}
|
|
1053
|
-
toArtplayer(): DM_JSON_Artplayer & { danuni?: DanUniConvertTip } {
|
|
1054
|
-
return {
|
|
1055
|
-
danuni: {
|
|
1056
|
-
...DanUniConvertTipTemplate,
|
|
1057
|
-
data: this.dans[0]?.SOID.split('@')[0],
|
|
1058
|
-
},
|
|
1059
|
-
danmuku: this.dans.map((dan) => {
|
|
1060
|
-
const d = dan.toArtplayer()
|
|
1061
|
-
return {
|
|
1062
|
-
text: d.content,
|
|
1063
|
-
time: d.progress,
|
|
1064
|
-
mode: d.mode as 0 | 1 | 2,
|
|
1065
|
-
color: `#${d.color.toString(16).toUpperCase() || 'FFFFFF'}`,
|
|
1066
|
-
border: d.border,
|
|
1067
|
-
style: d.style,
|
|
1068
|
-
}
|
|
1069
|
-
}),
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
static fromDDPlay(
|
|
1073
|
-
json: DM_JSON_DDPlay & { danuni?: DanUniConvertTip },
|
|
1074
|
-
episodeId: string,
|
|
1075
|
-
options?: Options,
|
|
1076
|
-
) {
|
|
1077
|
-
return new UniPool(
|
|
1078
|
-
json.comments.map((d) => {
|
|
1079
|
-
const p_arr = d.p.split(',')
|
|
1080
|
-
return UniDM.fromDDPlay(
|
|
1081
|
-
{
|
|
1082
|
-
cid: d.cid,
|
|
1083
|
-
color: Number.parseInt(p_arr[2]),
|
|
1084
|
-
m: d.m,
|
|
1085
|
-
mode: Number.parseInt(p_arr[1]),
|
|
1086
|
-
progress: Number.parseFloat(p_arr[0]),
|
|
1087
|
-
uid: p_arr[3],
|
|
1088
|
-
},
|
|
1089
|
-
episodeId,
|
|
1090
|
-
undefined, //使用默认
|
|
1091
|
-
options,
|
|
1092
|
-
)
|
|
1093
|
-
}),
|
|
1094
|
-
options,
|
|
1095
|
-
{ fromConverted: !!json.danuni },
|
|
1096
|
-
)
|
|
1097
|
-
}
|
|
1098
|
-
toDDPlay(): DM_JSON_DDPlay & { danuni?: DanUniConvertTip } {
|
|
1099
|
-
const episodeId = this.dans[0]?.SOID.split('@')[0].replaceAll(
|
|
1100
|
-
`def_${platform.PlatformDanmakuOnlySource.DanDanPlay}+`,
|
|
1101
|
-
'',
|
|
1102
|
-
)
|
|
1103
|
-
return {
|
|
1104
|
-
danuni: { ...DanUniConvertTipTemplate, data: episodeId },
|
|
1105
|
-
count: this.dans.length,
|
|
1106
|
-
comments: this.dans.map((dan) => {
|
|
1107
|
-
const d = dan.toDDPlay()
|
|
1108
|
-
return {
|
|
1109
|
-
cid: d.cid,
|
|
1110
|
-
p: `${d.progress},${d.mode},${d.color},${d.uid}`,
|
|
1111
|
-
m: d.m,
|
|
1112
|
-
}
|
|
1113
|
-
}),
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
static fromASS(ass: string, options?: Options) {
|
|
1117
|
-
return parseAssRawField(ass, options)
|
|
1118
|
-
}
|
|
1119
|
-
/**
|
|
1120
|
-
* 转换为ASS字幕格式的弹幕,需播放器支持多行ASS渲染
|
|
1121
|
-
*/
|
|
1122
|
-
toASS(canvasCtx: CanvasCtx, options?: AssGenOptions): string {
|
|
1123
|
-
const defaultOptions: AssGenOptions = { substyle: {} }
|
|
1124
|
-
const finalOptions = options ?? defaultOptions
|
|
1125
|
-
const fn = this.getShared('SOID')
|
|
1126
|
-
return generateASS(
|
|
1127
|
-
this,
|
|
1128
|
-
{ filename: fn, title: fn, ...finalOptions },
|
|
1129
|
-
canvasCtx,
|
|
1130
|
-
)
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
export {
|
|
1135
|
-
platform,
|
|
1136
|
-
// UniPool,
|
|
1137
|
-
UniDM,
|
|
1138
|
-
UniDMTools,
|
|
1139
|
-
UniIDTools,
|
|
1140
|
-
type DM_JSON_BiliCommandGrpc,
|
|
1141
|
-
// type UniDMType,
|
|
1142
|
-
// type UniIDType,
|
|
1143
|
-
}
|
|
1144
|
-
export * as plugins from './plugins'
|