@midscene/android-playground 1.12.7-beta-20260914023554.0 → 1.12.7

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/bin.mjs CHANGED
@@ -184,9 +184,67 @@ function _define_property(obj, key, value) {
184
184
  else obj[key] = value;
185
185
  return obj;
186
186
  }
187
+ const SCRCPY_MAX_IN_FLIGHT_BYTES = 8388608;
188
+ const SCRCPY_MAX_IN_FLIGHT_PACKETS = 256;
189
+ const SCRCPY_VIDEO_ACK_TIMEOUT_MS = 10000;
190
+ const debug = getDebug('android:playground:video', {
191
+ console: true
192
+ });
193
+ function buildScrcpyVideoPacket(packet, timestamp = Date.now()) {
194
+ return {
195
+ data: packet.data,
196
+ type: packet.type,
197
+ timestamp,
198
+ keyFrame: 'data' === packet.type ? packet.keyframe : void 0
199
+ };
200
+ }
201
+ class ScrcpyVideoSender {
202
+ fail(message) {
203
+ if (this.failed) return;
204
+ this.failed = true;
205
+ debug(message);
206
+ this.socket.conn.close(true);
207
+ }
208
+ send(packet) {
209
+ if (this.failed || !this.socket.connected) throw new Error('Cannot send video on a closed scrcpy connection');
210
+ const bytes = packet.data.byteLength;
211
+ if (this.inFlightPackets >= SCRCPY_MAX_IN_FLIGHT_PACKETS || this.inFlightBytes + bytes > SCRCPY_MAX_IN_FLIGHT_BYTES) {
212
+ const message = 'Scrcpy video receiver is too slow; reconnecting preview';
213
+ this.fail(message);
214
+ throw new Error(message);
215
+ }
216
+ this.inFlightBytes += bytes;
217
+ this.inFlightPackets += 1;
218
+ this.socket.timeout(SCRCPY_VIDEO_ACK_TIMEOUT_MS).emit('video-data', buildScrcpyVideoPacket(packet), (error)=>{
219
+ this.inFlightBytes -= bytes;
220
+ this.inFlightPackets -= 1;
221
+ if (error && this.socket.connected) this.fail('Scrcpy video acknowledgement timed out; reconnecting preview');
222
+ });
223
+ }
224
+ constructor(socket){
225
+ _define_property(this, "socket", void 0);
226
+ _define_property(this, "inFlightBytes", void 0);
227
+ _define_property(this, "inFlightPackets", void 0);
228
+ _define_property(this, "failed", void 0);
229
+ this.socket = socket;
230
+ this.inFlightBytes = 0;
231
+ this.inFlightPackets = 0;
232
+ this.failed = false;
233
+ }
234
+ }
235
+ function timeout_define_property(obj, key, value) {
236
+ if (key in obj) Object.defineProperty(obj, key, {
237
+ value: value,
238
+ enumerable: true,
239
+ configurable: true,
240
+ writable: true
241
+ });
242
+ else obj[key] = value;
243
+ return obj;
244
+ }
187
245
  class PromiseTimeoutError extends Error {
188
246
  constructor(message, timeoutMs){
189
- super(message), _define_property(this, "timeoutMs", void 0);
247
+ super(message), timeout_define_property(this, "timeoutMs", void 0);
190
248
  this.name = 'PromiseTimeoutError';
191
249
  this.timeoutMs = timeoutMs;
192
250
  }
@@ -410,6 +468,7 @@ class ScrcpyServer {
410
468
  let activeSession = null;
411
469
  let sessionGeneration = 0;
412
470
  let adb = null;
471
+ const videoSender = new ScrcpyVideoSender(socket);
413
472
  const closeScrcpySession = async (reason, sessionToClose = activeSession)=>{
414
473
  if (!sessionToClose) return;
415
474
  sessionToClose.closeReason ??= reason;
@@ -567,13 +626,7 @@ class ScrcpyServer {
567
626
  const { done, value } = await reader.read();
568
627
  if (done) break;
569
628
  if (!isCurrentGeneration() || activeSession !== streamSession) return;
570
- const frameType = value.type || 'data';
571
- socket.volatile.emit('video-data', {
572
- data: value.data,
573
- type: frameType,
574
- timestamp: Date.now(),
575
- keyFrame: value.keyFrame
576
- });
629
+ videoSender.send(value);
577
630
  }
578
631
  } catch (error) {
579
632
  console.error('error processing video stream:', error);
package/dist/es/index.mjs CHANGED
@@ -184,9 +184,67 @@ function _define_property(obj, key, value) {
184
184
  else obj[key] = value;
185
185
  return obj;
186
186
  }
187
+ const SCRCPY_MAX_IN_FLIGHT_BYTES = 8388608;
188
+ const SCRCPY_MAX_IN_FLIGHT_PACKETS = 256;
189
+ const SCRCPY_VIDEO_ACK_TIMEOUT_MS = 10000;
190
+ const debug = getDebug('android:playground:video', {
191
+ console: true
192
+ });
193
+ function buildScrcpyVideoPacket(packet, timestamp = Date.now()) {
194
+ return {
195
+ data: packet.data,
196
+ type: packet.type,
197
+ timestamp,
198
+ keyFrame: 'data' === packet.type ? packet.keyframe : void 0
199
+ };
200
+ }
201
+ class ScrcpyVideoSender {
202
+ fail(message) {
203
+ if (this.failed) return;
204
+ this.failed = true;
205
+ debug(message);
206
+ this.socket.conn.close(true);
207
+ }
208
+ send(packet) {
209
+ if (this.failed || !this.socket.connected) throw new Error('Cannot send video on a closed scrcpy connection');
210
+ const bytes = packet.data.byteLength;
211
+ if (this.inFlightPackets >= SCRCPY_MAX_IN_FLIGHT_PACKETS || this.inFlightBytes + bytes > SCRCPY_MAX_IN_FLIGHT_BYTES) {
212
+ const message = 'Scrcpy video receiver is too slow; reconnecting preview';
213
+ this.fail(message);
214
+ throw new Error(message);
215
+ }
216
+ this.inFlightBytes += bytes;
217
+ this.inFlightPackets += 1;
218
+ this.socket.timeout(SCRCPY_VIDEO_ACK_TIMEOUT_MS).emit('video-data', buildScrcpyVideoPacket(packet), (error)=>{
219
+ this.inFlightBytes -= bytes;
220
+ this.inFlightPackets -= 1;
221
+ if (error && this.socket.connected) this.fail('Scrcpy video acknowledgement timed out; reconnecting preview');
222
+ });
223
+ }
224
+ constructor(socket){
225
+ _define_property(this, "socket", void 0);
226
+ _define_property(this, "inFlightBytes", void 0);
227
+ _define_property(this, "inFlightPackets", void 0);
228
+ _define_property(this, "failed", void 0);
229
+ this.socket = socket;
230
+ this.inFlightBytes = 0;
231
+ this.inFlightPackets = 0;
232
+ this.failed = false;
233
+ }
234
+ }
235
+ function timeout_define_property(obj, key, value) {
236
+ if (key in obj) Object.defineProperty(obj, key, {
237
+ value: value,
238
+ enumerable: true,
239
+ configurable: true,
240
+ writable: true
241
+ });
242
+ else obj[key] = value;
243
+ return obj;
244
+ }
187
245
  class PromiseTimeoutError extends Error {
188
246
  constructor(message, timeoutMs){
189
- super(message), _define_property(this, "timeoutMs", void 0);
247
+ super(message), timeout_define_property(this, "timeoutMs", void 0);
190
248
  this.name = 'PromiseTimeoutError';
191
249
  this.timeoutMs = timeoutMs;
192
250
  }
@@ -410,6 +468,7 @@ class ScrcpyServer {
410
468
  let activeSession = null;
411
469
  let sessionGeneration = 0;
412
470
  let adb = null;
471
+ const videoSender = new ScrcpyVideoSender(socket);
413
472
  const closeScrcpySession = async (reason, sessionToClose = activeSession)=>{
414
473
  if (!sessionToClose) return;
415
474
  sessionToClose.closeReason ??= reason;
@@ -567,13 +626,7 @@ class ScrcpyServer {
567
626
  const { done, value } = await reader.read();
568
627
  if (done) break;
569
628
  if (!isCurrentGeneration() || activeSession !== streamSession) return;
570
- const frameType = value.type || 'data';
571
- socket.volatile.emit('video-data', {
572
- data: value.data,
573
- type: frameType,
574
- timestamp: Date.now(),
575
- keyFrame: value.keyFrame
576
- });
629
+ videoSender.send(value);
577
630
  }
578
631
  } catch (error) {
579
632
  console.error('error processing video stream:', error);
package/dist/lib/bin.js CHANGED
@@ -210,9 +210,67 @@ function _define_property(obj, key, value) {
210
210
  else obj[key] = value;
211
211
  return obj;
212
212
  }
213
+ const SCRCPY_MAX_IN_FLIGHT_BYTES = 8388608;
214
+ const SCRCPY_MAX_IN_FLIGHT_PACKETS = 256;
215
+ const SCRCPY_VIDEO_ACK_TIMEOUT_MS = 10000;
216
+ const debug = (0, logger_namespaceObject.getDebug)('android:playground:video', {
217
+ console: true
218
+ });
219
+ function buildScrcpyVideoPacket(packet, timestamp = Date.now()) {
220
+ return {
221
+ data: packet.data,
222
+ type: packet.type,
223
+ timestamp,
224
+ keyFrame: 'data' === packet.type ? packet.keyframe : void 0
225
+ };
226
+ }
227
+ class ScrcpyVideoSender {
228
+ fail(message) {
229
+ if (this.failed) return;
230
+ this.failed = true;
231
+ debug(message);
232
+ this.socket.conn.close(true);
233
+ }
234
+ send(packet) {
235
+ if (this.failed || !this.socket.connected) throw new Error('Cannot send video on a closed scrcpy connection');
236
+ const bytes = packet.data.byteLength;
237
+ if (this.inFlightPackets >= SCRCPY_MAX_IN_FLIGHT_PACKETS || this.inFlightBytes + bytes > SCRCPY_MAX_IN_FLIGHT_BYTES) {
238
+ const message = 'Scrcpy video receiver is too slow; reconnecting preview';
239
+ this.fail(message);
240
+ throw new Error(message);
241
+ }
242
+ this.inFlightBytes += bytes;
243
+ this.inFlightPackets += 1;
244
+ this.socket.timeout(SCRCPY_VIDEO_ACK_TIMEOUT_MS).emit('video-data', buildScrcpyVideoPacket(packet), (error)=>{
245
+ this.inFlightBytes -= bytes;
246
+ this.inFlightPackets -= 1;
247
+ if (error && this.socket.connected) this.fail('Scrcpy video acknowledgement timed out; reconnecting preview');
248
+ });
249
+ }
250
+ constructor(socket){
251
+ _define_property(this, "socket", void 0);
252
+ _define_property(this, "inFlightBytes", void 0);
253
+ _define_property(this, "inFlightPackets", void 0);
254
+ _define_property(this, "failed", void 0);
255
+ this.socket = socket;
256
+ this.inFlightBytes = 0;
257
+ this.inFlightPackets = 0;
258
+ this.failed = false;
259
+ }
260
+ }
261
+ function timeout_define_property(obj, key, value) {
262
+ if (key in obj) Object.defineProperty(obj, key, {
263
+ value: value,
264
+ enumerable: true,
265
+ configurable: true,
266
+ writable: true
267
+ });
268
+ else obj[key] = value;
269
+ return obj;
270
+ }
213
271
  class PromiseTimeoutError extends Error {
214
272
  constructor(message, timeoutMs){
215
- super(message), _define_property(this, "timeoutMs", void 0);
273
+ super(message), timeout_define_property(this, "timeoutMs", void 0);
216
274
  this.name = 'PromiseTimeoutError';
217
275
  this.timeoutMs = timeoutMs;
218
276
  }
@@ -436,6 +494,7 @@ class ScrcpyServer {
436
494
  let activeSession = null;
437
495
  let sessionGeneration = 0;
438
496
  let adb = null;
497
+ const videoSender = new ScrcpyVideoSender(socket);
439
498
  const closeScrcpySession = async (reason, sessionToClose = activeSession)=>{
440
499
  if (!sessionToClose) return;
441
500
  sessionToClose.closeReason ??= reason;
@@ -593,13 +652,7 @@ class ScrcpyServer {
593
652
  const { done, value } = await reader.read();
594
653
  if (done) break;
595
654
  if (!isCurrentGeneration() || activeSession !== streamSession) return;
596
- const frameType = value.type || 'data';
597
- socket.volatile.emit('video-data', {
598
- data: value.data,
599
- type: frameType,
600
- timestamp: Date.now(),
601
- keyFrame: value.keyFrame
602
- });
655
+ videoSender.send(value);
603
656
  }
604
657
  } catch (error) {
605
658
  console.error('error processing video stream:', error);
package/dist/lib/index.js CHANGED
@@ -225,9 +225,67 @@ function _define_property(obj, key, value) {
225
225
  else obj[key] = value;
226
226
  return obj;
227
227
  }
228
+ const SCRCPY_MAX_IN_FLIGHT_BYTES = 8388608;
229
+ const SCRCPY_MAX_IN_FLIGHT_PACKETS = 256;
230
+ const SCRCPY_VIDEO_ACK_TIMEOUT_MS = 10000;
231
+ const debug = (0, logger_namespaceObject.getDebug)('android:playground:video', {
232
+ console: true
233
+ });
234
+ function buildScrcpyVideoPacket(packet, timestamp = Date.now()) {
235
+ return {
236
+ data: packet.data,
237
+ type: packet.type,
238
+ timestamp,
239
+ keyFrame: 'data' === packet.type ? packet.keyframe : void 0
240
+ };
241
+ }
242
+ class ScrcpyVideoSender {
243
+ fail(message) {
244
+ if (this.failed) return;
245
+ this.failed = true;
246
+ debug(message);
247
+ this.socket.conn.close(true);
248
+ }
249
+ send(packet) {
250
+ if (this.failed || !this.socket.connected) throw new Error('Cannot send video on a closed scrcpy connection');
251
+ const bytes = packet.data.byteLength;
252
+ if (this.inFlightPackets >= SCRCPY_MAX_IN_FLIGHT_PACKETS || this.inFlightBytes + bytes > SCRCPY_MAX_IN_FLIGHT_BYTES) {
253
+ const message = 'Scrcpy video receiver is too slow; reconnecting preview';
254
+ this.fail(message);
255
+ throw new Error(message);
256
+ }
257
+ this.inFlightBytes += bytes;
258
+ this.inFlightPackets += 1;
259
+ this.socket.timeout(SCRCPY_VIDEO_ACK_TIMEOUT_MS).emit('video-data', buildScrcpyVideoPacket(packet), (error)=>{
260
+ this.inFlightBytes -= bytes;
261
+ this.inFlightPackets -= 1;
262
+ if (error && this.socket.connected) this.fail('Scrcpy video acknowledgement timed out; reconnecting preview');
263
+ });
264
+ }
265
+ constructor(socket){
266
+ _define_property(this, "socket", void 0);
267
+ _define_property(this, "inFlightBytes", void 0);
268
+ _define_property(this, "inFlightPackets", void 0);
269
+ _define_property(this, "failed", void 0);
270
+ this.socket = socket;
271
+ this.inFlightBytes = 0;
272
+ this.inFlightPackets = 0;
273
+ this.failed = false;
274
+ }
275
+ }
276
+ function timeout_define_property(obj, key, value) {
277
+ if (key in obj) Object.defineProperty(obj, key, {
278
+ value: value,
279
+ enumerable: true,
280
+ configurable: true,
281
+ writable: true
282
+ });
283
+ else obj[key] = value;
284
+ return obj;
285
+ }
228
286
  class PromiseTimeoutError extends Error {
229
287
  constructor(message, timeoutMs){
230
- super(message), _define_property(this, "timeoutMs", void 0);
288
+ super(message), timeout_define_property(this, "timeoutMs", void 0);
231
289
  this.name = 'PromiseTimeoutError';
232
290
  this.timeoutMs = timeoutMs;
233
291
  }
@@ -451,6 +509,7 @@ class ScrcpyServer {
451
509
  let activeSession = null;
452
510
  let sessionGeneration = 0;
453
511
  let adb = null;
512
+ const videoSender = new ScrcpyVideoSender(socket);
454
513
  const closeScrcpySession = async (reason, sessionToClose = activeSession)=>{
455
514
  if (!sessionToClose) return;
456
515
  sessionToClose.closeReason ??= reason;
@@ -608,13 +667,7 @@ class ScrcpyServer {
608
667
  const { done, value } = await reader.read();
609
668
  if (done) break;
610
669
  if (!isCurrentGeneration() || activeSession !== streamSession) return;
611
- const frameType = value.type || 'data';
612
- socket.volatile.emit('video-data', {
613
- data: value.data,
614
- type: frameType,
615
- timestamp: Date.now(),
616
- keyFrame: value.keyFrame
617
- });
670
+ videoSender.send(value);
618
671
  }
619
672
  } catch (error) {
620
673
  console.error('error processing video stream:', error);
@@ -0,0 +1,20 @@
1
+ import type { ScrcpyMediaStreamPacket } from '@yume-chan/scrcpy';
2
+ import type { Socket } from 'socket.io';
3
+ export declare const SCRCPY_MAX_IN_FLIGHT_BYTES: number;
4
+ export declare const SCRCPY_MAX_IN_FLIGHT_PACKETS = 256;
5
+ export declare const SCRCPY_VIDEO_ACK_TIMEOUT_MS = 10000;
6
+ export declare function buildScrcpyVideoPacket(packet: ScrcpyMediaStreamPacket, timestamp?: number): {
7
+ data: Uint8Array<ArrayBufferLike>;
8
+ type: "configuration" | "data";
9
+ timestamp: number;
10
+ keyFrame: boolean | undefined;
11
+ };
12
+ export declare class ScrcpyVideoSender {
13
+ private readonly socket;
14
+ private inFlightBytes;
15
+ private inFlightPackets;
16
+ private failed;
17
+ constructor(socket: Socket);
18
+ private fail;
19
+ send(packet: ScrcpyMediaStreamPacket): void;
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/android-playground",
3
- "version": "1.12.7-beta-20260914023554.0",
3
+ "version": "1.12.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/midscene.git",
@@ -39,10 +39,10 @@
39
39
  "express": "^4.21.2",
40
40
  "open": "10.1.0",
41
41
  "socket.io": "^4.8.1",
42
- "@midscene/core": "1.12.7-beta-20260914023554.0",
43
- "@midscene/android": "1.12.7-beta-20260914023554.0",
44
- "@midscene/shared": "1.12.7-beta-20260914023554.0",
45
- "@midscene/playground": "1.12.7-beta-20260914023554.0"
42
+ "@midscene/android": "1.12.7",
43
+ "@midscene/core": "1.12.7",
44
+ "@midscene/playground": "1.12.7",
45
+ "@midscene/shared": "1.12.7"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@rslib/core": "^0.18.3",
@@ -50,6 +50,7 @@
50
50
  "@types/cors": "^2.8.17",
51
51
  "@types/express": "^4.17.21",
52
52
  "@types/node": "^18.0.0",
53
+ "socket.io-client": "4.8.1",
53
54
  "typescript": "^5.8.3"
54
55
  },
55
56
  "license": "MIT",
package/static/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html><head><title>Midscene Android Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.574e3de9.js"></script><script defer src="/static/js/415.dadb20cf.js"></script><script defer src="/static/js/index.0ce47ddb.js"></script><link href="/static/css/index.67caac18.css" rel="stylesheet"></head><body><div id="root"></div></body></html>
1
+ <!doctype html><html><head><title>Midscene Android Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.574e3de9.js"></script><script defer src="/static/js/415.dadb20cf.js"></script><script defer src="/static/js/index.6736e95a.js"></script><link href="/static/css/index.67caac18.css" rel="stylesheet"></head><body><div id="root"></div></body></html>