dg-lab-mcp-sse-server 1.1.3 → 1.2.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/dist/app.d.ts.map +1 -1
- package/dist/cli.js +256 -80
- package/dist/cli.js.map +2 -2
- package/dist/index.js +256 -80
- package/dist/index.js.map +2 -2
- package/dist/tools/control-tools.d.ts.map +1 -1
- package/dist/tools/waveform-tools.d.ts +1 -1
- package/dist/tools/waveform-tools.d.ts.map +1 -1
- package/dist/ws-server.d.ts +23 -4
- package/dist/ws-server.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/app.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,OAAO,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AAGpE;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,IAAI,GAAG,CAkD/B;
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI5C,OAAO,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AAGpE;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,SAAS,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,IAAI,GAAG,CAkD/B;AA2HD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBtD"}
|
package/dist/cli.js
CHANGED
|
@@ -1238,7 +1238,7 @@ var DGLabWSServer = class {
|
|
|
1238
1238
|
this.waveformTimers.clear();
|
|
1239
1239
|
for (const playback of this.continuousPlaybacks.values()) {
|
|
1240
1240
|
if (playback.timerId) {
|
|
1241
|
-
|
|
1241
|
+
clearTimeout(playback.timerId);
|
|
1242
1242
|
}
|
|
1243
1243
|
}
|
|
1244
1244
|
this.continuousPlaybacks.clear();
|
|
@@ -1401,7 +1401,7 @@ var DGLabWSServer = class {
|
|
|
1401
1401
|
for (const [key, playback] of this.continuousPlaybacks.entries()) {
|
|
1402
1402
|
if (playback.controllerId === clientId) {
|
|
1403
1403
|
if (playback.timerId) {
|
|
1404
|
-
|
|
1404
|
+
clearTimeout(playback.timerId);
|
|
1405
1405
|
}
|
|
1406
1406
|
this.continuousPlaybacks.delete(key);
|
|
1407
1407
|
console.log(`[WS \u670D\u52A1\u5668] \u5DF2\u505C\u6B62\u6301\u7EED\u64AD\u653E: ${key}`);
|
|
@@ -1559,7 +1559,7 @@ var DGLabWSServer = class {
|
|
|
1559
1559
|
const state = this.continuousPlaybacks.get(key);
|
|
1560
1560
|
if (state) {
|
|
1561
1561
|
if (state.timerId) {
|
|
1562
|
-
|
|
1562
|
+
clearTimeout(state.timerId);
|
|
1563
1563
|
}
|
|
1564
1564
|
this.continuousPlaybacks.delete(key);
|
|
1565
1565
|
console.log(`[WS \u670D\u52A1\u5668] \u5DF2\u505C\u6B62\u6301\u7EED\u64AD\u653E: ${key}`);
|
|
@@ -1630,16 +1630,16 @@ var DGLabWSServer = class {
|
|
|
1630
1630
|
* 启动持续播放
|
|
1631
1631
|
*
|
|
1632
1632
|
* 循环发送波形数据到指定通道,直到手动停止。
|
|
1633
|
-
*
|
|
1633
|
+
* 使用动态等待机制,根据实际播放时长和发送耗时计算等待时间。
|
|
1634
1634
|
*
|
|
1635
1635
|
* @param controllerId - 控制器 ID
|
|
1636
1636
|
* @param channel - 目标通道 A 或 B
|
|
1637
1637
|
* @param waveforms - 要循环播放的波形数据
|
|
1638
|
-
* @param interval - 发送间隔(毫秒),默认 100ms
|
|
1639
1638
|
* @param batchSize - 每次发送的波形数量,默认 5
|
|
1639
|
+
* @param bufferRatio - 缓冲比例(0.5-1.0),默认 0.9,用于计算等待时间
|
|
1640
1640
|
* @returns 是否成功启动
|
|
1641
1641
|
*/
|
|
1642
|
-
startContinuousPlayback(controllerId, channel, waveforms,
|
|
1642
|
+
startContinuousPlayback(controllerId, channel, waveforms, batchSize = 5, bufferRatio = 0.9) {
|
|
1643
1643
|
if (!this.isControllerBound(controllerId)) {
|
|
1644
1644
|
console.log(`[WS \u670D\u52A1\u5668] \u6301\u7EED\u64AD\u653E\u5931\u8D25: \u63A7\u5236\u5668 ${controllerId} \u672A\u7ED1\u5B9A APP`);
|
|
1645
1645
|
return false;
|
|
@@ -1652,35 +1652,68 @@ var DGLabWSServer = class {
|
|
|
1652
1652
|
if (this.continuousPlaybacks.has(key)) {
|
|
1653
1653
|
this.stopContinuousPlayback(controllerId, channel);
|
|
1654
1654
|
}
|
|
1655
|
+
const validBufferRatio = bufferRatio >= 0.5 && bufferRatio <= 1 ? bufferRatio : 0.9;
|
|
1656
|
+
const playbackDuration = batchSize * 100;
|
|
1655
1657
|
const state = {
|
|
1656
1658
|
controllerId,
|
|
1657
1659
|
channel,
|
|
1658
1660
|
waveforms,
|
|
1659
1661
|
currentIndex: 0,
|
|
1660
|
-
interval,
|
|
1661
1662
|
batchSize,
|
|
1663
|
+
bufferRatio: validBufferRatio,
|
|
1664
|
+
playbackDuration,
|
|
1662
1665
|
timerId: null,
|
|
1663
|
-
active: true
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
}
|
|
1669
|
-
const batch = [];
|
|
1670
|
-
for (let i = 0; i < state.batchSize; i++) {
|
|
1671
|
-
batch.push(state.waveforms[state.currentIndex]);
|
|
1672
|
-
state.currentIndex = (state.currentIndex + 1) % state.waveforms.length;
|
|
1673
|
-
}
|
|
1674
|
-
const success = this.sendWaveform(controllerId, channel, batch);
|
|
1675
|
-
if (!success) {
|
|
1676
|
-
console.log(`[WS \u670D\u52A1\u5668] \u6301\u7EED\u64AD\u653E\u53D1\u9001\u5931\u8D25\uFF0C\u505C\u6B62\u64AD\u653E: ${key}`);
|
|
1677
|
-
this.stopContinuousPlayback(controllerId, channel);
|
|
1666
|
+
active: true,
|
|
1667
|
+
stats: {
|
|
1668
|
+
sendCount: 0,
|
|
1669
|
+
totalElapsedTime: 0,
|
|
1670
|
+
lastSendTime: 0
|
|
1678
1671
|
}
|
|
1679
|
-
}
|
|
1672
|
+
};
|
|
1680
1673
|
this.continuousPlaybacks.set(key, state);
|
|
1681
|
-
console.log(`[WS \u670D\u52A1\u5668] \u5DF2\u542F\u52A8\u6301\u7EED\u64AD\u653E: ${key}\uFF0C\u6CE2\u5F62\u6570: ${waveforms.length}\uFF0C\
|
|
1674
|
+
console.log(`[WS \u670D\u52A1\u5668] \u5DF2\u542F\u52A8\u6301\u7EED\u64AD\u653E: ${key}\uFF0C\u6CE2\u5F62\u6570: ${waveforms.length}\uFF0C\u6279\u6B21\u5927\u5C0F: ${batchSize}\uFF0C\u64AD\u653E\u65F6\u957F: ${playbackDuration}ms\uFF0C\u7F13\u51B2\u6BD4\u4F8B: ${validBufferRatio}`);
|
|
1675
|
+
this.scheduleSend(state);
|
|
1682
1676
|
return true;
|
|
1683
1677
|
}
|
|
1678
|
+
/**
|
|
1679
|
+
* 调度发送波形(内部方法)
|
|
1680
|
+
*
|
|
1681
|
+
* 使用递归 setTimeout 实现动态等待机制:
|
|
1682
|
+
* 1. 记录发送开始时间
|
|
1683
|
+
* 2. 发送波形批次
|
|
1684
|
+
* 3. 计算发送耗时
|
|
1685
|
+
* 4. 计算等待时间 = 播放时长 × 缓冲比例 - 发送耗时
|
|
1686
|
+
* 5. 调度下次发送
|
|
1687
|
+
*
|
|
1688
|
+
* @param state - 持续播放状态
|
|
1689
|
+
*/
|
|
1690
|
+
scheduleSend(state) {
|
|
1691
|
+
if (!state.active) {
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
const startTime = Date.now();
|
|
1695
|
+
const batch = [];
|
|
1696
|
+
for (let i = 0; i < state.batchSize; i++) {
|
|
1697
|
+
batch.push(state.waveforms[state.currentIndex]);
|
|
1698
|
+
state.currentIndex = (state.currentIndex + 1) % state.waveforms.length;
|
|
1699
|
+
}
|
|
1700
|
+
const success = this.sendWaveform(state.controllerId, state.channel, batch);
|
|
1701
|
+
if (!success) {
|
|
1702
|
+
console.log(`[WS \u670D\u52A1\u5668] \u6301\u7EED\u64AD\u653E\u53D1\u9001\u5931\u8D25\uFF0C\u505C\u6B62\u64AD\u653E: ${state.controllerId}-${state.channel}`);
|
|
1703
|
+
this.stopContinuousPlayback(state.controllerId, state.channel);
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
const elapsedTime = Date.now() - startTime;
|
|
1707
|
+
state.stats.sendCount++;
|
|
1708
|
+
state.stats.totalElapsedTime += elapsedTime;
|
|
1709
|
+
state.stats.lastSendTime = startTime;
|
|
1710
|
+
const targetWaitTime = state.playbackDuration * state.bufferRatio - elapsedTime;
|
|
1711
|
+
const actualWaitTime = Math.max(10, targetWaitTime);
|
|
1712
|
+
if (targetWaitTime < 0) {
|
|
1713
|
+
console.warn(`[WS \u670D\u52A1\u5668] \u6301\u7EED\u64AD\u653E\u53D1\u9001\u592A\u6162: \u8017\u65F6 ${elapsedTime}ms > \u76EE\u6807\u65F6\u95F4 ${state.playbackDuration * state.bufferRatio}ms`);
|
|
1714
|
+
}
|
|
1715
|
+
state.timerId = setTimeout(() => this.scheduleSend(state), actualWaitTime);
|
|
1716
|
+
}
|
|
1684
1717
|
/**
|
|
1685
1718
|
* 停止持续播放
|
|
1686
1719
|
*
|
|
@@ -1697,9 +1730,13 @@ var DGLabWSServer = class {
|
|
|
1697
1730
|
console.log(`[WS \u670D\u52A1\u5668] \u505C\u6B62\u6301\u7EED\u64AD\u653E\u5931\u8D25: ${key} \u4E0D\u5B58\u5728`);
|
|
1698
1731
|
return false;
|
|
1699
1732
|
}
|
|
1733
|
+
if (state.stats.sendCount > 0) {
|
|
1734
|
+
const avgElapsedTime = state.stats.totalElapsedTime / state.stats.sendCount;
|
|
1735
|
+
console.log(`[WS \u670D\u52A1\u5668] \u6301\u7EED\u64AD\u653E\u7EDF\u8BA1: ${key}\uFF0C\u53D1\u9001\u6B21\u6570: ${state.stats.sendCount}\uFF0C\u5E73\u5747\u8017\u65F6: ${avgElapsedTime.toFixed(2)}ms`);
|
|
1736
|
+
}
|
|
1700
1737
|
state.active = false;
|
|
1701
1738
|
if (state.timerId) {
|
|
1702
|
-
|
|
1739
|
+
clearTimeout(state.timerId);
|
|
1703
1740
|
state.timerId = null;
|
|
1704
1741
|
}
|
|
1705
1742
|
this.clearWaveform(controllerId, channel);
|
|
@@ -1732,9 +1769,15 @@ var DGLabWSServer = class {
|
|
|
1732
1769
|
if (!state) return null;
|
|
1733
1770
|
return {
|
|
1734
1771
|
waveformCount: state.waveforms.length,
|
|
1735
|
-
interval: state.interval,
|
|
1736
1772
|
batchSize: state.batchSize,
|
|
1737
|
-
|
|
1773
|
+
bufferRatio: state.bufferRatio,
|
|
1774
|
+
playbackDuration: state.playbackDuration,
|
|
1775
|
+
active: state.active,
|
|
1776
|
+
stats: {
|
|
1777
|
+
sendCount: state.stats.sendCount,
|
|
1778
|
+
totalElapsedTime: state.stats.totalElapsedTime,
|
|
1779
|
+
avgElapsedTime: state.stats.sendCount > 0 ? state.stats.totalElapsedTime / state.stats.sendCount : 0
|
|
1780
|
+
}
|
|
1738
1781
|
};
|
|
1739
1782
|
}
|
|
1740
1783
|
/** 获取 APP 扫描的二维码 URL */
|
|
@@ -2481,10 +2524,37 @@ function createToolSuccess(data) {
|
|
|
2481
2524
|
}
|
|
2482
2525
|
var dgParseWaveformTool = {
|
|
2483
2526
|
name: "dg_parse_waveform",
|
|
2484
|
-
description: `\u89E3\u6790\
|
|
2485
|
-
|
|
2486
|
-
\
|
|
2487
|
-
\
|
|
2527
|
+
description: `\u89E3\u6790 DG-LAB APP \u5BFC\u51FA\u7684\u6CE2\u5F62\u6570\u636E\u3002
|
|
2528
|
+
|
|
2529
|
+
\u529F\u80FD\uFF1A
|
|
2530
|
+
- \u89E3\u6790 Dungeonlab+pulse: \u683C\u5F0F\u7684\u6CE2\u5F62\u6570\u636E
|
|
2531
|
+
- \u8F6C\u6362\u4E3A\u8BBE\u5907\u53EF\u7528\u7684 hexWaveforms \u6570\u7EC4
|
|
2532
|
+
- \u53EF\u9009\u62E9\u662F\u5426\u4FDD\u5B58\u5230\u5B58\u50A8\u4F9B\u540E\u7EED\u4F7F\u7528
|
|
2533
|
+
|
|
2534
|
+
\u53C2\u6570\uFF1A
|
|
2535
|
+
- hexData (\u5FC5\u9700): \u6CE2\u5F62\u6570\u636E\u5B57\u7B26\u4E32\uFF0C\u5FC5\u987B\u4EE5 "Dungeonlab+pulse:" \u5F00\u5934
|
|
2536
|
+
- name (save=true\u65F6\u5FC5\u9700): \u6CE2\u5F62\u540D\u79F0\uFF0C\u7528\u4E8E\u4FDD\u5B58\u548C\u540E\u7EED\u5F15\u7528
|
|
2537
|
+
- save (\u53EF\u9009): \u662F\u5426\u4FDD\u5B58\u5230\u5B58\u50A8\uFF0C\u9ED8\u8BA4 false
|
|
2538
|
+
|
|
2539
|
+
\u4F7F\u7528\u573A\u666F\uFF1A
|
|
2540
|
+
1. \u4E34\u65F6\u89E3\u6790\uFF1A\u53EA\u9700\u8981 hexWaveforms\uFF0C\u4E0D\u4FDD\u5B58
|
|
2541
|
+
\u2192 \u53EA\u4F20 hexData\uFF0C\u8FD4\u56DE\u7ED3\u679C\u5305\u542B hexWaveforms
|
|
2542
|
+
2. \u4FDD\u5B58\u590D\u7528\uFF1A\u89E3\u6790\u5E76\u4FDD\u5B58\uFF0C\u540E\u7EED\u901A\u8FC7 dg_get_waveform \u83B7\u53D6
|
|
2543
|
+
\u2192 \u4F20 hexData\u3001name\u3001save=true
|
|
2544
|
+
|
|
2545
|
+
\u8FD4\u56DE\u503C\uFF1A
|
|
2546
|
+
- success: \u662F\u5426\u6210\u529F
|
|
2547
|
+
- name: \u6CE2\u5F62\u540D\u79F0
|
|
2548
|
+
- saved: \u662F\u5426\u5DF2\u4FDD\u5B58
|
|
2549
|
+
- hexWaveformCount: hexWaveforms \u6570\u91CF
|
|
2550
|
+
- hexWaveforms: \u6CE2\u5F62\u6570\u636E\u6570\u7EC4\uFF08\u4EC5\u5F53 save=false \u65F6\u8FD4\u56DE\uFF09
|
|
2551
|
+
- metadata: \u5143\u6570\u636E\uFF08sectionCount, totalDuration\uFF09
|
|
2552
|
+
- overwritten: \u662F\u5426\u8986\u76D6\u4E86\u5DF2\u5B58\u5728\u7684\u6CE2\u5F62\uFF08\u4EC5\u5F53\u8986\u76D6\u65F6\u8FD4\u56DE\uFF09
|
|
2553
|
+
|
|
2554
|
+
\u6CE8\u610F\u4E8B\u9879\uFF1A
|
|
2555
|
+
- \u6CE2\u5F62\u6570\u636E\u4ECE DG-LAB APP \u7684"\u5206\u4EAB\u6CE2\u5F62"\u529F\u80FD\u5BFC\u51FA
|
|
2556
|
+
- \u6BCF\u4E2A hexWaveform \u4EE3\u8868 100ms \u7684\u64AD\u653E\u65F6\u95F4
|
|
2557
|
+
- \u76F8\u540C\u540D\u79F0\u4F1A\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u6CE2\u5F62`,
|
|
2488
2558
|
inputSchema: {
|
|
2489
2559
|
type: "object",
|
|
2490
2560
|
properties: {
|
|
@@ -2494,32 +2564,58 @@ var dgParseWaveformTool = {
|
|
|
2494
2564
|
},
|
|
2495
2565
|
name: {
|
|
2496
2566
|
type: "string",
|
|
2497
|
-
description: "\u6CE2\u5F62\u540D\u79F0\uFF0C\u7528\u4E8E\u4FDD\u5B58\u548C\u540E\u7EED\u5F15\u7528"
|
|
2567
|
+
description: "\u6CE2\u5F62\u540D\u79F0\uFF0C\u7528\u4E8E\u4FDD\u5B58\u548C\u540E\u7EED\u5F15\u7528\u3002\u5F53 save=true \u65F6\u5FC5\u9700"
|
|
2568
|
+
},
|
|
2569
|
+
save: {
|
|
2570
|
+
type: "boolean",
|
|
2571
|
+
description: "\u662F\u5426\u4FDD\u5B58\u6CE2\u5F62\u5230\u5B58\u50A8\uFF08\u9ED8\u8BA4 false\uFF09\u3002\u8BBE\u4E3A true \u65F6\u9700\u8981\u63D0\u4F9B name \u53C2\u6570"
|
|
2498
2572
|
}
|
|
2499
2573
|
},
|
|
2500
|
-
required: ["hexData"
|
|
2574
|
+
required: ["hexData"]
|
|
2501
2575
|
},
|
|
2502
2576
|
handler: async (params) => {
|
|
2503
2577
|
const hexData = params.hexData;
|
|
2504
2578
|
const name = params.name;
|
|
2579
|
+
const save = params.save;
|
|
2505
2580
|
if (!hexData || typeof hexData !== "string") {
|
|
2506
2581
|
return createToolError2("hexData \u662F\u5FC5\u9700\u7684\u4E14\u5FC5\u987B\u662F\u5B57\u7B26\u4E32");
|
|
2507
2582
|
}
|
|
2508
|
-
if (
|
|
2509
|
-
return createToolError2("
|
|
2583
|
+
if (save !== void 0 && typeof save !== "boolean") {
|
|
2584
|
+
return createToolError2("save \u53C2\u6570\u5FC5\u987B\u662F boolean \u7C7B\u578B");
|
|
2510
2585
|
}
|
|
2586
|
+
const shouldSave = save === true;
|
|
2587
|
+
if (shouldSave && (!name || typeof name !== "string" || name.trim().length === 0)) {
|
|
2588
|
+
return createToolError2("\u5F53 save=true \u65F6\uFF0Cname \u662F\u5FC5\u9700\u7684\u4E14\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");
|
|
2589
|
+
}
|
|
2590
|
+
const waveformName = name?.trim() || "unnamed";
|
|
2511
2591
|
try {
|
|
2512
|
-
const waveform = parseWaveform(hexData,
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2592
|
+
const waveform = parseWaveform(hexData, waveformName);
|
|
2593
|
+
let overwritten = false;
|
|
2594
|
+
if (shouldSave) {
|
|
2595
|
+
const storage = getWaveformStorage();
|
|
2596
|
+
overwritten = storage.has(waveformName);
|
|
2597
|
+
storage.save(waveform);
|
|
2598
|
+
persistWaveforms(storage, storagePath);
|
|
2599
|
+
}
|
|
2600
|
+
const metadata = {
|
|
2601
|
+
sectionCount: waveform.sections.length,
|
|
2602
|
+
totalDuration: waveform.hexWaveforms.length * 100
|
|
2603
|
+
// 每个 hexWaveform 代表 100ms
|
|
2604
|
+
};
|
|
2605
|
+
const result = {
|
|
2518
2606
|
success: true,
|
|
2519
2607
|
name: waveform.name,
|
|
2520
|
-
|
|
2521
|
-
hexWaveformCount: waveform.hexWaveforms.length
|
|
2522
|
-
|
|
2608
|
+
saved: shouldSave,
|
|
2609
|
+
hexWaveformCount: waveform.hexWaveforms.length,
|
|
2610
|
+
metadata
|
|
2611
|
+
};
|
|
2612
|
+
if (shouldSave && overwritten) {
|
|
2613
|
+
result.overwritten = true;
|
|
2614
|
+
}
|
|
2615
|
+
if (!shouldSave) {
|
|
2616
|
+
result.hexWaveforms = waveform.hexWaveforms;
|
|
2617
|
+
}
|
|
2618
|
+
return createToolSuccess(result);
|
|
2523
2619
|
} catch (error) {
|
|
2524
2620
|
if (error instanceof Error) {
|
|
2525
2621
|
return createToolError2(error.message);
|
|
@@ -2530,9 +2626,26 @@ var dgParseWaveformTool = {
|
|
|
2530
2626
|
};
|
|
2531
2627
|
var dgListWaveformsTool = {
|
|
2532
2628
|
name: "dg_list_waveforms",
|
|
2533
|
-
description: `\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684\u6CE2\u5F62\
|
|
2534
|
-
|
|
2535
|
-
\
|
|
2629
|
+
description: `\u5217\u51FA\u6240\u6709\u5DF2\u4FDD\u5B58\u7684\u6CE2\u5F62\u3002
|
|
2630
|
+
|
|
2631
|
+
\u529F\u80FD\uFF1A
|
|
2632
|
+
- \u83B7\u53D6\u5B58\u50A8\u4E2D\u6240\u6709\u6CE2\u5F62\u7684\u6982\u89C8\u4FE1\u606F
|
|
2633
|
+
- \u663E\u793A\u6BCF\u4E2A\u6CE2\u5F62\u7684\u540D\u79F0\u548C\u6570\u636E\u91CF
|
|
2634
|
+
|
|
2635
|
+
\u8FD4\u56DE\u503C\uFF1A
|
|
2636
|
+
- count: \u6CE2\u5F62\u603B\u6570
|
|
2637
|
+
- waveforms: \u6CE2\u5F62\u5217\u8868\u6570\u7EC4
|
|
2638
|
+
- name: \u6CE2\u5F62\u540D\u79F0
|
|
2639
|
+
- hexWaveformCount: hexWaveforms \u6570\u91CF\uFF08\u6BCF\u4E2A\u4EE3\u8868 100ms\uFF09
|
|
2640
|
+
|
|
2641
|
+
\u5178\u578B\u5DE5\u4F5C\u6D41\u7A0B\uFF1A
|
|
2642
|
+
1. dg_list_waveforms \u67E5\u770B\u53EF\u7528\u6CE2\u5F62
|
|
2643
|
+
2. dg_get_waveform \u83B7\u53D6\u5177\u4F53\u6CE2\u5F62\u6570\u636E
|
|
2644
|
+
3. dg_send_waveform \u53D1\u9001\u5230\u8BBE\u5907
|
|
2645
|
+
|
|
2646
|
+
\u6CE8\u610F\u4E8B\u9879\uFF1A
|
|
2647
|
+
- \u53EA\u663E\u793A\u901A\u8FC7 dg_parse_waveform (save=true) \u4FDD\u5B58\u7684\u6CE2\u5F62
|
|
2648
|
+
- hexWaveformCount \xD7 100ms = \u6CE2\u5F62\u603B\u65F6\u957F`,
|
|
2536
2649
|
inputSchema: {
|
|
2537
2650
|
type: "object",
|
|
2538
2651
|
properties: {},
|
|
@@ -2553,9 +2666,31 @@ var dgListWaveformsTool = {
|
|
|
2553
2666
|
};
|
|
2554
2667
|
var dgGetWaveformTool = {
|
|
2555
2668
|
name: "dg_get_waveform",
|
|
2556
|
-
description: `\u6309\u540D\u79F0\u83B7\u53D6\u6CE2\u5F62\
|
|
2557
|
-
|
|
2558
|
-
\
|
|
2669
|
+
description: `\u6309\u540D\u79F0\u83B7\u53D6\u5DF2\u4FDD\u5B58\u7684\u6CE2\u5F62\u6570\u636E\u3002
|
|
2670
|
+
|
|
2671
|
+
\u529F\u80FD\uFF1A
|
|
2672
|
+
- \u4ECE\u5B58\u50A8\u4E2D\u83B7\u53D6\u6307\u5B9A\u540D\u79F0\u7684\u6CE2\u5F62
|
|
2673
|
+
- \u8FD4\u56DE\u5B8C\u6574\u7684 hexWaveforms \u6570\u7EC4
|
|
2674
|
+
|
|
2675
|
+
\u53C2\u6570\uFF1A
|
|
2676
|
+
- name (\u5FC5\u9700): \u6CE2\u5F62\u540D\u79F0
|
|
2677
|
+
|
|
2678
|
+
\u8FD4\u56DE\u503C\uFF1A
|
|
2679
|
+
- name: \u6CE2\u5F62\u540D\u79F0
|
|
2680
|
+
- hexWaveforms: \u6CE2\u5F62\u6570\u636E\u6570\u7EC4\uFF0C\u53EF\u76F4\u63A5\u7528\u4E8E dg_send_waveform
|
|
2681
|
+
|
|
2682
|
+
\u5178\u578B\u5DE5\u4F5C\u6D41\u7A0B\uFF1A
|
|
2683
|
+
1. dg_list_waveforms \u67E5\u770B\u53EF\u7528\u6CE2\u5F62
|
|
2684
|
+
2. dg_get_waveform \u83B7\u53D6\u5177\u4F53\u6CE2\u5F62\u6570\u636E
|
|
2685
|
+
3. dg_send_waveform \u6216 dg_start_continuous_playback \u53D1\u9001\u5230\u8BBE\u5907
|
|
2686
|
+
|
|
2687
|
+
\u4E0E\u5176\u4ED6\u5DE5\u5177\u914D\u5408\uFF1A
|
|
2688
|
+
- dg_send_waveform: \u4E00\u6B21\u6027\u53D1\u9001\u6CE2\u5F62
|
|
2689
|
+
- dg_start_continuous_playback: \u6301\u7EED\u5FAA\u73AF\u64AD\u653E\u6CE2\u5F62
|
|
2690
|
+
|
|
2691
|
+
\u6CE8\u610F\u4E8B\u9879\uFF1A
|
|
2692
|
+
- \u6CE2\u5F62\u5FC5\u987B\u5148\u901A\u8FC7 dg_parse_waveform (save=true) \u4FDD\u5B58
|
|
2693
|
+
- \u5982\u679C\u6CE2\u5F62\u4E0D\u5B58\u5728\u4F1A\u8FD4\u56DE\u9519\u8BEF`,
|
|
2559
2694
|
inputSchema: {
|
|
2560
2695
|
type: "object",
|
|
2561
2696
|
properties: {
|
|
@@ -2585,7 +2720,26 @@ var dgGetWaveformTool = {
|
|
|
2585
2720
|
var dgDeleteWaveformTool = {
|
|
2586
2721
|
name: "dg_delete_waveform",
|
|
2587
2722
|
description: `\u6309\u540D\u79F0\u5220\u9664\u5DF2\u4FDD\u5B58\u7684\u6CE2\u5F62\u3002
|
|
2588
|
-
|
|
2723
|
+
|
|
2724
|
+
\u529F\u80FD\uFF1A
|
|
2725
|
+
- \u4ECE\u5B58\u50A8\u4E2D\u6C38\u4E45\u5220\u9664\u6307\u5B9A\u6CE2\u5F62
|
|
2726
|
+
- \u540C\u65F6\u4ECE\u78C1\u76D8\u6301\u4E45\u5316\u6587\u4EF6\u4E2D\u79FB\u9664
|
|
2727
|
+
|
|
2728
|
+
\u53C2\u6570\uFF1A
|
|
2729
|
+
- name (\u5FC5\u9700): \u8981\u5220\u9664\u7684\u6CE2\u5F62\u540D\u79F0
|
|
2730
|
+
|
|
2731
|
+
\u8FD4\u56DE\u503C\uFF1A
|
|
2732
|
+
- success: \u662F\u5426\u6210\u529F
|
|
2733
|
+
- deleted: \u88AB\u5220\u9664\u7684\u6CE2\u5F62\u540D\u79F0
|
|
2734
|
+
|
|
2735
|
+
\u26A0\uFE0F \u8B66\u544A\uFF1A
|
|
2736
|
+
- \u5220\u9664\u64CD\u4F5C\u4E0D\u53EF\u9006\uFF01
|
|
2737
|
+
- \u5220\u9664\u540E\u9700\u8981\u91CD\u65B0\u7528 dg_parse_waveform \u89E3\u6790\u4FDD\u5B58
|
|
2738
|
+
- \u5EFA\u8BAE\u5220\u9664\u524D\u786E\u8BA4\u6CE2\u5F62\u540D\u79F0
|
|
2739
|
+
|
|
2740
|
+
\u6CE8\u610F\u4E8B\u9879\uFF1A
|
|
2741
|
+
- \u5982\u679C\u6CE2\u5F62\u4E0D\u5B58\u5728\u4F1A\u8FD4\u56DE\u9519\u8BEF
|
|
2742
|
+
- \u5220\u9664\u4E0D\u4F1A\u5F71\u54CD\u6B63\u5728\u8FDB\u884C\u7684\u6301\u7EED\u64AD\u653E`,
|
|
2589
2743
|
inputSchema: {
|
|
2590
2744
|
type: "object",
|
|
2591
2745
|
properties: {
|
|
@@ -2928,13 +3082,27 @@ function registerControlTools(toolManager, sessionManager, wsServer) {
|
|
|
2928
3082
|
toolManager.registerTool(
|
|
2929
3083
|
"dg_start_continuous_playback",
|
|
2930
3084
|
`\u542F\u52A8\u6301\u7EED\u64AD\u653E\u6A21\u5F0F\uFF0C\u5FAA\u73AF\u53D1\u9001\u6CE2\u5F62\u6570\u636E\u76F4\u5230\u624B\u52A8\u505C\u6B62\u3002
|
|
2931
|
-
|
|
2932
|
-
\
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
\
|
|
2936
|
-
|
|
2937
|
-
|
|
3085
|
+
|
|
3086
|
+
\u529F\u80FD\uFF1A
|
|
3087
|
+
- \u81EA\u52A8\u5FAA\u73AF\u53D1\u9001\u6CE2\u5F62\uFF0C\u9002\u5408\u9700\u8981\u6301\u7EED\u8F93\u51FA\u7684\u573A\u666F
|
|
3088
|
+
- \u4F7F\u7528\u52A8\u6001\u7B49\u5F85\u673A\u5236\uFF0C\u6839\u636E\u5B9E\u9645\u64AD\u653E\u65F6\u957F\u548C\u53D1\u9001\u8017\u65F6\u8BA1\u7B97\u7B49\u5F85\u65F6\u95F4
|
|
3089
|
+
- \u6BCF\u4E2A hexWaveform \u4EE3\u8868 100ms \u7684\u64AD\u653E\u65F6\u95F4
|
|
3090
|
+
|
|
3091
|
+
\u53C2\u6570\uFF1A
|
|
3092
|
+
- deviceId \u6216 alias: \u8BBE\u5907\u6807\u8BC6\uFF08\u4E8C\u9009\u4E00\uFF0CdeviceId\u4F18\u5148\uFF09
|
|
3093
|
+
- channel: A\u6216B\u901A\u9053
|
|
3094
|
+
- waveforms \u6216 waveformName: \u6CE2\u5F62\u6570\u636E\u6765\u6E90\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
3095
|
+
- batchSize: \u6BCF\u6B21\u53D1\u9001\u7684\u6CE2\u5F62\u6570\u91CF\uFF0C\u9ED8\u8BA45\uFF08\u64AD\u653E\u65F6\u957F = batchSize \xD7 100ms\uFF09
|
|
3096
|
+
- bufferRatio: \u7F13\u51B2\u6BD4\u4F8B\uFF080.5-1.0\uFF09\uFF0C\u9ED8\u8BA40.9\uFF0C\u7528\u4E8E\u8BA1\u7B97\u7B49\u5F85\u65F6\u95F4
|
|
3097
|
+
|
|
3098
|
+
\u65F6\u5E8F\u673A\u5236\uFF1A
|
|
3099
|
+
- \u64AD\u653E\u65F6\u957F = batchSize \xD7 100ms
|
|
3100
|
+
- \u7B49\u5F85\u65F6\u95F4 = \u64AD\u653E\u65F6\u957F \xD7 bufferRatio - \u53D1\u9001\u8017\u65F6
|
|
3101
|
+
- \u6700\u5C0F\u7B49\u5F85\u65F6\u95F4 = 10ms
|
|
3102
|
+
|
|
3103
|
+
\u4E0E dg_send_waveform \u7684\u533A\u522B\uFF1A
|
|
3104
|
+
- dg_send_waveform: \u4E00\u6B21\u6027\u53D1\u9001\uFF0C\u64AD\u653E\u5B8C\u6BD5\u540E\u505C\u6B62
|
|
3105
|
+
- dg_start_continuous_playback: \u5FAA\u73AF\u53D1\u9001\uFF0C\u76F4\u5230\u624B\u52A8\u505C\u6B62`,
|
|
2938
3106
|
{
|
|
2939
3107
|
type: "object",
|
|
2940
3108
|
properties: {
|
|
@@ -2951,17 +3119,17 @@ function registerControlTools(toolManager, sessionManager, wsServer) {
|
|
|
2951
3119
|
type: "string",
|
|
2952
3120
|
description: "\u5DF2\u4FDD\u5B58\u7684\u6CE2\u5F62\u540D\u79F0\u3002\u4E0Ewaveforms\u4E8C\u9009\u4E00"
|
|
2953
3121
|
},
|
|
2954
|
-
interval: {
|
|
2955
|
-
type: "number",
|
|
2956
|
-
minimum: 50,
|
|
2957
|
-
maximum: 5e3,
|
|
2958
|
-
description: "\u53D1\u9001\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09\uFF0C\u9ED8\u8BA4100"
|
|
2959
|
-
},
|
|
2960
3122
|
batchSize: {
|
|
2961
3123
|
type: "number",
|
|
2962
3124
|
minimum: 1,
|
|
2963
3125
|
maximum: 20,
|
|
2964
|
-
description: "\u6BCF\u6B21\u53D1\u9001\u7684\u6CE2\u5F62\u6570\u91CF\uFF0C\u9ED8\u8BA45"
|
|
3126
|
+
description: "\u6BCF\u6B21\u53D1\u9001\u7684\u6CE2\u5F62\u6570\u91CF\uFF0C\u9ED8\u8BA45\uFF08\u64AD\u653E\u65F6\u957F = batchSize \xD7 100ms\uFF09"
|
|
3127
|
+
},
|
|
3128
|
+
bufferRatio: {
|
|
3129
|
+
type: "number",
|
|
3130
|
+
minimum: 0.5,
|
|
3131
|
+
maximum: 1,
|
|
3132
|
+
description: "\u7F13\u51B2\u6BD4\u4F8B\uFF080.5-1.0\uFF09\uFF0C\u9ED8\u8BA40.9\uFF0C\u7528\u4E8E\u8BA1\u7B97\u7B49\u5F85\u65F6\u95F4"
|
|
2965
3133
|
}
|
|
2966
3134
|
},
|
|
2967
3135
|
required: ["channel"]
|
|
@@ -3002,27 +3170,29 @@ function registerControlTools(toolManager, sessionManager, wsServer) {
|
|
|
3002
3170
|
if (!isBound) {
|
|
3003
3171
|
return createToolError("\u8BBE\u5907\u672A\u7ED1\u5B9AAPP");
|
|
3004
3172
|
}
|
|
3005
|
-
const interval = typeof params.interval === "number" ? params.interval : 100;
|
|
3006
3173
|
const batchSize = typeof params.batchSize === "number" ? params.batchSize : 5;
|
|
3174
|
+
const bufferRatio = typeof params.bufferRatio === "number" ? params.bufferRatio : 0.9;
|
|
3007
3175
|
const success = wsServer.startContinuousPlayback(
|
|
3008
3176
|
session.clientId,
|
|
3009
3177
|
channel,
|
|
3010
3178
|
waveforms,
|
|
3011
|
-
|
|
3012
|
-
|
|
3179
|
+
batchSize,
|
|
3180
|
+
bufferRatio
|
|
3013
3181
|
);
|
|
3014
3182
|
if (!success) {
|
|
3015
3183
|
return createToolError("\u542F\u52A8\u6301\u7EED\u64AD\u653E\u5931\u8D25");
|
|
3016
3184
|
}
|
|
3017
3185
|
sessionManager.touchSession(session.deviceId);
|
|
3186
|
+
const playbackDuration = batchSize * 100;
|
|
3018
3187
|
return createToolResult(
|
|
3019
3188
|
JSON.stringify({
|
|
3020
3189
|
success: true,
|
|
3021
3190
|
deviceId: session.deviceId,
|
|
3022
3191
|
channel,
|
|
3023
3192
|
waveformCount: waveforms.length,
|
|
3024
|
-
interval,
|
|
3025
3193
|
batchSize,
|
|
3194
|
+
bufferRatio,
|
|
3195
|
+
playbackDuration,
|
|
3026
3196
|
source: rawWaveforms ? "direct" : `waveform:${waveformName}`
|
|
3027
3197
|
})
|
|
3028
3198
|
);
|
|
@@ -3072,7 +3242,14 @@ function registerControlTools(toolManager, sessionManager, wsServer) {
|
|
|
3072
3242
|
toolManager.registerTool(
|
|
3073
3243
|
"dg_get_playback_status",
|
|
3074
3244
|
`\u83B7\u53D6\u8BBE\u5907\u7684\u6301\u7EED\u64AD\u653E\u72B6\u6001\u3002
|
|
3075
|
-
|
|
3245
|
+
|
|
3246
|
+
\u8FD4\u56DE A \u548C B \u901A\u9053\u7684\u64AD\u653E\u72B6\u6001\uFF0C\u5305\u62EC\uFF1A
|
|
3247
|
+
- playing: \u662F\u5426\u6B63\u5728\u64AD\u653E
|
|
3248
|
+
- waveformCount: \u6CE2\u5F62\u6570\u91CF
|
|
3249
|
+
- batchSize: \u6BCF\u6B21\u53D1\u9001\u7684\u6CE2\u5F62\u6570\u91CF
|
|
3250
|
+
- bufferRatio: \u7F13\u51B2\u6BD4\u4F8B
|
|
3251
|
+
- playbackDuration: \u64AD\u653E\u65F6\u957F\uFF08\u6BEB\u79D2\uFF09
|
|
3252
|
+
- stats: \u7EDF\u8BA1\u4FE1\u606F\uFF08\u53D1\u9001\u6B21\u6570\u3001\u5E73\u5747\u8017\u65F6\uFF09`,
|
|
3076
3253
|
{
|
|
3077
3254
|
type: "object",
|
|
3078
3255
|
properties: {
|
|
@@ -3100,14 +3277,18 @@ function registerControlTools(toolManager, sessionManager, wsServer) {
|
|
|
3100
3277
|
channelA: statusA ? {
|
|
3101
3278
|
playing: statusA.active,
|
|
3102
3279
|
waveformCount: statusA.waveformCount,
|
|
3103
|
-
|
|
3104
|
-
|
|
3280
|
+
batchSize: statusA.batchSize,
|
|
3281
|
+
bufferRatio: statusA.bufferRatio,
|
|
3282
|
+
playbackDuration: statusA.playbackDuration,
|
|
3283
|
+
stats: statusA.stats
|
|
3105
3284
|
} : { playing: false },
|
|
3106
3285
|
channelB: statusB ? {
|
|
3107
3286
|
playing: statusB.active,
|
|
3108
3287
|
waveformCount: statusB.waveformCount,
|
|
3109
|
-
|
|
3110
|
-
|
|
3288
|
+
batchSize: statusB.batchSize,
|
|
3289
|
+
bufferRatio: statusB.bufferRatio,
|
|
3290
|
+
playbackDuration: statusB.playbackDuration,
|
|
3291
|
+
stats: statusB.stats
|
|
3111
3292
|
} : { playing: false }
|
|
3112
3293
|
})
|
|
3113
3294
|
);
|
|
@@ -3192,12 +3373,7 @@ function createWSServer(config, sessionManager) {
|
|
|
3192
3373
|
console.log(`[WS] \u63A7\u5236\u5668\u65AD\u5F00: ${controllerId}`);
|
|
3193
3374
|
const session = sessionManager.getSessionByClientId(controllerId);
|
|
3194
3375
|
if (session) {
|
|
3195
|
-
sessionManager.
|
|
3196
|
-
connected: false,
|
|
3197
|
-
boundToApp: false,
|
|
3198
|
-
clientId: null,
|
|
3199
|
-
targetId: null
|
|
3200
|
-
});
|
|
3376
|
+
sessionManager.handleDisconnection(session.deviceId);
|
|
3201
3377
|
}
|
|
3202
3378
|
},
|
|
3203
3379
|
onAppDisconnect: (appId) => {
|