@bililive-tools/bilibili-recorder 1.7.0 → 1.8.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 +2 -1
- package/lib/index.js +16 -21
- package/lib/utils.d.ts +1 -1
- package/lib/utils.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -53,7 +53,8 @@ interface Options {
|
|
|
53
53
|
m3u8ProxyUrl?: string; // 代理链接,文档待补充
|
|
54
54
|
videoFormat?: "auto"; // 视频格式: "auto", "ts", "mkv" ,auto模式下, 分段使用 "ts",不分段使用 "mp4"
|
|
55
55
|
onlyAudio?: boolean; // 只录制音频,默认为否
|
|
56
|
-
recorderType?: "auto" | "ffmpeg" | "mesio"; // 底层录制器,使用mesio时videoFormat参数无效
|
|
56
|
+
recorderType?: "auto" | "ffmpeg" | "mesio" | "bililive"; // 底层录制器,使用mesio和bililive时videoFormat参数无效
|
|
57
|
+
debugLevel?: `verbose` | "basic"; // verbose参数时,录制器会输出更加详细的log
|
|
57
58
|
}
|
|
58
59
|
```
|
|
59
60
|
|
package/lib/index.js
CHANGED
|
@@ -72,14 +72,10 @@ const ffmpegOutputOptions = [
|
|
|
72
72
|
"10000000",
|
|
73
73
|
];
|
|
74
74
|
const ffmpegInputOptions = [
|
|
75
|
-
"-reconnect",
|
|
76
|
-
"1",
|
|
77
|
-
"-reconnect_streamed",
|
|
78
|
-
"1",
|
|
79
|
-
"-reconnect_delay_max",
|
|
80
|
-
"10",
|
|
81
75
|
"-rw_timeout",
|
|
82
|
-
"
|
|
76
|
+
"10000000",
|
|
77
|
+
"-timeout",
|
|
78
|
+
"10000000",
|
|
83
79
|
"-headers",
|
|
84
80
|
"Referer:https://live.bilibili.com/",
|
|
85
81
|
];
|
|
@@ -96,6 +92,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
96
92
|
cover: "",
|
|
97
93
|
liveId: liveId,
|
|
98
94
|
};
|
|
95
|
+
this.state = "idle";
|
|
99
96
|
}
|
|
100
97
|
catch (error) {
|
|
101
98
|
this.state = "check-error";
|
|
@@ -113,12 +110,10 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
113
110
|
return null;
|
|
114
111
|
// 检查标题是否包含关键词,如果包含则不自动录制
|
|
115
112
|
// 手动开始录制时不检查标题关键词
|
|
116
|
-
if (
|
|
117
|
-
this.titleKeywords &&
|
|
118
|
-
typeof this.titleKeywords === "string" &&
|
|
119
|
-
this.titleKeywords.trim()) {
|
|
113
|
+
if (utils.shouldCheckTitleKeywords(isManualStart, this.titleKeywords)) {
|
|
120
114
|
const hasTitleKeyword = hasKeyword(this.liveInfo.title, this.titleKeywords);
|
|
121
115
|
if (hasTitleKeyword) {
|
|
116
|
+
this.state = "title-blocked";
|
|
122
117
|
this.emit("DebugLog", {
|
|
123
118
|
type: "common",
|
|
124
119
|
text: `跳过录制:直播间标题 "${this.liveInfo.title}" 包含关键词 "${this.titleKeywords}"`,
|
|
@@ -130,7 +125,6 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
130
125
|
const { owner, title, roomId } = liveInfo;
|
|
131
126
|
this.liveInfo = liveInfo;
|
|
132
127
|
let res;
|
|
133
|
-
// TODO: 先不做什么错误处理,就简单包一下预期上会有错误的地方
|
|
134
128
|
try {
|
|
135
129
|
let strictQuality = false;
|
|
136
130
|
if (this.qualityRetry > 0) {
|
|
@@ -206,17 +200,19 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
206
200
|
const reason = args[0] instanceof Error ? args[0].message : String(args[0]);
|
|
207
201
|
this.recordHandle?.stop(reason);
|
|
208
202
|
};
|
|
209
|
-
|
|
210
|
-
const recorder = createBaseRecorder(recorderType, {
|
|
203
|
+
const recorder = createBaseRecorder(this.recorderType, {
|
|
211
204
|
url: url,
|
|
212
205
|
outputOptions: ffmpegOutputOptions,
|
|
213
206
|
inputOptions: ffmpegInputOptions,
|
|
214
|
-
mesioOptions: ["-H", "Referer:https://live.bilibili.com/"],
|
|
215
207
|
segment: this.segment ?? 0,
|
|
216
208
|
getSavePath: (opts) => getSavePath({ owner, title: opts.title ?? title, startTime: opts.startTime }),
|
|
217
209
|
formatName: streamOptions.format_name,
|
|
218
210
|
disableDanma: this.disableProvideCommentsWhenRecording,
|
|
219
211
|
videoFormat: this.videoFormat,
|
|
212
|
+
debugLevel: this.debugLevel ?? "none",
|
|
213
|
+
headers: {
|
|
214
|
+
Referer: "https://live.bilibili.com/",
|
|
215
|
+
},
|
|
220
216
|
}, onEnd, async () => {
|
|
221
217
|
const info = await getInfo(this.channelId);
|
|
222
218
|
return info;
|
|
@@ -232,8 +228,8 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
232
228
|
this.state = "idle";
|
|
233
229
|
throw err;
|
|
234
230
|
}
|
|
235
|
-
const handleVideoCreated = async ({ filename, title, cover }) => {
|
|
236
|
-
this.emit("videoFileCreated", { filename, cover });
|
|
231
|
+
const handleVideoCreated = async ({ filename, title, cover, rawFilename }) => {
|
|
232
|
+
this.emit("videoFileCreated", { filename, cover, rawFilename });
|
|
237
233
|
if (title && this?.liveInfo) {
|
|
238
234
|
this.liveInfo.title = title;
|
|
239
235
|
}
|
|
@@ -281,13 +277,11 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
281
277
|
extraDataController.addMessage(msg);
|
|
282
278
|
});
|
|
283
279
|
danmaClient.on("onRoomInfoChange", (msg) => {
|
|
284
|
-
if (
|
|
285
|
-
this.titleKeywords &&
|
|
286
|
-
typeof this.titleKeywords === "string" &&
|
|
287
|
-
this.titleKeywords.trim()) {
|
|
280
|
+
if (utils.shouldCheckTitleKeywords(isManualStart, this.titleKeywords)) {
|
|
288
281
|
const title = msg?.body?.title ?? "";
|
|
289
282
|
const hasTitleKeyword = hasKeyword(title, this.titleKeywords);
|
|
290
283
|
if (hasTitleKeyword) {
|
|
284
|
+
this.state = "title-blocked";
|
|
291
285
|
this.emit("DebugLog", {
|
|
292
286
|
type: "common",
|
|
293
287
|
text: `检测到标题包含关键词,停止录制:直播间标题 "${title}" 包含关键词 "${this.titleKeywords}"`,
|
|
@@ -338,6 +332,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
338
332
|
id: genRecordUUID(),
|
|
339
333
|
stream: stream.name,
|
|
340
334
|
source: stream.source,
|
|
335
|
+
recorderType: recorder.type,
|
|
341
336
|
url: stream.url,
|
|
342
337
|
ffmpegArgs,
|
|
343
338
|
savePath: savePath,
|
package/lib/utils.d.ts
CHANGED
|
@@ -21,4 +21,4 @@ export declare function assertStringType(data: unknown, msg?: string): asserts d
|
|
|
21
21
|
export declare function assertNumberType(data: unknown, msg?: string): asserts data is number;
|
|
22
22
|
export declare function assertObjectType(data: unknown, msg?: string): asserts data is object;
|
|
23
23
|
export declare function createInvalidStreamChecker(count?: number): (ffmpegLogLine: string) => boolean;
|
|
24
|
-
export declare function hasKeyword(title: string, titleKeywords: string): boolean;
|
|
24
|
+
export declare function hasKeyword(title: string, titleKeywords: string | undefined): boolean;
|
package/lib/utils.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bililive-tools/bilibili-recorder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "bililive-tools bilibili recorder implemention",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"tiny-bilibili-ws": "^1.0.2",
|
|
40
40
|
"lodash-es": "^4.17.21",
|
|
41
41
|
"axios": "^1.7.8",
|
|
42
|
-
"@bililive-tools/manager": "^1.
|
|
42
|
+
"@bililive-tools/manager": "^1.8.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsc",
|