@bililive-tools/bilibili-recorder 1.10.0 → 1.12.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/index.js +7 -26
- package/lib/stream.js +5 -5
- package/lib/utils.d.ts +0 -1
- package/lib/utils.js +0 -8
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import mitt from "mitt";
|
|
3
3
|
import { defaultFromJSON, defaultToJSON, genRecorderUUID, genRecordUUID, utils, createDownloader, } from "@bililive-tools/manager";
|
|
4
4
|
import { getInfo, getStream, getLiveStatus, getStrictStream } from "./stream.js";
|
|
5
|
-
import { ensureFolderExist
|
|
5
|
+
import { ensureFolderExist } from "./utils.js";
|
|
6
6
|
import DanmaClient from "./danma.js";
|
|
7
7
|
function createRecorder(opts) {
|
|
8
8
|
// 内部实现时,应该只有 proxy 包裹的那一层会使用这个 recorder 标识符,不应该有直接通过
|
|
@@ -104,18 +104,8 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
104
104
|
if (!this.liveInfo.living)
|
|
105
105
|
return null;
|
|
106
106
|
// 检查标题是否包含关键词,如果包含则不自动录制
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const hasTitleKeyword = hasKeyword(this.liveInfo.title, this.titleKeywords);
|
|
110
|
-
if (hasTitleKeyword) {
|
|
111
|
-
this.state = "title-blocked";
|
|
112
|
-
this.emit("DebugLog", {
|
|
113
|
-
type: "common",
|
|
114
|
-
text: `跳过录制:直播间标题 "${this.liveInfo.title}" 包含关键词 "${this.titleKeywords}"`,
|
|
115
|
-
});
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
107
|
+
if (utils.checkTitleKeywordsBeforeRecord(this.liveInfo.title, this, isManualStart))
|
|
108
|
+
return null;
|
|
119
109
|
const liveInfo = await getInfo(this.channelId);
|
|
120
110
|
const { owner, title, roomId, liveStartTime, recordStartTime } = liveInfo;
|
|
121
111
|
this.liveInfo = liveInfo;
|
|
@@ -147,7 +137,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
147
137
|
this.usedSource = stream.source;
|
|
148
138
|
let url = stream.url;
|
|
149
139
|
let intervalId = null;
|
|
150
|
-
if (this.useM3U8Proxy && streamOptions.
|
|
140
|
+
if (this.useM3U8Proxy && streamOptions.format_name === "ts") {
|
|
151
141
|
url = `${this.m3u8ProxyUrl}?id=${this.id}&format=hls`;
|
|
152
142
|
this.emit("DebugLog", {
|
|
153
143
|
type: "common",
|
|
@@ -170,13 +160,8 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
170
160
|
});
|
|
171
161
|
}, 50 * 60 * 1000);
|
|
172
162
|
}
|
|
173
|
-
let isCutting = false;
|
|
174
163
|
let isEnded = false;
|
|
175
164
|
const onEnd = (...args) => {
|
|
176
|
-
if (isCutting) {
|
|
177
|
-
isCutting = false;
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
165
|
if (isEnded)
|
|
181
166
|
return;
|
|
182
167
|
isEnded = true;
|
|
@@ -200,6 +185,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
200
185
|
recordStartTime,
|
|
201
186
|
}),
|
|
202
187
|
formatName: streamOptions.format_name,
|
|
188
|
+
disableDanma: this.disableProvideCommentsWhenRecording,
|
|
203
189
|
videoFormat: this.videoFormat,
|
|
204
190
|
debugLevel: this.debugLevel ?? "none",
|
|
205
191
|
headers: {
|
|
@@ -274,7 +260,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
274
260
|
danmaClient.on("onRoomInfoChange", (msg) => {
|
|
275
261
|
if (utils.shouldCheckTitleKeywords(isManualStart, this.titleKeywords)) {
|
|
276
262
|
const title = msg?.body?.title ?? "";
|
|
277
|
-
const hasTitleKeyword =
|
|
263
|
+
const hasTitleKeyword = utils.hasBlockedTitleKeywords(title, this.titleKeywords);
|
|
278
264
|
if (hasTitleKeyword) {
|
|
279
265
|
this.state = "title-blocked";
|
|
280
266
|
this.emit("DebugLog", {
|
|
@@ -293,12 +279,7 @@ const checkLiveStatusAndRecord = async function ({ getSavePath, isManualStart, b
|
|
|
293
279
|
const cut = utils.singleton(async () => {
|
|
294
280
|
if (!this.recordHandle)
|
|
295
281
|
return;
|
|
296
|
-
|
|
297
|
-
return;
|
|
298
|
-
isCutting = true;
|
|
299
|
-
await downloader.stop();
|
|
300
|
-
downloader.createCommand();
|
|
301
|
-
downloader.run();
|
|
282
|
+
downloader.cut();
|
|
302
283
|
});
|
|
303
284
|
const stop = utils.singleton(async (reason) => {
|
|
304
285
|
if (!this.recordHandle)
|
package/lib/stream.js
CHANGED
|
@@ -83,13 +83,13 @@ async function getLiveInfo(roomIdOrShortId, opts) {
|
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
protocol_name: "http_hls",
|
|
86
|
-
format_name: "
|
|
86
|
+
format_name: "fmp4",
|
|
87
87
|
codec_name: "avc",
|
|
88
88
|
sort: 8,
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
protocol_name: "http_hls",
|
|
92
|
-
format_name: "
|
|
92
|
+
format_name: "ts",
|
|
93
93
|
codec_name: "avc",
|
|
94
94
|
sort: 7,
|
|
95
95
|
},
|
|
@@ -101,13 +101,13 @@ async function getLiveInfo(roomIdOrShortId, opts) {
|
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
protocol_name: "http_hls",
|
|
104
|
-
format_name: "
|
|
104
|
+
format_name: "fmp4",
|
|
105
105
|
codec_name: "hevc",
|
|
106
106
|
sort: 5,
|
|
107
107
|
},
|
|
108
108
|
{
|
|
109
109
|
protocol_name: "http_hls",
|
|
110
|
-
format_name: "
|
|
110
|
+
format_name: "ts",
|
|
111
111
|
codec_name: "hevc",
|
|
112
112
|
sort: 4,
|
|
113
113
|
},
|
|
@@ -164,7 +164,7 @@ async function getLiveInfo(roomIdOrShortId, opts) {
|
|
|
164
164
|
?.format.find(({ format_name }) => format_name === condition.format_name)
|
|
165
165
|
?.codec.filter(({ codec_name }) => codec_name === condition.codec_name);
|
|
166
166
|
if (streamList && streamList.length > 1) {
|
|
167
|
-
//
|
|
167
|
+
// 由于直播姬直推hevc时,指定qn,服务端仍会返回其他画质的流,这里需要指定找一下流
|
|
168
168
|
streamInfo = streamList.find((item) => item.current_qn === opts.qn);
|
|
169
169
|
}
|
|
170
170
|
if (!streamInfo) {
|
package/lib/utils.d.ts
CHANGED
|
@@ -21,4 +21,3 @@ 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 | undefined): boolean;
|
package/lib/utils.js
CHANGED
|
@@ -81,11 +81,3 @@ export function createInvalidStreamChecker(count = 10) {
|
|
|
81
81
|
return false;
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
-
export function hasKeyword(title, titleKeywords) {
|
|
85
|
-
const keywords = (titleKeywords ?? "")
|
|
86
|
-
.split(",")
|
|
87
|
-
.map((k) => k.trim())
|
|
88
|
-
.filter((k) => k);
|
|
89
|
-
const hasTitleKeyword = keywords.some((keyword) => title.toLowerCase().includes(keyword.toLowerCase()));
|
|
90
|
-
return hasTitleKeyword;
|
|
91
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bililive-tools/bilibili-recorder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.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.12.0"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsc",
|