@midscene/playground 1.8.0 → 1.8.1
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/es/mjpeg-stream-handler.mjs +179 -0
- package/dist/es/mjpeg-stream-handler.mjs.map +1 -0
- package/dist/es/pointer-dispatch.mjs +160 -0
- package/dist/es/pointer-dispatch.mjs.map +1 -0
- package/dist/es/server.mjs +52 -163
- package/dist/es/server.mjs.map +1 -1
- package/dist/lib/mjpeg-stream-handler.js +223 -0
- package/dist/lib/mjpeg-stream-handler.js.map +1 -0
- package/dist/lib/pointer-dispatch.js +197 -0
- package/dist/lib/pointer-dispatch.js.map +1 -0
- package/dist/lib/server.js +52 -164
- package/dist/lib/server.js.map +1 -1
- package/dist/types/mjpeg-stream-handler.d.ts +51 -0
- package/dist/types/pointer-dispatch.d.ts +21 -0
- package/dist/types/server.d.ts +2 -21
- package/package.json +3 -3
- package/static/index.html +1 -1
- package/static/static/css/{index.63b028da.css → index.26c9c911.css} +2 -2
- package/static/static/css/{index.63b028da.css.map → index.26c9c911.css.map} +1 -1
- package/static/static/js/{889.c8e2e995.js → 596.5426be9e.js} +27 -27
- package/static/static/js/596.5426be9e.js.map +1 -0
- package/static/static/js/index.acaa5ec1.js +914 -0
- package/static/static/js/index.acaa5ec1.js.map +1 -0
- package/static/static/js/889.c8e2e995.js.map +0 -1
- package/static/static/js/index.7d3d953d.js +0 -914
- package/static/static/js/index.7d3d953d.js.map +0 -1
- /package/static/static/js/{889.c8e2e995.js.LICENSE.txt → 596.5426be9e.js.LICENSE.txt} +0 -0
- /package/static/static/js/{index.7d3d953d.js.LICENSE.txt → index.acaa5ec1.js.LICENSE.txt} +0 -0
package/dist/lib/server.js
CHANGED
|
@@ -44,8 +44,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
44
44
|
buildInteractParams: ()=>buildInteractParams
|
|
45
45
|
});
|
|
46
46
|
const external_node_fs_namespaceObject = require("node:fs");
|
|
47
|
-
const external_node_http_namespaceObject = require("node:http");
|
|
48
|
-
var external_node_http_default = /*#__PURE__*/ __webpack_require__.n(external_node_http_namespaceObject);
|
|
49
47
|
const external_node_path_namespaceObject = require("node:path");
|
|
50
48
|
const external_node_url_namespaceObject = require("node:url");
|
|
51
49
|
const core_namespaceObject = require("@midscene/core");
|
|
@@ -58,7 +56,8 @@ const shared_utils_namespaceObject = require("@midscene/shared/utils");
|
|
|
58
56
|
const external_express_namespaceObject = require("express");
|
|
59
57
|
var external_express_default = /*#__PURE__*/ __webpack_require__.n(external_express_namespaceObject);
|
|
60
58
|
const external_common_js_namespaceObject = require("./common.js");
|
|
61
|
-
const
|
|
59
|
+
const external_mjpeg_stream_handler_js_namespaceObject = require("./mjpeg-stream-handler.js");
|
|
60
|
+
const external_pointer_dispatch_js_namespaceObject = require("./pointer-dispatch.js");
|
|
62
61
|
const external_runtime_metadata_js_namespaceObject = require("./runtime-metadata.js");
|
|
63
62
|
require("dotenv/config");
|
|
64
63
|
function _define_property(obj, key, value) {
|
|
@@ -128,6 +127,19 @@ function locateFromPoint(x, y, fieldX, fieldY, description) {
|
|
|
128
127
|
Math.round(requireNumber(y, fieldY))
|
|
129
128
|
], description);
|
|
130
129
|
}
|
|
130
|
+
const POINTER_INTERACT_ACTIONS = new Set([
|
|
131
|
+
'Tap',
|
|
132
|
+
'DoubleClick',
|
|
133
|
+
'LongPress',
|
|
134
|
+
'Swipe',
|
|
135
|
+
'DragAndDrop',
|
|
136
|
+
'KeyboardPress',
|
|
137
|
+
'Input',
|
|
138
|
+
'Pinch'
|
|
139
|
+
]);
|
|
140
|
+
function isPointerInteractActionType(actionType) {
|
|
141
|
+
return POINTER_INTERACT_ACTIONS.has(actionType);
|
|
142
|
+
}
|
|
131
143
|
const buildLocateActionParams = (body, actionType)=>{
|
|
132
144
|
const params = {
|
|
133
145
|
locate: locateFromPoint(body.x, body.y, 'x', 'y', `manual ${actionType}`)
|
|
@@ -218,6 +230,10 @@ function isRecoverablePageSessionError(error) {
|
|
|
218
230
|
return RECOVERABLE_PAGE_SESSION_ERROR_PATTERN.test(message);
|
|
219
231
|
}
|
|
220
232
|
class PlaygroundServer {
|
|
233
|
+
setActiveAgent(agent) {
|
|
234
|
+
this._activeConnection.agent = agent;
|
|
235
|
+
this._mjpegHandler.reset();
|
|
236
|
+
}
|
|
221
237
|
get agent() {
|
|
222
238
|
return this._activeConnection.agent;
|
|
223
239
|
}
|
|
@@ -270,6 +286,7 @@ class PlaygroundServer {
|
|
|
270
286
|
executionHooks: this._baseExecutionHooks,
|
|
271
287
|
sidecars: this._baseSidecars
|
|
272
288
|
};
|
|
289
|
+
this._mjpegHandler.reset();
|
|
273
290
|
this.syncRuntimeState();
|
|
274
291
|
}
|
|
275
292
|
setPreparedPlatform(prepared) {
|
|
@@ -365,7 +382,7 @@ class PlaygroundServer {
|
|
|
365
382
|
} catch (error) {
|
|
366
383
|
console.warn('Failed to destroy old agent:', error);
|
|
367
384
|
} finally{
|
|
368
|
-
this.
|
|
385
|
+
this.setActiveAgent(null);
|
|
369
386
|
this._configDirty = false;
|
|
370
387
|
}
|
|
371
388
|
}
|
|
@@ -404,6 +421,7 @@ class PlaygroundServer {
|
|
|
404
421
|
executionHooks: session.executionHooks || this._baseExecutionHooks,
|
|
405
422
|
sidecars: sessionSidecars
|
|
406
423
|
};
|
|
424
|
+
this._mjpegHandler.reset();
|
|
407
425
|
this.sessionSetupState = 'ready';
|
|
408
426
|
this.sessionSetupBlockingReason = void 0;
|
|
409
427
|
this.syncRuntimeState();
|
|
@@ -461,7 +479,7 @@ class PlaygroundServer {
|
|
|
461
479
|
console.log('Recreating agent to cancel current task...');
|
|
462
480
|
await this.destroyCurrentAgent();
|
|
463
481
|
if (this._activeConnection.agentFactory) try {
|
|
464
|
-
this.
|
|
482
|
+
this.setActiveAgent(await this._activeConnection.agentFactory());
|
|
465
483
|
this._agentReady = true;
|
|
466
484
|
console.log('Agent recreated successfully');
|
|
467
485
|
} catch (error) {
|
|
@@ -478,7 +496,7 @@ class PlaygroundServer {
|
|
|
478
496
|
if (!this._activeConnection.agentFactory || !isRecoverablePageSessionError(error)) return null;
|
|
479
497
|
debugMjpeg(`Recovering active agent after ${reason}:`, error);
|
|
480
498
|
try {
|
|
481
|
-
this.
|
|
499
|
+
this._mjpegHandler.reset();
|
|
482
500
|
await this.recreateAgent();
|
|
483
501
|
return this._activeConnection.agent;
|
|
484
502
|
} catch (recreateError) {
|
|
@@ -552,7 +570,7 @@ class PlaygroundServer {
|
|
|
552
570
|
await this.destroyCurrentSession();
|
|
553
571
|
const created = await this.sessionManager.createSession(req.body || {});
|
|
554
572
|
await this.applyCreatedSession(created);
|
|
555
|
-
if (!this._activeConnection.agent && this._activeConnection.agentFactory) this.
|
|
573
|
+
if (!this._activeConnection.agent && this._activeConnection.agentFactory) this.setActiveAgent(await this._activeConnection.agentFactory());
|
|
556
574
|
if (this._configDirty && this._activeConnection.agentFactory) {
|
|
557
575
|
this._configDirty = false;
|
|
558
576
|
await this.recreateAgent();
|
|
@@ -684,7 +702,7 @@ class PlaygroundServer {
|
|
|
684
702
|
console.log('AI config changed, recreating agent...');
|
|
685
703
|
try {
|
|
686
704
|
await this.destroyCurrentAgent();
|
|
687
|
-
this.
|
|
705
|
+
this.setActiveAgent(await this._activeConnection.agentFactory());
|
|
688
706
|
agent = this.getActiveAgentOrThrow();
|
|
689
707
|
this._agentReady = true;
|
|
690
708
|
console.log('Agent recreated with new config');
|
|
@@ -854,19 +872,7 @@ class PlaygroundServer {
|
|
|
854
872
|
if (!agent) return res.status(409).json({
|
|
855
873
|
error: 'No active session'
|
|
856
874
|
});
|
|
857
|
-
|
|
858
|
-
const recentlyFailed = false === this._nativeMjpegAvailable && null !== this._nativeMjpegFailedAt && Date.now() - this._nativeMjpegFailedAt < PlaygroundServer.MJPEG_NEGATIVE_CACHE_MS;
|
|
859
|
-
if (nativeUrl && !recentlyFailed) {
|
|
860
|
-
const proxyOk = await this.probeAndProxyNativeMjpeg(nativeUrl, req, res);
|
|
861
|
-
if (proxyOk) return;
|
|
862
|
-
}
|
|
863
|
-
const interfaceStreamStarted = await this._interfaceMjpegHub.streamRequest(req, res, agent.interface, async (startupError)=>(await this.recoverActiveAgentAfterPreviewError(startupError, 'interface MJPEG startup'))?.interface ?? null);
|
|
864
|
-
if (interfaceStreamStarted) return;
|
|
865
|
-
const fallbackAgent = this._activeConnection.agent;
|
|
866
|
-
if ('function' != typeof fallbackAgent?.interface?.screenshotBase64) return res.status(500).json({
|
|
867
|
-
error: 'Screenshot method not available on current interface'
|
|
868
|
-
});
|
|
869
|
-
await this.startPollingMjpegStream(req, res);
|
|
875
|
+
await this._mjpegHandler.serve(req, res);
|
|
870
876
|
});
|
|
871
877
|
this._app.get('/interface-info', async (_req, res)=>{
|
|
872
878
|
try {
|
|
@@ -925,26 +931,26 @@ class PlaygroundServer {
|
|
|
925
931
|
if ('string' != typeof actionType || !actionType) return res.status(400).json({
|
|
926
932
|
error: 'actionType is required'
|
|
927
933
|
});
|
|
928
|
-
if (!this.findInteractAction(agent, actionType) && !this.canRunBrowserChromeInteractAction(agent, actionType)) return res.status(404).json({
|
|
929
|
-
error: `Action "${actionType}" is not available on the current device`
|
|
930
|
-
});
|
|
931
|
-
let params;
|
|
932
934
|
try {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
error: errorMessage
|
|
935
|
+
const inputPrimitives = agent.interface.inputPrimitives;
|
|
936
|
+
if (inputPrimitives) {
|
|
937
|
+
await (0, external_pointer_dispatch_js_namespaceObject.dispatchPointer)(inputPrimitives, req.body ?? {}, ()=>agent.interface.size());
|
|
938
|
+
res.json({});
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (!this.findInteractAction(agent, actionType) && !this.canRunBrowserChromeInteractAction(agent, actionType)) return res.status(404).json({
|
|
942
|
+
error: isPointerInteractActionType(actionType) ? 'Manual control is not supported on this device' : `Action "${actionType}" is not available on the current device`
|
|
942
943
|
});
|
|
943
|
-
|
|
944
|
-
try {
|
|
944
|
+
const params = buildInteractParams(actionType, req.body ?? {});
|
|
945
945
|
await this.runInteractAction(agent, actionType, params);
|
|
946
946
|
res.json({});
|
|
947
947
|
} catch (error) {
|
|
948
|
+
if (error instanceof external_pointer_dispatch_js_namespaceObject.PointerInputError) return res.status(error.statusCode).json({
|
|
949
|
+
error: error.message
|
|
950
|
+
});
|
|
951
|
+
if (error instanceof InteractParamsValidationError) return res.status(400).json({
|
|
952
|
+
error: error.message
|
|
953
|
+
});
|
|
948
954
|
const recoveredAgent = await this.recoverActiveAgentAfterPreviewError(error, `manual interact action "${actionType}"`);
|
|
949
955
|
if (recoveredAgent) return res.status(409).json({
|
|
950
956
|
error: 'The page session was closed and has been recreated. Please retry the action.'
|
|
@@ -1026,123 +1032,6 @@ class PlaygroundServer {
|
|
|
1026
1032
|
}
|
|
1027
1033
|
});
|
|
1028
1034
|
}
|
|
1029
|
-
probeAndProxyNativeMjpeg(nativeUrl, req, res) {
|
|
1030
|
-
return new Promise((resolve)=>{
|
|
1031
|
-
console.log(`MJPEG: trying native stream from ${nativeUrl}`);
|
|
1032
|
-
const proxyReq = external_node_http_default().get(nativeUrl, (proxyRes)=>{
|
|
1033
|
-
const statusCode = proxyRes.statusCode ?? 0;
|
|
1034
|
-
if (statusCode >= 400) {
|
|
1035
|
-
this._nativeMjpegAvailable = false;
|
|
1036
|
-
this._nativeMjpegFailedAt = Date.now();
|
|
1037
|
-
proxyRes.resume();
|
|
1038
|
-
debugMjpeg(`native stream returned HTTP ${statusCode}, using polling mode`);
|
|
1039
|
-
resolve(false);
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
this._nativeMjpegAvailable = true;
|
|
1043
|
-
this._nativeMjpegFailedAt = null;
|
|
1044
|
-
console.log('MJPEG: streaming via native WDA MJPEG server');
|
|
1045
|
-
const contentType = proxyRes.headers['content-type'];
|
|
1046
|
-
if (contentType) res.setHeader('Content-Type', contentType);
|
|
1047
|
-
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
1048
|
-
res.setHeader('Connection', 'keep-alive');
|
|
1049
|
-
proxyRes.pipe(res);
|
|
1050
|
-
req.on('close', ()=>proxyReq.destroy());
|
|
1051
|
-
resolve(true);
|
|
1052
|
-
});
|
|
1053
|
-
proxyReq.on('error', (err)=>{
|
|
1054
|
-
this._nativeMjpegAvailable = false;
|
|
1055
|
-
this._nativeMjpegFailedAt = Date.now();
|
|
1056
|
-
debugMjpeg(`MJPEG: native stream unavailable (${err.message}), using polling mode`);
|
|
1057
|
-
resolve(false);
|
|
1058
|
-
});
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
probeNativeMjpegLiveness(nativeUrl) {
|
|
1062
|
-
return new Promise((resolve)=>{
|
|
1063
|
-
const probe = external_node_http_default().get(nativeUrl, (probeRes)=>{
|
|
1064
|
-
const statusCode = probeRes.statusCode ?? 0;
|
|
1065
|
-
const reachable = statusCode >= 200 && statusCode < 400;
|
|
1066
|
-
probeRes.destroy();
|
|
1067
|
-
resolve(reachable);
|
|
1068
|
-
});
|
|
1069
|
-
probe.setTimeout(1000, ()=>{
|
|
1070
|
-
probe.destroy();
|
|
1071
|
-
resolve(false);
|
|
1072
|
-
});
|
|
1073
|
-
probe.on('error', ()=>resolve(false));
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
async startPollingMjpegStream(req, res) {
|
|
1077
|
-
const defaultMjpegFps = 10;
|
|
1078
|
-
const maxMjpegFps = 30;
|
|
1079
|
-
const maxErrorBackoffMs = 3000;
|
|
1080
|
-
const errorLogThreshold = 3;
|
|
1081
|
-
const nativeProbeIntervalMs = 3000;
|
|
1082
|
-
const parsedFps = Number(req.query.fps);
|
|
1083
|
-
const fps = Math.min(Math.max(Number.isNaN(parsedFps) ? defaultMjpegFps : parsedFps, 1), maxMjpegFps);
|
|
1084
|
-
const interval = Math.round(1000 / fps);
|
|
1085
|
-
const boundary = 'mjpeg-boundary';
|
|
1086
|
-
console.log(`MJPEG: streaming via polling mode (${fps}fps)`);
|
|
1087
|
-
res.setHeader('Content-Type', `multipart/x-mixed-replace; boundary=${boundary}`);
|
|
1088
|
-
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
|
1089
|
-
res.setHeader('Connection', 'keep-alive');
|
|
1090
|
-
let stopped = false;
|
|
1091
|
-
let consecutiveErrors = 0;
|
|
1092
|
-
const nativeUrl = this._activeConnection.agent?.interface?.mjpegStreamUrl;
|
|
1093
|
-
let probeTimer;
|
|
1094
|
-
if (nativeUrl) probeTimer = setInterval(async ()=>{
|
|
1095
|
-
if (stopped) return;
|
|
1096
|
-
const reachable = await this.probeNativeMjpegLiveness(nativeUrl);
|
|
1097
|
-
if (reachable && !stopped) {
|
|
1098
|
-
console.log('MJPEG: native stream came online, ending polling so client reconnects');
|
|
1099
|
-
this._nativeMjpegAvailable = true;
|
|
1100
|
-
this._nativeMjpegFailedAt = null;
|
|
1101
|
-
stopped = true;
|
|
1102
|
-
try {
|
|
1103
|
-
res.destroy();
|
|
1104
|
-
} catch {}
|
|
1105
|
-
}
|
|
1106
|
-
}, nativeProbeIntervalMs);
|
|
1107
|
-
req.on('close', ()=>{
|
|
1108
|
-
stopped = true;
|
|
1109
|
-
if (probeTimer) clearInterval(probeTimer);
|
|
1110
|
-
});
|
|
1111
|
-
while(!stopped){
|
|
1112
|
-
if (!this._agentReady) {
|
|
1113
|
-
await new Promise((r)=>setTimeout(r, 200));
|
|
1114
|
-
continue;
|
|
1115
|
-
}
|
|
1116
|
-
const frameStart = Date.now();
|
|
1117
|
-
try {
|
|
1118
|
-
const agent = this.getActiveAgentOrThrow();
|
|
1119
|
-
const base64 = await agent.interface.screenshotBase64();
|
|
1120
|
-
if (stopped) break;
|
|
1121
|
-
consecutiveErrors = 0;
|
|
1122
|
-
(0, external_mjpeg_hub_js_namespaceObject.writeMjpegFrame)(res, boundary, {
|
|
1123
|
-
data: base64,
|
|
1124
|
-
contentType: 'image/jpeg'
|
|
1125
|
-
});
|
|
1126
|
-
} catch (err) {
|
|
1127
|
-
if (stopped) break;
|
|
1128
|
-
const recoveredAgent = await this.recoverActiveAgentAfterPreviewError(err, 'polling MJPEG frame capture');
|
|
1129
|
-
if (recoveredAgent) {
|
|
1130
|
-
consecutiveErrors = 0;
|
|
1131
|
-
continue;
|
|
1132
|
-
}
|
|
1133
|
-
consecutiveErrors++;
|
|
1134
|
-
if (consecutiveErrors <= errorLogThreshold) console.error('MJPEG frame error:', err);
|
|
1135
|
-
else if (consecutiveErrors === errorLogThreshold + 1) console.error('MJPEG: suppressing further errors, retrying silently...');
|
|
1136
|
-
const backoff = Math.min(1000 * consecutiveErrors, maxErrorBackoffMs);
|
|
1137
|
-
await new Promise((r)=>setTimeout(r, backoff));
|
|
1138
|
-
continue;
|
|
1139
|
-
}
|
|
1140
|
-
const elapsed = Date.now() - frameStart;
|
|
1141
|
-
const remaining = interval - elapsed;
|
|
1142
|
-
if (remaining > 0) await new Promise((r)=>setTimeout(r, remaining));
|
|
1143
|
-
}
|
|
1144
|
-
if (probeTimer) clearInterval(probeTimer);
|
|
1145
|
-
}
|
|
1146
1035
|
setupStaticRoutes() {
|
|
1147
1036
|
this._app.get('/', (_req, res)=>{
|
|
1148
1037
|
this.serveHtmlWithPorts(res);
|
|
@@ -1176,7 +1065,7 @@ class PlaygroundServer {
|
|
|
1176
1065
|
async launch(port) {
|
|
1177
1066
|
if (this._activeConnection.agentFactory && !this.sessionManager) {
|
|
1178
1067
|
console.log('Initializing agent from factory function...');
|
|
1179
|
-
this.
|
|
1068
|
+
this.setActiveAgent(await this._activeConnection.agentFactory());
|
|
1180
1069
|
this._activeConnection.session = {
|
|
1181
1070
|
connected: true,
|
|
1182
1071
|
metadata: {}
|
|
@@ -1198,6 +1087,7 @@ class PlaygroundServer {
|
|
|
1198
1087
|
await this.destroyCurrentSession().catch((error)=>{
|
|
1199
1088
|
console.warn('Failed to destroy current session during shutdown:', error);
|
|
1200
1089
|
});
|
|
1090
|
+
this._mjpegHandler.shutdown();
|
|
1201
1091
|
return new Promise((resolve, reject)=>{
|
|
1202
1092
|
if (this.server) {
|
|
1203
1093
|
this.taskExecutionDumps = {};
|
|
@@ -1221,12 +1111,13 @@ class PlaygroundServer {
|
|
|
1221
1111
|
_define_property(this, "id", void 0);
|
|
1222
1112
|
_define_property(this, "scrcpyPort", void 0);
|
|
1223
1113
|
_define_property(this, "_initialized", false);
|
|
1224
|
-
_define_property(this, "
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1114
|
+
_define_property(this, "_mjpegHandler", new external_mjpeg_stream_handler_js_namespaceObject.MjpegStreamHandler({
|
|
1115
|
+
getNativeUrl: ()=>this._activeConnection.agent?.interface?.mjpegStreamUrl,
|
|
1116
|
+
getActiveInterface: ()=>this._activeConnection.agent?.interface ?? null,
|
|
1117
|
+
takeScreenshot: ()=>this.getActiveAgentOrThrow().interface.screenshotBase64(),
|
|
1118
|
+
canTakeScreenshot: ()=>'function' == typeof this._activeConnection.agent?.interface?.screenshotBase64,
|
|
1119
|
+
isAgentReady: ()=>this._agentReady,
|
|
1120
|
+
recoverFromPreviewError: async (error, reason)=>(await this.recoverActiveAgentAfterPreviewError(error, reason))?.interface ?? null
|
|
1230
1121
|
}));
|
|
1231
1122
|
_define_property(this, "sessionManager", void 0);
|
|
1232
1123
|
_define_property(this, "sessionSetupState", 'ready');
|
|
@@ -1253,12 +1144,9 @@ class PlaygroundServer {
|
|
|
1253
1144
|
this.taskExecutionDumps = {};
|
|
1254
1145
|
this.id = id || (0, shared_utils_namespaceObject.uuid)();
|
|
1255
1146
|
if ('function' == typeof agent) this._activeConnection.agentFactory = agent;
|
|
1256
|
-
else this.
|
|
1147
|
+
else this.setActiveAgent(agent || null);
|
|
1257
1148
|
}
|
|
1258
1149
|
}
|
|
1259
|
-
_define_property(PlaygroundServer, "MJPEG_NEGATIVE_CACHE_MS", 10000);
|
|
1260
|
-
_define_property(PlaygroundServer, "INTERFACE_MJPEG_INITIAL_FRAME_TIMEOUT_MS", 1500);
|
|
1261
|
-
_define_property(PlaygroundServer, "INTERFACE_MJPEG_IDLE_STOP_MS", 2000);
|
|
1262
1150
|
const server = PlaygroundServer;
|
|
1263
1151
|
exports.InteractParamsValidationError = __webpack_exports__.InteractParamsValidationError;
|
|
1264
1152
|
exports.PlaygroundServer = __webpack_exports__.PlaygroundServer;
|