@bililive-tools/douyu-recorder 1.2.0 → 1.3.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/lib/dy_client/index.d.ts +1 -0
- package/lib/dy_client/index.js +6 -1
- package/lib/index.js +32 -8
- package/package.json +2 -2
package/lib/dy_client/index.d.ts
CHANGED
package/lib/dy_client/index.js
CHANGED
|
@@ -15,7 +15,12 @@ export function createDYClient(channelId, opts = {}) {
|
|
|
15
15
|
const send = (message) => ws?.send(coder.encode(STT.serialize(message)));
|
|
16
16
|
const sendLogin = () => send({ type: "loginreq", roomid: channelId });
|
|
17
17
|
const sendJoinGroup = () => send({ type: "joingroup", rid: channelId, gid: -9999 });
|
|
18
|
-
const sendHeartbeat = () =>
|
|
18
|
+
const sendHeartbeat = () => {
|
|
19
|
+
if (ws?.readyState !== WebSocket.OPEN) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
send({ type: "mrkl" });
|
|
23
|
+
};
|
|
19
24
|
const sendLogout = () => send({ type: "logout" });
|
|
20
25
|
const onOpen = () => {
|
|
21
26
|
sendLogin();
|
package/lib/index.js
CHANGED
|
@@ -60,7 +60,7 @@ const ffmpegOutputOptions = [
|
|
|
60
60
|
"-movflags",
|
|
61
61
|
"faststart+frag_keyframe+empty_moov",
|
|
62
62
|
"-min_frag_duration",
|
|
63
|
-
"
|
|
63
|
+
"10000000",
|
|
64
64
|
];
|
|
65
65
|
const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isManualStart, }) {
|
|
66
66
|
// 如果已经在录制中,只在需要检查标题关键词时才获取最新信息
|
|
@@ -106,7 +106,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
106
106
|
}
|
|
107
107
|
// 获取直播间信息
|
|
108
108
|
const liveInfo = await getInfo(this.channelId);
|
|
109
|
-
const { living, owner, title
|
|
109
|
+
const { living, owner, title } = liveInfo;
|
|
110
110
|
this.liveInfo = liveInfo;
|
|
111
111
|
if (liveInfo.liveId === banLiveId) {
|
|
112
112
|
this.tempStopIntervalCheck = true;
|
|
@@ -137,7 +137,6 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
137
137
|
return null;
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
|
-
this.emit("LiveStart", { liveId });
|
|
141
140
|
let res;
|
|
142
141
|
// TODO: 先不做什么错误处理,就简单包一下预期上会有错误的地方
|
|
143
142
|
try {
|
|
@@ -170,6 +169,10 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
170
169
|
this.usedStream = stream.name;
|
|
171
170
|
this.usedSource = stream.source;
|
|
172
171
|
const onEnd = (...args) => {
|
|
172
|
+
if (isCutting) {
|
|
173
|
+
isCutting = false;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
173
176
|
if (isEnded)
|
|
174
177
|
return;
|
|
175
178
|
isEnded = true;
|
|
@@ -181,14 +184,18 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
181
184
|
this.recordHandle?.stop(reason);
|
|
182
185
|
};
|
|
183
186
|
let isEnded = false;
|
|
187
|
+
let isCutting = false;
|
|
184
188
|
const recorder = new FFMPEGRecorder({
|
|
185
189
|
url: stream.url,
|
|
186
190
|
outputOptions: ffmpegOutputOptions,
|
|
187
191
|
segment: this.segment ?? 0,
|
|
188
|
-
getSavePath: (opts) => getSavePath({ owner, title, startTime: opts.startTime }),
|
|
192
|
+
getSavePath: (opts) => getSavePath({ owner, title: opts.title ?? title, startTime: opts.startTime }),
|
|
189
193
|
disableDanma: this.disableProvideCommentsWhenRecording,
|
|
190
194
|
videoFormat: this.videoFormat ?? "auto",
|
|
191
|
-
}, onEnd)
|
|
195
|
+
}, onEnd, async () => {
|
|
196
|
+
const info = await getInfo(this.channelId);
|
|
197
|
+
return info;
|
|
198
|
+
});
|
|
192
199
|
const savePath = getSavePath({
|
|
193
200
|
owner,
|
|
194
201
|
title,
|
|
@@ -200,8 +207,14 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
200
207
|
this.state = "idle";
|
|
201
208
|
throw err;
|
|
202
209
|
}
|
|
203
|
-
const handleVideoCreated = async ({ filename }) => {
|
|
204
|
-
this.emit("videoFileCreated", { filename });
|
|
210
|
+
const handleVideoCreated = async ({ filename, title, cover }) => {
|
|
211
|
+
this.emit("videoFileCreated", { filename, cover });
|
|
212
|
+
if (title && this?.liveInfo) {
|
|
213
|
+
this.liveInfo.title = title;
|
|
214
|
+
}
|
|
215
|
+
if (cover && this?.liveInfo) {
|
|
216
|
+
this.liveInfo.cover = cover;
|
|
217
|
+
}
|
|
205
218
|
const extraDataController = recorder.getExtraDataController();
|
|
206
219
|
extraDataController?.setMeta({
|
|
207
220
|
room_id: this.channelId,
|
|
@@ -236,7 +249,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
236
249
|
case "chatmsg": {
|
|
237
250
|
const comment = {
|
|
238
251
|
type: "comment",
|
|
239
|
-
timestamp:
|
|
252
|
+
timestamp: Number(msg.cst),
|
|
240
253
|
text: msg.txt,
|
|
241
254
|
color: colorTab[msg.col] ?? "#ffffff",
|
|
242
255
|
sender: {
|
|
@@ -370,6 +383,16 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
370
383
|
const ffmpegArgs = recorder.getArguments();
|
|
371
384
|
recorder.run();
|
|
372
385
|
// TODO: 需要一个机制防止空录制,比如检查文件的大小变化、ffmpeg 的输出、直播状态等
|
|
386
|
+
const cut = utils.singleton(async () => {
|
|
387
|
+
if (!this.recordHandle)
|
|
388
|
+
return;
|
|
389
|
+
if (isCutting)
|
|
390
|
+
return;
|
|
391
|
+
isCutting = true;
|
|
392
|
+
await recorder.stop();
|
|
393
|
+
recorder.createCommand();
|
|
394
|
+
recorder.run();
|
|
395
|
+
});
|
|
373
396
|
const stop = utils.singleton(async (reason) => {
|
|
374
397
|
if (!this.recordHandle)
|
|
375
398
|
return;
|
|
@@ -400,6 +423,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, banLiveId, isMan
|
|
|
400
423
|
ffmpegArgs,
|
|
401
424
|
savePath: savePath,
|
|
402
425
|
stop,
|
|
426
|
+
cut,
|
|
403
427
|
};
|
|
404
428
|
this.emit("RecordStart", this.recordHandle);
|
|
405
429
|
return this.recordHandle;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bililive-tools/douyu-recorder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "bililive-tools douyu recorder implemention",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"lodash-es": "^4.17.21",
|
|
42
42
|
"axios": "^1.7.8",
|
|
43
43
|
"douyu-api": "^0.1.0",
|
|
44
|
-
"@bililive-tools/manager": "^1.
|
|
44
|
+
"@bililive-tools/manager": "^1.3.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/ws": "^8.5.13"
|