crabatool 1.0.856 → 1.0.857
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/index.js +1 -0
- package/package.json +1 -1
- package/tool/evsockettool.js +132 -74
- package/tool/sockettool.js +1 -4
package/index.js
CHANGED
package/package.json
CHANGED
package/tool/evsockettool.js
CHANGED
|
@@ -19,6 +19,9 @@ var evConfig = {
|
|
|
19
19
|
// 监控的文件
|
|
20
20
|
var monitoringFiles = {};
|
|
21
21
|
|
|
22
|
+
// 已完成的文件(防止重复处理)
|
|
23
|
+
var completedFiles = {};
|
|
24
|
+
|
|
22
25
|
// 确保输出目录存在
|
|
23
26
|
if (!fs.existsSync(evConfig.outputDir)) {
|
|
24
27
|
fs.mkdirSync(evConfig.outputDir, { recursive: true });
|
|
@@ -62,6 +65,9 @@ function init() {
|
|
|
62
65
|
// 直接启动runEv服务时,什么都不用做
|
|
63
66
|
// 等待前端连接和start消息,如果等到的是连接消息,记录连接时间。
|
|
64
67
|
log('evsockettool 初始化完成,等待前端连接');
|
|
68
|
+
if (config.local) {
|
|
69
|
+
startEvRecording();
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
// 启动ev录屏
|
|
@@ -132,10 +138,21 @@ function stopEvRecording(conn) {
|
|
|
132
138
|
// 清理监控文件
|
|
133
139
|
for (var filePath in monitoringFiles) {
|
|
134
140
|
if (monitoringFiles.hasOwnProperty(filePath)) {
|
|
135
|
-
|
|
141
|
+
if (monitoringFiles[filePath].timer) {
|
|
142
|
+
clearInterval(monitoringFiles[filePath].timer);
|
|
143
|
+
}
|
|
136
144
|
delete monitoringFiles[filePath];
|
|
137
145
|
}
|
|
138
146
|
}
|
|
147
|
+
log('清理监控文件');
|
|
148
|
+
|
|
149
|
+
// 清理已完成文件标记
|
|
150
|
+
for (var completedFile in completedFiles) {
|
|
151
|
+
if (completedFiles.hasOwnProperty(completedFile)) {
|
|
152
|
+
delete completedFiles[completedFile];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
log('清理已完成文件标记');
|
|
139
156
|
|
|
140
157
|
// 清理watcher
|
|
141
158
|
if (evConfig.watcher) {
|
|
@@ -169,15 +186,21 @@ function watchEvOutput(conn) {
|
|
|
169
186
|
evConfig.watcher.on('add', function(filePath) {
|
|
170
187
|
var ext = path.extname(filePath).toLowerCase();
|
|
171
188
|
if (ext === '.mp3' || ext === '.wav' || ext === '.mp4') {
|
|
172
|
-
|
|
189
|
+
// 检查文件是否已完成
|
|
190
|
+
if (completedFiles[filePath]) {
|
|
191
|
+
log('文件已处理完成,跳过:', filePath);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
console.log('\r\n\r\n');
|
|
195
|
+
log('---------发现新的媒体文件---------', filePath);
|
|
173
196
|
|
|
174
197
|
// 检查文件创建时间是否大于启动时间
|
|
175
198
|
try {
|
|
176
199
|
var stats = fs.statSync(filePath);
|
|
177
200
|
var fileCreateTime = stats.ctime.getTime();
|
|
178
201
|
if (fileCreateTime > evConfig.startTime) {
|
|
179
|
-
log('录屏开始,文件已生成:', filePath);
|
|
180
202
|
sendEvMessage(conn, 'msg', '录屏已开始,正在录制中');
|
|
203
|
+
startFileMonitoring(conn, filePath);
|
|
181
204
|
}
|
|
182
205
|
} catch (ex) {
|
|
183
206
|
log('检查文件信息失败:', ex.message);
|
|
@@ -188,25 +211,29 @@ function watchEvOutput(conn) {
|
|
|
188
211
|
evConfig.watcher.on('change', function(filePath) {
|
|
189
212
|
var ext = path.extname(filePath).toLowerCase();
|
|
190
213
|
if (ext === '.mp3' || ext === '.wav' || ext === '.mp4') {
|
|
191
|
-
log('文件变化:', filePath);
|
|
214
|
+
//log('文件变化:', filePath);
|
|
215
|
+
|
|
216
|
+
// 检查文件是否已完成
|
|
217
|
+
if (completedFiles[filePath]) {
|
|
218
|
+
log('文件已处理完成,跳过:', filePath);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
192
221
|
|
|
193
222
|
// 检查文件创建时间和大小
|
|
194
223
|
try {
|
|
195
224
|
var stats = fs.statSync(filePath);
|
|
196
225
|
var fileCreateTime = stats.ctime.getTime();
|
|
197
|
-
|
|
198
226
|
// 文件创建时间必须大于启动时间
|
|
199
227
|
if (fileCreateTime > evConfig.startTime) {
|
|
200
|
-
log('
|
|
201
|
-
|
|
202
|
-
//
|
|
203
|
-
if (
|
|
204
|
-
log('
|
|
205
|
-
|
|
206
|
-
monitoringFiles[filePath] = true;
|
|
207
|
-
startMonitoringFile(conn, filePath);
|
|
228
|
+
log('文件发生改变:', filePath, '当前大小:', stats.size, 'bytes');
|
|
229
|
+
|
|
230
|
+
// 如果文件已经在监控中,重置成功计数
|
|
231
|
+
if (monitoringFiles[filePath]) {
|
|
232
|
+
log('文件在监控中发生变化,重置成功计数:', filePath);
|
|
233
|
+
monitoringFiles[filePath].successCount = 0;
|
|
208
234
|
} else {
|
|
209
|
-
|
|
235
|
+
// 开始监控文件
|
|
236
|
+
startFileMonitoring(conn, filePath);
|
|
210
237
|
}
|
|
211
238
|
} else {
|
|
212
239
|
log('文件创建时间不符合要求,跳过:', filePath);
|
|
@@ -222,74 +249,60 @@ function watchEvOutput(conn) {
|
|
|
222
249
|
});
|
|
223
250
|
}
|
|
224
251
|
|
|
225
|
-
//
|
|
226
|
-
function
|
|
227
|
-
//
|
|
228
|
-
if (monitoringFiles[filePath]
|
|
229
|
-
log('文件已在监控中,跳过:', filePath);
|
|
252
|
+
// 开始监控文件,每隔1秒尝试重命名检测,连续3次成功才算完成
|
|
253
|
+
function startFileMonitoring(conn, filePath) {
|
|
254
|
+
// 如果已经在监控中,跳过
|
|
255
|
+
if (monitoringFiles[filePath]) {
|
|
256
|
+
//log('文件已在监控中,跳过:', filePath);
|
|
230
257
|
return;
|
|
231
258
|
}
|
|
259
|
+
var stats = fs.statSync(filePath);
|
|
260
|
+
log('开始监控文件是否录制完成:', filePath, '当前大小:', stats.size, 'bytes');
|
|
261
|
+
|
|
262
|
+
// 标记为监控中,存储状态
|
|
263
|
+
monitoringFiles[filePath] = {
|
|
264
|
+
timer: null,
|
|
265
|
+
successCount: 0,
|
|
266
|
+
requiredSuccessCount: 3 // 需要连续3次成功
|
|
267
|
+
};
|
|
232
268
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
monitoringFiles[filePath] = setInterval(function() {
|
|
257
|
-
try {
|
|
258
|
-
var stats = fs.statSync(filePath);
|
|
259
|
-
var currentSize = stats.size;
|
|
260
|
-
|
|
261
|
-
if (currentSize > lastSize) {
|
|
262
|
-
hasGrowth = true;
|
|
263
|
-
stableCount = 0; // 重置计数
|
|
264
|
-
log('文件大小增长:', filePath, '当前大小:', currentSize, 'bytes');
|
|
265
|
-
} else if (currentSize === lastSize) {
|
|
266
|
-
stableCount++;
|
|
267
|
-
log('文件大小稳定:', filePath, '连续稳定次数:', stableCount, '稳定时间:', (stableCount * checkInterval / 1000).toFixed(1), '秒');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
lastSize = currentSize;
|
|
271
|
-
|
|
272
|
-
// 当文件大小连续稳定5次(15秒)且至少有过一次增长,并且文件大小大于最小阈值时,认为录制真正结束
|
|
273
|
-
if (stableCount >= stableThreshold && hasGrowth && currentSize >= minFileSize) {
|
|
274
|
-
clearInterval(monitoringFiles[filePath]);
|
|
275
|
-
delete monitoringFiles[filePath];
|
|
276
|
-
log('文件录制真正完成:', filePath, '最终大小:', currentSize, 'bytes');
|
|
277
|
-
processEvFile(conn, filePath);
|
|
269
|
+
const state = monitoringFiles[filePath];
|
|
270
|
+
|
|
271
|
+
state.timer = setInterval(function() {
|
|
272
|
+
// 尝试重命名检测文件是否被占用
|
|
273
|
+
checkFileLock(filePath, function(isLocked) {
|
|
274
|
+
if (!isLocked) {
|
|
275
|
+
// 重命名成功,增加成功计数
|
|
276
|
+
state.successCount++;
|
|
277
|
+
log('文件重命名成功,连续成功次数:', state.successCount + '/' + state.requiredSuccessCount, filePath);
|
|
278
|
+
|
|
279
|
+
// 连续3次成功,说明文件未被占用,录制完成
|
|
280
|
+
if (state.successCount >= state.requiredSuccessCount) {
|
|
281
|
+
clearInterval(state.timer);
|
|
282
|
+
delete monitoringFiles[filePath];
|
|
283
|
+
// 标记文件为已完成
|
|
284
|
+
completedFiles[filePath] = true;
|
|
285
|
+
log('【文件录制完成】:', filePath);
|
|
286
|
+
processEvFile(conn, filePath);
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
// 重命名失败,重置成功计数,文件仍被占用,继续监控
|
|
290
|
+
state.successCount = 0;
|
|
291
|
+
//log('文件仍被占用,重置成功计数:', filePath);
|
|
278
292
|
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
clearInterval(monitoringFiles[filePath]);
|
|
282
|
-
delete monitoringFiles[filePath];
|
|
283
|
-
}
|
|
284
|
-
}, checkInterval);
|
|
293
|
+
});
|
|
294
|
+
}, 1000); // 每隔1秒检查一次
|
|
285
295
|
}
|
|
286
296
|
|
|
287
297
|
// 处理ev生成的文件
|
|
288
298
|
function processEvFile(conn, filePath) {
|
|
299
|
+
var stats = fs.statSync(filePath);
|
|
300
|
+
log('【开始上传文件到七牛】:', filePath, '当前大小:', stats.size, 'bytes');
|
|
301
|
+
|
|
289
302
|
// 检查是否有七牛token
|
|
290
303
|
if (!evConfig.qiniuToken) {
|
|
291
|
-
log('
|
|
292
|
-
sendEvMessage(conn, 'error', '
|
|
304
|
+
log('但没有七牛token,无法上传文件');
|
|
305
|
+
sendEvMessage(conn, 'error', '【录制完成】,但没有七牛token,无法上传文件');
|
|
293
306
|
return;
|
|
294
307
|
}
|
|
295
308
|
|
|
@@ -307,8 +320,6 @@ function processEvFile(conn, filePath) {
|
|
|
307
320
|
var formUploader = new qiniu.form_up.FormUploader();
|
|
308
321
|
var putExtra = new qiniu.form_up.PutExtra();
|
|
309
322
|
|
|
310
|
-
log('开始上传文件到七牛服务器:', filePath);
|
|
311
|
-
|
|
312
323
|
// 上传文件
|
|
313
324
|
formUploader.putFile(evConfig.qiniuToken, qiniuFileName, filePath, putExtra, function(respErr, respBody, respInfo) {
|
|
314
325
|
if (respErr) {
|
|
@@ -343,6 +354,9 @@ function processEvFile(conn, filePath) {
|
|
|
343
354
|
|
|
344
355
|
// 发送ev消息给前端
|
|
345
356
|
function sendEvMessage(conn, status, message, data) {
|
|
357
|
+
if (!conn) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
346
360
|
var response = {
|
|
347
361
|
mode: 'evRecord',
|
|
348
362
|
status: status,
|
|
@@ -359,6 +373,50 @@ function sendEvMessage(conn, status, message, data) {
|
|
|
359
373
|
}
|
|
360
374
|
}
|
|
361
375
|
|
|
376
|
+
// 检查文件是否被占用(通过重命名检测)
|
|
377
|
+
function checkFileLock(filePath, callback) {
|
|
378
|
+
// 生成临时文件名(在原文件名后添加递增数字)
|
|
379
|
+
const dir = path.dirname(filePath);
|
|
380
|
+
const ext = path.extname(filePath);
|
|
381
|
+
const baseName = path.basename(filePath, ext);
|
|
382
|
+
|
|
383
|
+
// 生成带递增数字的临时文件名
|
|
384
|
+
let tempName = baseName + '_temp' + ext;
|
|
385
|
+
let tempPath = path.join(dir, tempName);
|
|
386
|
+
let counter = 1;
|
|
387
|
+
|
|
388
|
+
// 确保临时文件名不冲突
|
|
389
|
+
while (fs.existsSync(tempPath)) {
|
|
390
|
+
tempName = baseName + '_temp' + counter + ext;
|
|
391
|
+
tempPath = path.join(dir, tempName);
|
|
392
|
+
counter++;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
//log('尝试重命名文件:', filePath, '→', tempPath);
|
|
396
|
+
|
|
397
|
+
// 尝试重命名文件
|
|
398
|
+
fs.rename(filePath, tempPath, function(err) {
|
|
399
|
+
if (err) {
|
|
400
|
+
// 重命名失败,说明文件被占用
|
|
401
|
+
//log('文件被占用,重命名失败:', err.message);
|
|
402
|
+
callback(true);
|
|
403
|
+
} else {
|
|
404
|
+
// 重命名成功,说明文件未被占用
|
|
405
|
+
//log('文件未被占用,重命名成功');
|
|
406
|
+
|
|
407
|
+
// 恢复原文件名
|
|
408
|
+
fs.rename(tempPath, filePath, function(restoreErr) {
|
|
409
|
+
if (restoreErr) {
|
|
410
|
+
log('恢复文件名失败:', restoreErr.message);
|
|
411
|
+
} else {
|
|
412
|
+
log('文件未被占用,重命名成功:', filePath);
|
|
413
|
+
}
|
|
414
|
+
callback(false);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
362
420
|
// 自动检测ev录屏工具路径
|
|
363
421
|
function autoDetectEvPath() {
|
|
364
422
|
var possiblePaths = [
|
package/tool/sockettool.js
CHANGED
|
@@ -53,7 +53,6 @@ function createSocket() {
|
|
|
53
53
|
}
|
|
54
54
|
} catch (ex) { }
|
|
55
55
|
});
|
|
56
|
-
|
|
57
56
|
conn.on('connect', function(code, reason) {
|
|
58
57
|
utils.log('connect连接成功');
|
|
59
58
|
broadcast('ws connect success');
|
|
@@ -61,9 +60,7 @@ function createSocket() {
|
|
|
61
60
|
conn.on("close", function(code, reason) {
|
|
62
61
|
utils.debug("connect关闭");
|
|
63
62
|
});
|
|
64
|
-
conn.on("error", function(code, reason) {
|
|
65
|
-
|
|
66
|
-
});
|
|
63
|
+
conn.on("error", function(code, reason) {});
|
|
67
64
|
}).listen(config.socketPort);
|
|
68
65
|
|
|
69
66
|
socketServer.on('connection', function(code, reason) {
|