@lightsoft/js-sdk 1.2.4 → 1.2.5

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/dist/index.d.ts CHANGED
@@ -344,8 +344,9 @@ declare class AudioRecorder {
344
344
  getAudioBlob(): Blob | null;
345
345
  getAudioUrl(): string;
346
346
  getAudioBase64(blob: Blob): Promise<string>;
347
- getAudioInfo(): Promise<unknown>;
348
- getWavBitDepth(blob: Blob): Promise<number>;
347
+ getAudioInfo(blob: Blob): Promise<unknown>;
348
+ getBitDepth(audioContext: AudioContext, blob: Blob): Promise<number>;
349
+ download(blob: Blob): null | undefined;
349
350
  getExtension(mimeType: string): string;
350
351
  upload(url: string, options?: RequestInit): Promise<any>;
351
352
  }
package/dist/index.js CHANGED
@@ -2999,7 +2999,7 @@ var AudioRecorder = /** @class */ (function () {
2999
2999
  sampleRate: 0,
3000
3000
  channels: 0,
3001
3001
  format: null,
3002
- bitDepth: 0,
3002
+ bitDepth: 16,
3003
3003
  };
3004
3004
  this.timer = null;
3005
3005
  this.timerCount = 0;
@@ -3052,13 +3052,16 @@ var AudioRecorder = /** @class */ (function () {
3052
3052
  };
3053
3053
  // 停止录音
3054
3054
  AudioRecorder.prototype.stop = function () {
3055
+ var _a;
3055
3056
  if (this.mediaRecorder) {
3056
- this.audioChunks = [];
3057
+ this.reset();
3058
+ (_a = this.timerEndCallback) === null || _a === void 0 ? void 0 : _a.call(this);
3057
3059
  this.mediaRecorder.stop();
3058
3060
  }
3059
3061
  };
3060
3062
  AudioRecorder.prototype.reset = function () {
3061
3063
  var _a, _b;
3064
+ this.clearTimer();
3062
3065
  this.audioChunks = [];
3063
3066
  (_b = (_a = this.stream) === null || _a === void 0 ? void 0 : _a.getTracks()) === null || _b === void 0 ? void 0 : _b.forEach(function (track) { return track.stop(); });
3064
3067
  };
@@ -3072,7 +3075,6 @@ var AudioRecorder = /** @class */ (function () {
3072
3075
  var _a, _b;
3073
3076
  next === null || next === void 0 ? void 0 : next();
3074
3077
  (_a = _this.timerCallback) === null || _a === void 0 ? void 0 : _a.call(_this, _this.timerCount);
3075
- console.log('this.timerCount2: ', _this.timerCount);
3076
3078
  if (_this.timerCount === _this.options.maxTime) {
3077
3079
  _this.clearTimer();
3078
3080
  end === null || end === void 0 ? void 0 : end();
@@ -3114,28 +3116,29 @@ var AudioRecorder = /** @class */ (function () {
3114
3116
  reader.readAsDataURL(blob);
3115
3117
  });
3116
3118
  };
3117
- AudioRecorder.prototype.getAudioInfo = function () {
3119
+ AudioRecorder.prototype.getAudioInfo = function (blob) {
3118
3120
  var _this = this;
3119
3121
  return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
3120
- var audioContext, source, analyser, sampleRate, channels, bitDepth, error_2;
3121
- var _a;
3122
- return __generator(this, function (_b) {
3123
- switch (_b.label) {
3122
+ var audioContext, source, analyser, sampleRate, channels, bitDepth, format, error_2;
3123
+ var _a, _b;
3124
+ return __generator(this, function (_c) {
3125
+ switch (_c.label) {
3124
3126
  case 0:
3125
- _b.trys.push([0, 2, , 3]);
3127
+ _c.trys.push([0, 2, , 3]);
3126
3128
  audioContext = new (window.AudioContext || window.webkitAudioContext)();
3127
3129
  source = audioContext.createMediaStreamSource(this.stream);
3128
3130
  analyser = audioContext.createAnalyser();
3129
3131
  source.connect(analyser);
3130
3132
  sampleRate = audioContext.sampleRate;
3131
3133
  channels = ((_a = this.stream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0].getSettings().channelCount) || 0;
3132
- return [4 /*yield*/, this.getWavBitDepth(this.getAudioBlob())];
3134
+ return [4 /*yield*/, this.getBitDepth(audioContext, blob)];
3133
3135
  case 1:
3134
- bitDepth = _b.sent();
3135
- resolve(__assign({ sampleRate: sampleRate, channels: channels, bitDepth: bitDepth }, this.audioInfo));
3136
+ bitDepth = _c.sent();
3137
+ format = this.getExtension((_b = this.mediaRecorder) === null || _b === void 0 ? void 0 : _b.mimeType);
3138
+ resolve(__assign(__assign({}, this.audioInfo), { sampleRate: sampleRate, channels: channels, bitDepth: bitDepth, format: format }));
3136
3139
  return [3 /*break*/, 3];
3137
3140
  case 2:
3138
- error_2 = _b.sent();
3141
+ error_2 = _c.sent();
3139
3142
  reject(error_2);
3140
3143
  return [3 /*break*/, 3];
3141
3144
  case 3: return [2 /*return*/];
@@ -3143,25 +3146,54 @@ var AudioRecorder = /** @class */ (function () {
3143
3146
  });
3144
3147
  }); });
3145
3148
  };
3146
- AudioRecorder.prototype.getWavBitDepth = function (blob) {
3149
+ AudioRecorder.prototype.getBitDepth = function (audioContext, blob) {
3150
+ var _this = this;
3147
3151
  return new Promise(function (resolve, reject) {
3148
3152
  var reader = new FileReader();
3149
- reader.onload = function (event) {
3153
+ reader.onload = function (event) { return __awaiter(_this, void 0, void 0, function () {
3154
+ var arrayBuffer, channelData, maxAmplitude, i, isFloat;
3150
3155
  var _a;
3151
- var arrayBuffer = (_a = event.target) === null || _a === void 0 ? void 0 : _a.result;
3152
- if (!arrayBuffer) {
3153
- reject();
3154
- throw new Error('未能读取 Blob 数据');
3155
- }
3156
- var data = new DataView(arrayBuffer);
3157
- // 检查 "fmt " 区域,WAV文件的音频格式信息通常在此
3158
- var fmtChunkOffset = 20; // "fmt " chunk 在 WAV 文件头的位置
3159
- var bitDepth = data.getUint16(fmtChunkOffset + 14, true); // 16位表示小端存储
3160
- resolve(bitDepth);
3161
- };
3156
+ return __generator(this, function (_b) {
3157
+ switch (_b.label) {
3158
+ case 0: return [4 /*yield*/, audioContext.decodeAudioData((_a = event.target) === null || _a === void 0 ? void 0 : _a.result)];
3159
+ case 1:
3160
+ arrayBuffer = _b.sent();
3161
+ if (!arrayBuffer) {
3162
+ reject({
3163
+ error: '未能读取 Blob 数据'
3164
+ });
3165
+ }
3166
+ channelData = arrayBuffer.getChannelData(0);
3167
+ maxAmplitude = 0;
3168
+ for (i = 0; i < channelData.length; i++) {
3169
+ maxAmplitude = Math.max(maxAmplitude, Math.abs(channelData[i]));
3170
+ }
3171
+ isFloat = channelData.some(function (value) {
3172
+ return Math.abs(value) > 1.0 ||
3173
+ value.toString().includes('.');
3174
+ });
3175
+ resolve(isFloat ? 32 : 16);
3176
+ return [2 /*return*/];
3177
+ }
3178
+ });
3179
+ }); };
3162
3180
  reader.readAsArrayBuffer(blob);
3163
3181
  });
3164
3182
  };
3183
+ AudioRecorder.prototype.download = function (blob) {
3184
+ var _a;
3185
+ if (!blob)
3186
+ return null;
3187
+ var format = this.getExtension((_a = this.mediaRecorder) === null || _a === void 0 ? void 0 : _a.mimeType);
3188
+ var fileName = "recording_".concat(Date.now() + Math.random().toString(36).substring(2), ".").concat(format);
3189
+ var url = URL.createObjectURL(blob);
3190
+ var a = document.createElement('a');
3191
+ a.style.display = 'none';
3192
+ a.href = url;
3193
+ a.download = fileName;
3194
+ a.click();
3195
+ URL.revokeObjectURL(url);
3196
+ };
3165
3197
  AudioRecorder.prototype.getExtension = function (mimeType) {
3166
3198
  var mimeToExt = {
3167
3199
  'audio/webm': 'webm',
@@ -3180,27 +3212,30 @@ var AudioRecorder = /** @class */ (function () {
3180
3212
  // 上传音频到服务器
3181
3213
  AudioRecorder.prototype.upload = function (url, options) {
3182
3214
  return __awaiter(this, void 0, void 0, function () {
3183
- var audioBlob, formData, response, data, error_3;
3184
- return __generator(this, function (_a) {
3185
- switch (_a.label) {
3215
+ var audioBlob, formData, format, fileName, response, data, error_3;
3216
+ var _a;
3217
+ return __generator(this, function (_b) {
3218
+ switch (_b.label) {
3186
3219
  case 0:
3187
3220
  audioBlob = this.getAudioBlob();
3188
3221
  if (!audioBlob)
3189
3222
  return [2 /*return*/, null];
3190
3223
  formData = new FormData();
3191
- formData.append('audio', audioBlob, 'recording.mp4');
3192
- _a.label = 1;
3224
+ format = this.getExtension((_a = this.mediaRecorder) === null || _a === void 0 ? void 0 : _a.mimeType);
3225
+ fileName = "recording_".concat(Date.now() + Math.random().toString(36).substring(2), ".").concat(format);
3226
+ formData.append('audio', audioBlob, fileName);
3227
+ _b.label = 1;
3193
3228
  case 1:
3194
- _a.trys.push([1, 4, , 5]);
3229
+ _b.trys.push([1, 4, , 5]);
3195
3230
  return [4 /*yield*/, fetch(url, options)];
3196
3231
  case 2:
3197
- response = _a.sent();
3232
+ response = _b.sent();
3198
3233
  return [4 /*yield*/, response.json()];
3199
3234
  case 3:
3200
- data = _a.sent();
3235
+ data = _b.sent();
3201
3236
  return [2 /*return*/, data];
3202
3237
  case 4:
3203
- error_3 = _a.sent();
3238
+ error_3 = _b.sent();
3204
3239
  throw new Error(error_3);
3205
3240
  case 5: return [2 /*return*/];
3206
3241
  }
package/dist/index.umd.js CHANGED
@@ -1206,7 +1206,7 @@
1206
1206
  sampleRate: 0,
1207
1207
  channels: 0,
1208
1208
  format: null,
1209
- bitDepth: 0,
1209
+ bitDepth: 16,
1210
1210
  };
1211
1211
  this.timer = null;
1212
1212
  this.timerCount = 0;
@@ -1259,13 +1259,16 @@
1259
1259
  };
1260
1260
  // 停止录音
1261
1261
  AudioRecorder.prototype.stop = function () {
1262
+ var _a;
1262
1263
  if (this.mediaRecorder) {
1263
- this.audioChunks = [];
1264
+ this.reset();
1265
+ (_a = this.timerEndCallback) === null || _a === void 0 ? void 0 : _a.call(this);
1264
1266
  this.mediaRecorder.stop();
1265
1267
  }
1266
1268
  };
1267
1269
  AudioRecorder.prototype.reset = function () {
1268
1270
  var _a, _b;
1271
+ this.clearTimer();
1269
1272
  this.audioChunks = [];
1270
1273
  (_b = (_a = this.stream) === null || _a === void 0 ? void 0 : _a.getTracks()) === null || _b === void 0 ? void 0 : _b.forEach(function (track) { return track.stop(); });
1271
1274
  };
@@ -1279,7 +1282,6 @@
1279
1282
  var _a, _b;
1280
1283
  next === null || next === void 0 ? void 0 : next();
1281
1284
  (_a = _this.timerCallback) === null || _a === void 0 ? void 0 : _a.call(_this, _this.timerCount);
1282
- console.log('this.timerCount2: ', _this.timerCount);
1283
1285
  if (_this.timerCount === _this.options.maxTime) {
1284
1286
  _this.clearTimer();
1285
1287
  end === null || end === void 0 ? void 0 : end();
@@ -1321,28 +1323,29 @@
1321
1323
  reader.readAsDataURL(blob);
1322
1324
  });
1323
1325
  };
1324
- AudioRecorder.prototype.getAudioInfo = function () {
1326
+ AudioRecorder.prototype.getAudioInfo = function (blob) {
1325
1327
  var _this = this;
1326
1328
  return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
1327
- var audioContext, source, analyser, sampleRate, channels, bitDepth, error_2;
1328
- var _a;
1329
- return __generator(this, function (_b) {
1330
- switch (_b.label) {
1329
+ var audioContext, source, analyser, sampleRate, channels, bitDepth, format, error_2;
1330
+ var _a, _b;
1331
+ return __generator(this, function (_c) {
1332
+ switch (_c.label) {
1331
1333
  case 0:
1332
- _b.trys.push([0, 2, , 3]);
1334
+ _c.trys.push([0, 2, , 3]);
1333
1335
  audioContext = new (window.AudioContext || window.webkitAudioContext)();
1334
1336
  source = audioContext.createMediaStreamSource(this.stream);
1335
1337
  analyser = audioContext.createAnalyser();
1336
1338
  source.connect(analyser);
1337
1339
  sampleRate = audioContext.sampleRate;
1338
1340
  channels = ((_a = this.stream) === null || _a === void 0 ? void 0 : _a.getAudioTracks()[0].getSettings().channelCount) || 0;
1339
- return [4 /*yield*/, this.getWavBitDepth(this.getAudioBlob())];
1341
+ return [4 /*yield*/, this.getBitDepth(audioContext, blob)];
1340
1342
  case 1:
1341
- bitDepth = _b.sent();
1342
- resolve(__assign({ sampleRate: sampleRate, channels: channels, bitDepth: bitDepth }, this.audioInfo));
1343
+ bitDepth = _c.sent();
1344
+ format = this.getExtension((_b = this.mediaRecorder) === null || _b === void 0 ? void 0 : _b.mimeType);
1345
+ resolve(__assign(__assign({}, this.audioInfo), { sampleRate: sampleRate, channels: channels, bitDepth: bitDepth, format: format }));
1343
1346
  return [3 /*break*/, 3];
1344
1347
  case 2:
1345
- error_2 = _b.sent();
1348
+ error_2 = _c.sent();
1346
1349
  reject(error_2);
1347
1350
  return [3 /*break*/, 3];
1348
1351
  case 3: return [2 /*return*/];
@@ -1350,25 +1353,54 @@
1350
1353
  });
1351
1354
  }); });
1352
1355
  };
1353
- AudioRecorder.prototype.getWavBitDepth = function (blob) {
1356
+ AudioRecorder.prototype.getBitDepth = function (audioContext, blob) {
1357
+ var _this = this;
1354
1358
  return new Promise(function (resolve, reject) {
1355
1359
  var reader = new FileReader();
1356
- reader.onload = function (event) {
1360
+ reader.onload = function (event) { return __awaiter(_this, void 0, void 0, function () {
1361
+ var arrayBuffer, channelData, maxAmplitude, i, isFloat;
1357
1362
  var _a;
1358
- var arrayBuffer = (_a = event.target) === null || _a === void 0 ? void 0 : _a.result;
1359
- if (!arrayBuffer) {
1360
- reject();
1361
- throw new Error('未能读取 Blob 数据');
1362
- }
1363
- var data = new DataView(arrayBuffer);
1364
- // 检查 "fmt " 区域,WAV文件的音频格式信息通常在此
1365
- var fmtChunkOffset = 20; // "fmt " chunk 在 WAV 文件头的位置
1366
- var bitDepth = data.getUint16(fmtChunkOffset + 14, true); // 16位表示小端存储
1367
- resolve(bitDepth);
1368
- };
1363
+ return __generator(this, function (_b) {
1364
+ switch (_b.label) {
1365
+ case 0: return [4 /*yield*/, audioContext.decodeAudioData((_a = event.target) === null || _a === void 0 ? void 0 : _a.result)];
1366
+ case 1:
1367
+ arrayBuffer = _b.sent();
1368
+ if (!arrayBuffer) {
1369
+ reject({
1370
+ error: '未能读取 Blob 数据'
1371
+ });
1372
+ }
1373
+ channelData = arrayBuffer.getChannelData(0);
1374
+ maxAmplitude = 0;
1375
+ for (i = 0; i < channelData.length; i++) {
1376
+ maxAmplitude = Math.max(maxAmplitude, Math.abs(channelData[i]));
1377
+ }
1378
+ isFloat = channelData.some(function (value) {
1379
+ return Math.abs(value) > 1.0 ||
1380
+ value.toString().includes('.');
1381
+ });
1382
+ resolve(isFloat ? 32 : 16);
1383
+ return [2 /*return*/];
1384
+ }
1385
+ });
1386
+ }); };
1369
1387
  reader.readAsArrayBuffer(blob);
1370
1388
  });
1371
1389
  };
1390
+ AudioRecorder.prototype.download = function (blob) {
1391
+ var _a;
1392
+ if (!blob)
1393
+ return null;
1394
+ var format = this.getExtension((_a = this.mediaRecorder) === null || _a === void 0 ? void 0 : _a.mimeType);
1395
+ var fileName = "recording_".concat(Date.now() + Math.random().toString(36).substring(2), ".").concat(format);
1396
+ var url = URL.createObjectURL(blob);
1397
+ var a = document.createElement('a');
1398
+ a.style.display = 'none';
1399
+ a.href = url;
1400
+ a.download = fileName;
1401
+ a.click();
1402
+ URL.revokeObjectURL(url);
1403
+ };
1372
1404
  AudioRecorder.prototype.getExtension = function (mimeType) {
1373
1405
  var mimeToExt = {
1374
1406
  'audio/webm': 'webm',
@@ -1387,27 +1419,30 @@
1387
1419
  // 上传音频到服务器
1388
1420
  AudioRecorder.prototype.upload = function (url, options) {
1389
1421
  return __awaiter(this, void 0, void 0, function () {
1390
- var audioBlob, formData, response, data, error_3;
1391
- return __generator(this, function (_a) {
1392
- switch (_a.label) {
1422
+ var audioBlob, formData, format, fileName, response, data, error_3;
1423
+ var _a;
1424
+ return __generator(this, function (_b) {
1425
+ switch (_b.label) {
1393
1426
  case 0:
1394
1427
  audioBlob = this.getAudioBlob();
1395
1428
  if (!audioBlob)
1396
1429
  return [2 /*return*/, null];
1397
1430
  formData = new FormData();
1398
- formData.append('audio', audioBlob, 'recording.mp4');
1399
- _a.label = 1;
1431
+ format = this.getExtension((_a = this.mediaRecorder) === null || _a === void 0 ? void 0 : _a.mimeType);
1432
+ fileName = "recording_".concat(Date.now() + Math.random().toString(36).substring(2), ".").concat(format);
1433
+ formData.append('audio', audioBlob, fileName);
1434
+ _b.label = 1;
1400
1435
  case 1:
1401
- _a.trys.push([1, 4, , 5]);
1436
+ _b.trys.push([1, 4, , 5]);
1402
1437
  return [4 /*yield*/, fetch(url, options)];
1403
1438
  case 2:
1404
- response = _a.sent();
1439
+ response = _b.sent();
1405
1440
  return [4 /*yield*/, response.json()];
1406
1441
  case 3:
1407
- data = _a.sent();
1442
+ data = _b.sent();
1408
1443
  return [2 /*return*/, data];
1409
1444
  case 4:
1410
- error_3 = _a.sent();
1445
+ error_3 = _b.sent();
1411
1446
  throw new Error(error_3);
1412
1447
  case 5: return [2 /*return*/];
1413
1448
  }
@@ -36,8 +36,9 @@ export declare class AudioRecorder {
36
36
  getAudioBlob(): Blob | null;
37
37
  getAudioUrl(): string;
38
38
  getAudioBase64(blob: Blob): Promise<string>;
39
- getAudioInfo(): Promise<unknown>;
40
- getWavBitDepth(blob: Blob): Promise<number>;
39
+ getAudioInfo(blob: Blob): Promise<unknown>;
40
+ getBitDepth(audioContext: AudioContext, blob: Blob): Promise<number>;
41
+ download(blob: Blob): null | undefined;
41
42
  getExtension(mimeType: string): string;
42
43
  upload(url: string, options?: RequestInit): Promise<any>;
43
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightsoft/js-sdk",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "",
5
5
  "main": "dist/index.umd.js",
6
6
  "module": "dist/index.js",