@bililive-tools/douyin-recorder 1.5.1 → 1.5.3

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/lib/douyin_api.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import axios from "axios";
2
2
  import { isEmpty } from "lodash-es";
3
3
  import { assert } from "./utils.js";
4
+ import { ABogus } from "./sign.js";
4
5
  const requester = axios.create({
5
6
  timeout: 10e3,
6
7
  // axios 会自动读取环境变量中的 http_proxy 和 https_proxy 并应用,这会让请求发往代理的 host。
@@ -71,6 +72,13 @@ export const getCookie = async () => {
71
72
  return cookie.split(";")[0];
72
73
  })
73
74
  .join("; ");
75
+ if (!cookies.includes("ttwid")) {
76
+ // 如果不含ttwid,且已经存在含ttwid的cookie,将缓存时间直接增加1小时,复用之前的参数
77
+ if (cookieCache?.cookies) {
78
+ cookieCache.startTimestamp += 60 * 60 * 1000; // 增加1小时
79
+ return cookieCache.cookies;
80
+ }
81
+ }
74
82
  cookieCache = {
75
83
  startTimestamp: now,
76
84
  cookies,
@@ -87,28 +95,30 @@ export async function getRoomInfo(webRoomId, opts = {}) {
87
95
  // 所以在这里请求一次自动设置。
88
96
  cookies = await getCookie();
89
97
  }
90
- const res = await requester.get("https://live.douyin.com/webcast/room/web/enter/", {
91
- params: {
92
- aid: 6383,
93
- live_id: 1,
94
- device_platform: "web",
95
- language: "zh-CN",
96
- enter_from: "web_live",
97
- cookie_enabled: "true",
98
- screen_width: 1920,
99
- screen_height: 1080,
100
- browser_language: "zh-CN",
101
- browser_platform: "MacIntel",
102
- browser_name: "Chrome",
103
- browser_version: "108.0.0.0",
104
- web_rid: webRoomId,
105
- // enter_source:,
106
- "Room-Enter-User-Login-Ab": 0,
107
- is_need_double_stream: "false",
108
- a_bogus: "1",
109
- },
98
+ const params = {
99
+ aid: 6383,
100
+ live_id: 1,
101
+ device_platform: "web",
102
+ language: "zh-CN",
103
+ enter_from: "web_live",
104
+ cookie_enabled: "true",
105
+ screen_width: 1920,
106
+ screen_height: 1080,
107
+ browser_language: "zh-CN",
108
+ browser_platform: "MacIntel",
109
+ browser_name: "Chrome",
110
+ browser_version: "108.0.0.0",
111
+ web_rid: webRoomId,
112
+ // enter_source:,
113
+ "Room-Enter-User-Login-Ab": 0,
114
+ is_need_double_stream: "false",
115
+ };
116
+ const abogus = new ABogus();
117
+ const [query, _, ua] = abogus.generateAbogus(new URLSearchParams(params).toString(), "");
118
+ const res = await requester.get(`https://live.douyin.com/webcast/room/web/enter/?${query}`, {
110
119
  headers: {
111
120
  cookie: cookies,
121
+ "User-Agent": ua,
112
122
  },
113
123
  });
114
124
  // 无 cookie 时 code 为 10037
@@ -126,7 +136,7 @@ export async function getRoomInfo(webRoomId, opts = {}) {
126
136
  doubleScreen: opts.doubleScreen,
127
137
  });
128
138
  }
129
- assert(res.data.status_code === 0, `Unexpected resp, code ${res.data.status_code}, msg ${JSON.stringify(res.data.data)}, id ${webRoomId}`);
139
+ assert(res.data.status_code === 0, `Unexpected resp, code ${res.data.status_code}, msg ${JSON.stringify(res.data.data)}, id ${webRoomId}, cookies: ${cookies}`);
130
140
  const data = res.data.data;
131
141
  const room = data.data[0];
132
142
  assert(room, `No room data, id ${webRoomId}`);
package/lib/index.js CHANGED
@@ -253,7 +253,31 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
253
253
  client.on("reconnect", (attempts) => {
254
254
  this.emit("DebugLog", {
255
255
  type: "common",
256
- text: `danma has reconnect ${attempts}`,
256
+ text: `douyin ${this.channelId} danma has reconnect ${attempts}`,
257
+ });
258
+ });
259
+ client.on("error", (err) => {
260
+ this.emit("DebugLog", {
261
+ type: "common",
262
+ text: `douyin ${this.channelId} danma error: ${String(err)}`,
263
+ });
264
+ });
265
+ client.on("init", (url) => {
266
+ this.emit("DebugLog", {
267
+ type: "common",
268
+ text: `douyin ${this.channelId} danma init ${url}`,
269
+ });
270
+ });
271
+ client.on("open", () => {
272
+ this.emit("DebugLog", {
273
+ type: "common",
274
+ text: `douyin ${this.channelId} danma open`,
275
+ });
276
+ });
277
+ client.on("close", () => {
278
+ this.emit("DebugLog", {
279
+ type: "common",
280
+ text: `douyin danma close`,
257
281
  });
258
282
  });
259
283
  // client.on("open", () => {
@@ -287,8 +311,8 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
287
311
  if (!this.recordHandle)
288
312
  return;
289
313
  this.state = "stopping-record";
290
- client.close();
291
314
  try {
315
+ client.close();
292
316
  await recorder.stop();
293
317
  }
294
318
  catch (err) {
@@ -323,7 +347,7 @@ export const provider = {
323
347
  siteURL: "https://live.douyin.com/",
324
348
  matchURL(channelURL) {
325
349
  // 支持 v.douyin.com 和 live.douyin.com
326
- return /https?:\/\/(live|v)\.douyin\.com\//.test(channelURL);
350
+ return /https?:\/\/(live|v|www)\.douyin\.com\//.test(channelURL);
327
351
  },
328
352
  async resolveChannelInfoFromURL(channelURL) {
329
353
  if (!this.matchURL(channelURL))
@@ -347,6 +371,7 @@ export const provider = {
347
371
  id: info.roomId,
348
372
  title: info.title,
349
373
  owner: info.owner,
374
+ avatar: info.avatar,
350
375
  };
351
376
  },
352
377
  createRecorder(opts) {
package/lib/sign.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ export declare class StringProcessor {
2
+ static toCharStr(bytes: Uint8Array): string;
3
+ static toCharArray(s: string): number[];
4
+ static generateRandomBytes(length: number): string;
5
+ }
6
+ export declare class CryptoUtility {
7
+ salt: string;
8
+ base64Alphabet: string[][];
9
+ bigArray: number[];
10
+ constructor(salt: string, customBase64Alphabet: string[]);
11
+ static sm3ToArray(input: Uint8Array | string): number[];
12
+ addSalt(param: string): string;
13
+ paramsToArray(param: string, addSalt: boolean): number[];
14
+ transformBytes(valuesList: number[]): number[];
15
+ base64Encode(bytes: Uint8Array, selectedAlphabet: number): string;
16
+ abogusEncode(values: number[], selectedAlphabet: number): string;
17
+ static rc4Encrypt(key: number[], plaintext: string): Uint8Array;
18
+ }
19
+ export declare class BrowserFingerprintGenerator {
20
+ static generateFingerprint(browserType: string): string;
21
+ private static _generateFingerprint;
22
+ }
23
+ export declare class ABogus {
24
+ cryptoUtility: CryptoUtility;
25
+ userAgent: string;
26
+ browserFp: string;
27
+ options: number[];
28
+ pageId: number;
29
+ aid: number;
30
+ uaKey: number[];
31
+ sortIndex: number[];
32
+ sortIndex2: number[];
33
+ constructor(fp?: string, userAgent?: string, options?: number[]);
34
+ generateAbogus(params: string, body: string): [string, string, string, string];
35
+ }
package/lib/sign.js ADDED
@@ -0,0 +1,295 @@
1
+ // abogus.ts
2
+ // 这是对 Rust 版 ABogus 的 TypeScript 实现
3
+ // 代码来自:https://github.com/hua0512/rust-srec/blob/6444641014ea58628af9b0fa51b099620a01d0d0/crates/platforms/src/extractor/platforms/douyin/abogus.rs
4
+ // 依赖 sm3、rc4、random 等库
5
+ import { sm3 } from "sm-crypto"; // npm install sm-crypto
6
+ export class StringProcessor {
7
+ static toCharStr(bytes) {
8
+ return Array.from(bytes)
9
+ .map((b) => String.fromCharCode(b))
10
+ .join("");
11
+ }
12
+ static toCharArray(s) {
13
+ return Array.from(s).map((c) => c.charCodeAt(0));
14
+ }
15
+ static generateRandomBytes(length) {
16
+ const result = [];
17
+ for (let i = 0; i < length; i++) {
18
+ const rd = Math.floor(Math.random() * 10000);
19
+ result.push((rd & 255 & 170) | 1);
20
+ result.push((rd & 255 & 85) | 2);
21
+ result.push(((rd >> 8) & 170) | 5);
22
+ result.push(((rd >> 8) & 85) | 40);
23
+ }
24
+ return this.toCharStr(Uint8Array.from(result));
25
+ }
26
+ }
27
+ export class CryptoUtility {
28
+ salt;
29
+ base64Alphabet;
30
+ bigArray;
31
+ constructor(salt, customBase64Alphabet) {
32
+ this.salt = salt;
33
+ this.base64Alphabet = customBase64Alphabet.map((s) => Array.from(s));
34
+ this.bigArray = [
35
+ 121, 243, 55, 234, 103, 36, 47, 228, 30, 231, 106, 6, 115, 95, 78, 101, 250, 207, 198, 50,
36
+ 139, 227, 220, 105, 97, 143, 34, 28, 194, 215, 18, 100, 159, 160, 43, 8, 169, 217, 180, 120,
37
+ 247, 45, 90, 11, 27, 197, 46, 3, 84, 72, 5, 68, 62, 56, 221, 75, 144, 79, 73, 161, 178, 81,
38
+ 64, 187, 134, 117, 186, 118, 16, 241, 130, 71, 89, 147, 122, 129, 65, 40, 88, 150, 110, 219,
39
+ 199, 255, 181, 254, 48, 4, 195, 248, 208, 32, 116, 167, 69, 201, 17, 124, 125, 104, 96, 83,
40
+ 80, 127, 236, 108, 154, 126, 204, 15, 20, 135, 112, 158, 13, 1, 188, 164, 210, 237, 222, 98,
41
+ 212, 77, 253, 42, 170, 202, 26, 22, 29, 182, 251, 10, 173, 152, 58, 138, 54, 141, 185, 33,
42
+ 157, 31, 252, 132, 233, 235, 102, 196, 191, 223, 240, 148, 39, 123, 92, 82, 128, 109, 57, 24,
43
+ 38, 113, 209, 245, 2, 119, 153, 229, 189, 214, 230, 174, 232, 63, 52, 205, 86, 140, 66, 175,
44
+ 111, 171, 246, 133, 238, 193, 99, 60, 74, 91, 225, 51, 76, 37, 145, 211, 166, 151, 213, 206,
45
+ 0, 200, 244, 176, 218, 44, 184, 172, 49, 216, 93, 168, 53, 21, 183, 41, 67, 85, 224, 155, 226,
46
+ 242, 87, 177, 146, 70, 190, 12, 162, 19, 137, 114, 25, 165, 163, 192, 23, 59, 9, 94, 179, 107,
47
+ 35, 7, 142, 131, 239, 203, 149, 136, 61, 249, 14, 156,
48
+ ];
49
+ }
50
+ static sm3ToArray(input) {
51
+ const hash = sm3(input instanceof Uint8Array ? Buffer.from(input) : input);
52
+ return Buffer.from(hash, "hex").toJSON().data;
53
+ }
54
+ addSalt(param) {
55
+ return param + this.salt;
56
+ }
57
+ paramsToArray(param, addSalt) {
58
+ const processed = addSalt ? this.addSalt(param) : param;
59
+ return CryptoUtility.sm3ToArray(processed);
60
+ }
61
+ transformBytes(valuesList) {
62
+ const result = [];
63
+ let indexB = this.bigArray[1];
64
+ let initialValue = 0, valueE = 0;
65
+ const arrayLen = this.bigArray.length;
66
+ for (let index = 0; index < valuesList.length; index++) {
67
+ let sumInitial;
68
+ if (index === 0) {
69
+ initialValue = this.bigArray[indexB];
70
+ sumInitial = indexB + initialValue;
71
+ this.bigArray[1] = initialValue;
72
+ this.bigArray[indexB] = indexB;
73
+ }
74
+ else {
75
+ sumInitial = initialValue + valueE;
76
+ }
77
+ const sumInitialIdx = sumInitial % arrayLen;
78
+ const valueF = this.bigArray[sumInitialIdx];
79
+ result.push(valuesList[index] ^ valueF);
80
+ const nextIdx = (index + 2) % arrayLen;
81
+ valueE = this.bigArray[nextIdx];
82
+ const newSumInitialIdx = (indexB + valueE) % arrayLen;
83
+ initialValue = this.bigArray[newSumInitialIdx];
84
+ [this.bigArray[newSumInitialIdx], this.bigArray[nextIdx]] = [
85
+ this.bigArray[nextIdx],
86
+ this.bigArray[newSumInitialIdx],
87
+ ];
88
+ indexB = newSumInitialIdx;
89
+ }
90
+ return result;
91
+ }
92
+ base64Encode(bytes, selectedAlphabet) {
93
+ const alphabet = this.base64Alphabet[selectedAlphabet];
94
+ let output = "";
95
+ for (let i = 0; i < bytes.length; i += 3) {
96
+ const b1 = bytes[i];
97
+ const b2 = bytes[i + 1] || 0;
98
+ const b3 = bytes[i + 2] || 0;
99
+ const combined = (b1 << 16) | (b2 << 8) | b3;
100
+ output += alphabet[(combined >> 18) & 63];
101
+ output += alphabet[(combined >> 12) & 63];
102
+ output += i + 1 < bytes.length ? alphabet[(combined >> 6) & 63] : "";
103
+ output += i + 2 < bytes.length ? alphabet[combined & 63] : "";
104
+ }
105
+ while (output.length % 4 !== 0)
106
+ output += "=";
107
+ return output;
108
+ }
109
+ abogusEncode(values, selectedAlphabet) {
110
+ const alphabet = this.base64Alphabet[selectedAlphabet];
111
+ let abogus = "";
112
+ for (let i = 0; i < values.length; i += 3) {
113
+ const v1 = values[i];
114
+ const v2 = values[i + 1] || 0;
115
+ const v3 = values[i + 2] || 0;
116
+ const n = (v1 << 16) | (v2 << 8) | v3;
117
+ abogus += alphabet[(n & 0xfc0000) >> 18];
118
+ abogus += alphabet[(n & 0x03f000) >> 12];
119
+ abogus += i + 1 < values.length ? alphabet[(n & 0x0fc0) >> 6] : "";
120
+ abogus += i + 2 < values.length ? alphabet[n & 0x3f] : "";
121
+ }
122
+ while (abogus.length % 4 !== 0)
123
+ abogus += "=";
124
+ return abogus;
125
+ }
126
+ static rc4Encrypt(key, plaintext) {
127
+ // 推荐用 npm 包 rc4 或自己实现
128
+ const S = Array.from({ length: 256 }, (_, i) => i);
129
+ let j = 0;
130
+ for (let i = 0; i < 256; i++) {
131
+ j = (j + S[i] + key[i % key.length]) & 0xff;
132
+ [S[i], S[j]] = [S[j], S[i]];
133
+ }
134
+ let i = 0;
135
+ j = 0;
136
+ const ptBytes = StringProcessor.toCharArray(plaintext);
137
+ const ct = [];
138
+ for (const charVal of ptBytes) {
139
+ i = (i + 1) & 0xff;
140
+ j = (j + S[i]) & 0xff;
141
+ [S[i], S[j]] = [S[j], S[i]];
142
+ const k = S[(S[i] + S[j]) & 0xff];
143
+ ct.push(charVal ^ k);
144
+ }
145
+ return Uint8Array.from(ct);
146
+ }
147
+ }
148
+ export class BrowserFingerprintGenerator {
149
+ static generateFingerprint(browserType) {
150
+ switch (browserType) {
151
+ case "Chrome":
152
+ case "Edge":
153
+ case "Firefox":
154
+ return this._generateFingerprint("Win32");
155
+ case "Safari":
156
+ return this._generateFingerprint("MacIntel");
157
+ default:
158
+ return this._generateFingerprint("Win32");
159
+ }
160
+ }
161
+ static _generateFingerprint(platform) {
162
+ const rand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
163
+ const innerWidth = rand(1024, 1920);
164
+ const innerHeight = rand(768, 1080);
165
+ const outerWidth = innerWidth + rand(24, 32);
166
+ const outerHeight = innerHeight + rand(75, 90);
167
+ const screenX = 0;
168
+ const screenY = [0, 30][rand(0, 1)];
169
+ const sizeWidth = rand(1024, 1920);
170
+ const sizeHeight = rand(768, 1080);
171
+ const availWidth = rand(1280, 1920);
172
+ const availHeight = rand(800, 1080);
173
+ return `${innerWidth}|${innerHeight}|${outerWidth}|${outerHeight}|${screenX}|${screenY}|0|0|${sizeWidth}|${sizeHeight}|${availWidth}|${availHeight}|${innerWidth}|${innerHeight}|24|24|${platform}`;
174
+ }
175
+ }
176
+ export class ABogus {
177
+ cryptoUtility;
178
+ userAgent;
179
+ browserFp;
180
+ options;
181
+ pageId;
182
+ aid;
183
+ uaKey;
184
+ sortIndex;
185
+ sortIndex2;
186
+ constructor(fp, userAgent, options) {
187
+ const salt = "cus";
188
+ const character = "Dkdpgh2ZmsQB80/MfvV36XI1R45-WUAlEixNLwoqYTOPuzKFjJnry79HbGcaStCe";
189
+ const character2 = "ckdp1h4ZKsUB80/Mfvw36XIgR25+WQAlEi7NLboqYTOPuzmFjJnryx9HVGDaStCe";
190
+ const characterList = [character, character2];
191
+ this.cryptoUtility = new CryptoUtility(salt, characterList);
192
+ this.userAgent =
193
+ userAgent && userAgent.length > 0
194
+ ? userAgent
195
+ : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0";
196
+ this.browserFp =
197
+ fp && fp.length > 0 ? fp : BrowserFingerprintGenerator.generateFingerprint("Edge");
198
+ this.options = options || [0, 1, 14];
199
+ this.pageId = 0;
200
+ this.aid = 6383;
201
+ this.uaKey = [0x00, 0x01, 0x0e];
202
+ this.sortIndex = [
203
+ 18, 20, 52, 26, 30, 34, 58, 38, 40, 53, 42, 21, 27, 54, 55, 31, 35, 57, 39, 41, 43, 22, 28,
204
+ 32, 60, 36, 23, 29, 33, 37, 44, 45, 59, 46, 47, 48, 49, 50, 24, 25, 65, 66, 70, 71,
205
+ ];
206
+ this.sortIndex2 = [
207
+ 18, 20, 26, 30, 34, 38, 40, 42, 21, 27, 31, 35, 39, 41, 43, 22, 28, 32, 36, 23, 29, 33, 37,
208
+ 44, 45, 46, 47, 48, 49, 50, 24, 25, 52, 53, 54, 55, 57, 58, 59, 60, 65, 66, 70, 71,
209
+ ];
210
+ }
211
+ generateAbogus(params, body) {
212
+ const abDir = {
213
+ 8: 3,
214
+ 18: 44,
215
+ 66: 0,
216
+ 69: 0,
217
+ 70: 0,
218
+ 71: 0,
219
+ };
220
+ const startEncryption = Date.now();
221
+ // Hash(Hash(params))
222
+ const paramsHash1 = this.cryptoUtility.paramsToArray(params, true);
223
+ // @ts-ignore
224
+ const array1 = CryptoUtility.sm3ToArray(paramsHash1);
225
+ // Hash(Hash(body))
226
+ const bodyHash1 = this.cryptoUtility.paramsToArray(body, true);
227
+ // @ts-ignore
228
+ const array2 = CryptoUtility.sm3ToArray(bodyHash1);
229
+ // Hash(Base64(RC4(user_agent)))
230
+ const rc4Ua = CryptoUtility.rc4Encrypt(this.uaKey, this.userAgent);
231
+ const uaB64 = this.cryptoUtility.base64Encode(rc4Ua, 1);
232
+ const array3 = this.cryptoUtility.paramsToArray(uaB64, false);
233
+ const endEncryption = Date.now();
234
+ // 动态填充 abDir
235
+ abDir[20] = (startEncryption >> 24) & 255;
236
+ abDir[21] = (startEncryption >> 16) & 255;
237
+ abDir[22] = (startEncryption >> 8) & 255;
238
+ abDir[23] = startEncryption & 255;
239
+ abDir[24] = Math.floor(startEncryption / 0x100000000);
240
+ abDir[25] = Math.floor(startEncryption / 0x10000000000);
241
+ abDir[26] = (this.options[0] >> 24) & 255;
242
+ abDir[27] = (this.options[0] >> 16) & 255;
243
+ abDir[28] = (this.options[0] >> 8) & 255;
244
+ abDir[29] = this.options[0] & 255;
245
+ abDir[30] = Math.floor(this.options[1] / 256) & 255;
246
+ abDir[31] = this.options[1] % 256;
247
+ abDir[32] = (this.options[1] >> 24) & 255;
248
+ abDir[33] = (this.options[1] >> 16) & 255;
249
+ abDir[34] = (this.options[2] >> 24) & 255;
250
+ abDir[35] = (this.options[2] >> 16) & 255;
251
+ abDir[36] = (this.options[2] >> 8) & 255;
252
+ abDir[37] = this.options[2] & 255;
253
+ abDir[38] = array1[21];
254
+ abDir[39] = array1[22];
255
+ abDir[40] = array2[21];
256
+ abDir[41] = array2[22];
257
+ abDir[42] = array3[23];
258
+ abDir[43] = array3[24];
259
+ abDir[44] = (endEncryption >> 24) & 255;
260
+ abDir[45] = (endEncryption >> 16) & 255;
261
+ abDir[46] = (endEncryption >> 8) & 255;
262
+ abDir[47] = endEncryption & 255;
263
+ abDir[48] = abDir[8];
264
+ abDir[49] = Math.floor(endEncryption / 0x100000000);
265
+ abDir[50] = Math.floor(endEncryption / 0x10000000000);
266
+ abDir[51] = (this.pageId >> 24) & 255;
267
+ abDir[52] = (this.pageId >> 16) & 255;
268
+ abDir[53] = (this.pageId >> 8) & 255;
269
+ abDir[54] = this.pageId & 255;
270
+ abDir[55] = this.pageId;
271
+ abDir[56] = this.aid;
272
+ abDir[57] = this.aid & 255;
273
+ abDir[58] = (this.aid >> 8) & 255;
274
+ abDir[59] = (this.aid >> 16) & 255;
275
+ abDir[60] = (this.aid >> 24) & 255;
276
+ abDir[64] = this.browserFp.length;
277
+ abDir[65] = this.browserFp.length;
278
+ const sortedValues = this.sortIndex.map((i) => abDir[i] || 0);
279
+ const fpArray = StringProcessor.toCharArray(this.browserFp);
280
+ let abXor = 0;
281
+ this.sortIndex2.forEach((key, idx) => {
282
+ const val = abDir[key] || 0;
283
+ abXor = idx === 0 ? val : abXor ^ val;
284
+ });
285
+ const allValues = [...sortedValues, ...fpArray, abXor];
286
+ const transformedValues = this.cryptoUtility.transformBytes(allValues);
287
+ const randomPrefix = StringProcessor.generateRandomBytes(3)
288
+ .split("")
289
+ .map((c) => c.charCodeAt(0));
290
+ const finalValues = [...randomPrefix, ...transformedValues];
291
+ const abogus = this.cryptoUtility.abogusEncode(finalValues, 0);
292
+ const finalParams = `${params}&a_bogus=${abogus}`;
293
+ return [finalParams, abogus, this.userAgent, body];
294
+ }
295
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bililive-tools/douyin-recorder",
3
- "version": "1.5.1",
3
+ "version": "1.5.3",
4
4
  "description": "@bililive-tools douyin recorder implemention",
5
5
  "main": "./lib/index.js",
6
6
  "type": "module",
@@ -37,8 +37,9 @@
37
37
  "axios": "^1.7.8",
38
38
  "lodash-es": "^4.17.21",
39
39
  "mitt": "^3.0.1",
40
- "@bililive-tools/manager": "^1.4.0",
41
- "douyin-danma-listener": "0.2.0"
40
+ "sm-crypto": "^0.3.13",
41
+ "douyin-danma-listener": "0.2.0",
42
+ "@bililive-tools/manager": "^1.5.0"
42
43
  },
43
44
  "devDependencies": {
44
45
  "@types/node": "*"