crabatool 1.0.849 → 1.0.853

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crabatool",
3
- "version": "1.0.849",
3
+ "version": "1.0.853",
4
4
  "description": "crabatool",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "sale-doc": "node ./test/test.js -convertJavadoc -targetPath F:/docs/sale -outPath F:/docs/sale.json",
14
14
  "start": "node run.js",
15
15
  "test": "node ./test/test.js",
16
- "checkSale":"node ./test/test.js -checkjs -modName sale -webPath F:/sale/web/src/main/resources/static/sale -ignoreCheck /js/biz.js,/js/jquery.min.js,/_Sys/UI/SkinConfig.js,/_Sys/UI/SkinConfig.gspx,/Main.js,/js/content.min.js,/analysiscloud/ProductComboStatistics.js,/eshoporder/js/init.js,jarvis/js/biz/common.js,/jarvis/js/biz.js,/analysiscloud/LazyGrid.js,/analysiscloud/ProductComboStatistics.js,/analysiscloud/component/BaseQuery.js,/analysiscloud/js/init.js,/analysiscloud/component/ExtendCheckedQuery.js,/analysiscloud/Demob.js,/eshoporder/advance/,/analysiscloud/component/,/js/qrcode.min.js -globals recordsheet,AMap,shopsale -progress 0",
16
+ "checkSale": "node ./test/test.js -checkjs -modName sale -webPath F:/sale/web/src/main/resources/static/sale -ignoreCheck /js/biz.js,/js/jquery.min.js,/_Sys/UI/SkinConfig.js,/_Sys/UI/SkinConfig.gspx,/Main.js,/js/content.min.js,/analysiscloud/ProductComboStatistics.js,/eshoporder/js/init.js,jarvis/js/biz/common.js,/jarvis/js/biz.js,/analysiscloud/LazyGrid.js,/analysiscloud/ProductComboStatistics.js,/analysiscloud/component/BaseQuery.js,/analysiscloud/js/init.js,/analysiscloud/component/ExtendCheckedQuery.js,/analysiscloud/Demob.js,/eshoporder/advance/,/analysiscloud/component/,/js/qrcode.min.js -globals recordsheet,AMap,shopsale -progress 0",
17
17
  "test_git": "node ./test/git.js -webPath F:/basicweb/www",
18
18
  "run": "node ./test/test.js -run -webPath F:/basicweb/www -refresh true -proxy \"{'/shell/framework/':{'target':'http://127.0.0.1:8339','changeOrigin':true,'logLevel':'debug'}}\"",
19
19
  "mergeinitjs": "node ./test/test.js -mergeinitjs",
@@ -84,7 +84,8 @@
84
84
  "uglify-js": "^3.15.1",
85
85
  "uglifycss": "^0.0.29",
86
86
  "xml-js": "^1.6.11",
87
- "xml-minifier": "^1.0.1"
87
+ "xml-minifier": "^1.0.1",
88
+ "qiniu": "^3.1.1"
88
89
  },
89
90
  "repository": {
90
91
  "type": "git",
@@ -12,7 +12,8 @@ var evConfig = {
12
12
  watcher: null,
13
13
  conn: null,
14
14
  startTime: null,
15
- connectTime: null
15
+ connectTime: null,
16
+ qiniuToken: null
16
17
  };
17
18
 
18
19
  // 监控的文件
@@ -42,6 +43,16 @@ function handleEvRecord(conn, message) {
42
43
  startEvRecording(conn);
43
44
  } else if (message.action === 'stop') {
44
45
  stopEvRecording(conn);
46
+ } else if (message.action === 'setQiNiuToken') {
47
+ // 正确处理前端发送的token
48
+ var token = message.token;
49
+ log('收到七牛token:', token ? '已设置' : '空值');
50
+ evConfig.qiniuToken = token;
51
+ if (token) {
52
+ sendEvMessage(conn, 'msg', '七牛token已设置,请开始录制音视频;录制完成会自动上传七牛,并自动关联当前教学步骤。');
53
+ } else {
54
+ sendEvMessage(conn, 'error', '获取七牛token失败,无法上传音/视频到七牛,请联系服务中心。');
55
+ }
45
56
  }
46
57
  }
47
58
 
@@ -74,10 +85,10 @@ function startEvRecording(conn) {
74
85
  }
75
86
 
76
87
  log('找到ev录屏工具:', evPath);
77
-
88
+
78
89
  // 无论启动成功还是失败,都先开始监听存储目录的变动
79
90
  watchEvOutput(conn);
80
-
91
+
81
92
  // 启动ev录屏工具
82
93
  try {
83
94
  // 使用spawn替代exec,避免编码问题
@@ -85,15 +96,15 @@ function startEvRecording(conn) {
85
96
  windowsHide: true,
86
97
  detached: true
87
98
  });
88
-
99
+
89
100
  var startupError = false;
90
-
101
+
91
102
  child.on('error', function(error) {
92
103
  startupError = true;
93
104
  log('启动ev录屏工具失败:', error.message);
94
105
  sendEvMessage(conn, 'started', '请手动启动,启动ev录屏工具失败: ' + error.message);
95
106
  });
96
-
107
+
97
108
  // 对于GUI应用程序,进程会在后台运行,不会立即退出
98
109
  // 所以我们直接认为启动成功
99
110
  setTimeout(function() {
@@ -102,7 +113,7 @@ function startEvRecording(conn) {
102
113
  sendEvMessage(conn, 'started', 'ev录屏工具已启动,请开始录制');
103
114
  }
104
115
  }, 1000);
105
-
116
+
106
117
  // 分离子进程,让它在后台运行
107
118
  child.unref();
108
119
  } catch (ex) {
@@ -158,7 +169,7 @@ function watchEvOutput(conn) {
158
169
  var ext = path.extname(filePath).toLowerCase();
159
170
  if (ext === '.mp3' || ext === '.wav' || ext === '.mp4') {
160
171
  log('发现新的媒体文件:', filePath);
161
-
172
+
162
173
  // 检查文件创建时间是否大于启动时间
163
174
  try {
164
175
  var stats = fs.statSync(filePath);
@@ -190,7 +201,11 @@ function watchEvOutput(conn) {
190
201
  // 如果文件还没有被监控,开始监控
191
202
  if (!monitoringFiles[filePath]) {
192
203
  log('开始监控文件:', filePath, '当前大小:', stats.size, 'bytes');
204
+ // 先标记为监控中,防止短时间内重复触发
205
+ monitoringFiles[filePath] = true;
193
206
  startMonitoringFile(conn, filePath);
207
+ } else {
208
+ log('文件已在监控中,跳过:', filePath);
194
209
  }
195
210
  } else {
196
211
  log('文件创建时间不符合要求,跳过:', filePath);
@@ -208,27 +223,34 @@ function watchEvOutput(conn) {
208
223
 
209
224
  // 监控文件大小变化,判断录制是否真正结束
210
225
  function startMonitoringFile(conn, filePath) {
211
- if (monitoringFiles[filePath]) {
226
+ // 如果已经是一个有效的interval,说明已经在监控中
227
+ if (monitoringFiles[filePath] && monitoringFiles[filePath] !== true) {
228
+ log('文件已在监控中,跳过:', filePath);
212
229
  return;
213
230
  }
214
231
 
215
232
  var lastSize = 0;
216
233
  var stableCount = 0;
217
234
  var hasGrowth = false;
218
-
235
+
219
236
  // 根据文件类型设置不同的阈值
220
237
  var ext = path.extname(filePath).toLowerCase();
221
238
  var isVideo = ext === '.mp4';
222
239
  var isAudio = ext === '.mp3' || ext === '.wav';
223
-
240
+
224
241
  // MP4视频:帧率20fps,文件增长快,检查间隔1秒,稳定3次(3秒)即可判定完成
225
242
  // MP3音频:码率128kbps,文件增长慢,检查间隔3秒,稳定2次(6秒)即可判定完成
226
243
  var checkInterval = isVideo ? 1000 : (isAudio ? 3000 : 2000); // MP4: 1秒, MP3: 3秒, 其他: 2秒
227
244
  var stableThreshold = isVideo ? 3 : (isAudio ? 2 : 3); // MP4: 3次(3秒), MP3: 2次(6秒), 其他: 3次
228
245
  var minFileSize = isVideo ? 5000 : (isAudio ? 3000 : 1000); // MP4: 5KB, MP3: 3KB, 其他: 1KB
229
-
230
- log('开始监控文件:', path.basename(filePath), '类型:', isVideo ? '视频' : (isAudio ? '音频' : '其他'),
231
- '检查间隔:', checkInterval + 'ms', '稳定阈值:', stableThreshold + '次');
246
+
247
+ log('开始监控文件:', path.basename(filePath), '类型:', isVideo ? '视频' : (isAudio ? '音频' : '其他'),
248
+ '检查间隔:', checkInterval + 'ms', '稳定阈值:', stableThreshold + '次');
249
+
250
+ // 清除之前的标记,设置为真正的interval
251
+ if (monitoringFiles[filePath] === true) {
252
+ delete monitoringFiles[filePath];
253
+ }
232
254
 
233
255
  monitoringFiles[filePath] = setInterval(function() {
234
256
  try {
@@ -263,46 +285,56 @@ function startMonitoringFile(conn, filePath) {
263
285
 
264
286
  // 处理ev生成的文件
265
287
  function processEvFile(conn, filePath) {
266
- // 模拟上传到七牛服务器的逻辑
288
+ // 检查是否有七牛token
289
+ if (!evConfig.qiniuToken) {
290
+ log('没有七牛token,无法上传文件');
291
+ sendEvMessage(conn, 'error', '录制完成,但没有七牛token,无法上传文件');
292
+ return;
293
+ }
294
+
267
295
  var fileName = path.basename(filePath);
268
296
  var fileExt = path.extname(fileName);
269
297
  var timestamp = new Date().getTime();
270
298
  var qiniuFileName = 'ev-recording/' + timestamp + fileExt;
271
299
 
272
- // 模拟七牛服务器返回的URL
273
- var audioUrl = 'https://cdn.example.com/' + qiniuFileName;
274
-
275
- // 这里应该实现真正的七牛上传逻辑
276
- // 例如使用qiniu SDK上传文件
277
- // const qiniu = require('qiniu');
278
- // const formUploader = new qiniu.form_up.FormUploader();
279
- // const putExtra = new qiniu.form_up.PutExtra();
280
- // const bucket = 'your-bucket';
281
- // const key = qiniuFileName;
282
- // formUploader.putFile(uploadToken, key, filePath, putExtra, function(respErr, respBody, respInfo) {
283
- // if (respErr) {
284
- // sendEvMessage(conn, 'error', '上传失败: ' + respErr.message);
285
- // } else {
286
- // if (respInfo.statusCode == 200) {
287
- // var audioUrl = 'https://cdn.example.com/' + respBody.key;
288
- // sendEvMessage(conn, 'completed', '录制完成', { audioUrl: audioUrl });
289
- // } else {
290
- // sendEvMessage(conn, 'error', '上传失败: ' + respInfo.statusCode);
291
- // }
292
- // }
293
- // });
294
-
295
- // 模拟上传成功
296
- log('模拟上传文件到七牛服务器:', filePath, '->', audioUrl);
297
-
298
300
  // 确定文件类型
299
301
  var fileType = fileExt.toLowerCase() === '.mp4' ? 'video' : 'audio';
300
-
301
- // 发送文件URL给前端,包含文件类型
302
- sendEvMessage(conn, 'completed', '录制完成', {
303
- audioUrl: audioUrl,
304
- fileType: fileType
305
- });
302
+
303
+ try {
304
+ // 尝试加载七牛SDK
305
+ var qiniu = require('qiniu');
306
+ var formUploader = new qiniu.form_up.FormUploader();
307
+ var putExtra = new qiniu.form_up.PutExtra();
308
+
309
+ log('开始上传文件到七牛服务器:', filePath);
310
+
311
+ // 上传文件
312
+ formUploader.putFile(evConfig.qiniuToken, qiniuFileName, filePath, putExtra, function(respErr, respBody, respInfo) {
313
+ if (respErr) {
314
+ log('上传失败:', respErr.message);
315
+ sendEvMessage(conn, 'error', '上传失败: ' + respErr.message);
316
+ } else {
317
+ if (respInfo.statusCode == 200) {
318
+ // 构建文件URL - 使用配置的CDN域名或从上传结果获取
319
+ var cdnDomain = config.qiniuCdnDomain || 'https://cdn.example.com';
320
+ var audioUrl = cdnDomain + '/' + respBody.key;
321
+ log('上传成功:', filePath, '->', audioUrl);
322
+
323
+ // 发送文件URL给前端,包含文件类型
324
+ sendEvMessage(conn, 'completed', '录制完成', {
325
+ audioUrl: audioUrl,
326
+ fileType: fileType
327
+ });
328
+ } else {
329
+ log('上传失败,状态码:', respInfo.statusCode);
330
+ sendEvMessage(conn, 'error', '上传失败: ' + respInfo.statusCode);
331
+ }
332
+ }
333
+ });
334
+ } catch (ex) {
335
+ log('七牛上传失败:', ex.message);
336
+ sendEvMessage(conn, 'error', '七牛上传失败');
337
+ }
306
338
 
307
339
  // 保持监控状态,等待下一次录制
308
340
  }