@midscene/android 1.12.1-beta-20260827032340.0 → 1.12.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/cli.mjs CHANGED
@@ -32,10 +32,11 @@ var __webpack_modules__ = {
32
32
  ScrcpyScreenshotManager: ()=>ScrcpyScreenshotManager,
33
33
  ov: ()=>DEFAULT_SCRCPY_CONFIG
34
34
  });
35
- var node_module__rspack_import_0 = __webpack_require__("node:module");
36
- var node_path__rspack_import_1 = __webpack_require__("node:path");
37
- var _midscene_shared_logger__rspack_import_2 = __webpack_require__("@midscene/shared/logger");
38
- var _resource_path__rspack_import_3 = __webpack_require__("./src/resource-path.ts");
35
+ var node_fs__rspack_import_0 = __webpack_require__("node:fs");
36
+ var node_module__rspack_import_1 = __webpack_require__("node:module");
37
+ var node_path__rspack_import_2 = __webpack_require__("node:path");
38
+ var _midscene_shared_logger__rspack_import_3 = __webpack_require__("@midscene/shared/logger");
39
+ var _resource_path__rspack_import_4 = __webpack_require__("./src/resource-path.ts");
39
40
  function _define_property(obj, key, value) {
40
41
  if (key in obj) Object.defineProperty(obj, key, {
41
42
  value: value,
@@ -46,8 +47,8 @@ var __webpack_modules__ = {
46
47
  else obj[key] = value;
47
48
  return obj;
48
49
  }
49
- const debugScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy');
50
- const warnScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy', {
50
+ const debugScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy');
51
+ const warnScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy', {
51
52
  console: true
52
53
  });
53
54
  const NAL_TYPE_IDR = 5;
@@ -146,9 +147,10 @@ var __webpack_modules__ = {
146
147
  try {
147
148
  debugScrcpy('Starting scrcpy connection...');
148
149
  const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
150
+ const { ReadableStream } = await import("@yume-chan/stream-extra");
149
151
  const { DefaultServerPath } = await import("@yume-chan/scrcpy");
150
152
  const serverBinPath = this.resolveServerBinPath();
151
- await this.pushServer(serverBinPath, DefaultServerPath);
153
+ await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
152
154
  const scrcpyOptions = await this.createScrcpyOptions();
153
155
  await this.ensureFrameClockCalibration();
154
156
  this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
@@ -232,12 +234,12 @@ var __webpack_modules__ = {
232
234
  return output.filter((line)=>'string' == typeof line);
233
235
  }
234
236
  resolveServerBinPath() {
235
- const androidPkgJson = (0, node_module__rspack_import_0.createRequire)(import.meta.url).resolve('@midscene/android/package.json');
236
- return (0, _resource_path__rspack_import_3.J)(node_path__rspack_import_1["default"].join(node_path__rspack_import_1["default"].dirname(androidPkgJson), 'bin', 'scrcpy-server'));
237
+ const androidPkgJson = (0, node_module__rspack_import_1.createRequire)(import.meta.url).resolve('@midscene/android/package.json');
238
+ return (0, _resource_path__rspack_import_4.J)(node_path__rspack_import_2["default"].join(node_path__rspack_import_2["default"].dirname(androidPkgJson), 'bin', 'scrcpy-server'));
237
239
  }
238
240
  getFfmpegPath() {
239
241
  try {
240
- const dynamicRequire = (0, node_module__rspack_import_0.createRequire)(import.meta.url);
242
+ const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(import.meta.url);
241
243
  const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
242
244
  debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
243
245
  return ffmpegInstaller.path;
@@ -776,63 +778,36 @@ var __webpack_modules__ = {
776
778
  isConnected() {
777
779
  return this.isInitialized && null !== this.scrcpyClient;
778
780
  }
779
- constructor(adb, pushServer, options = {}){
780
- _define_property(this, "pushServer", void 0);
781
+ constructor(adb, options = {}){
781
782
  _define_property(this, "adb", void 0);
782
- _define_property(this, "scrcpyClient", void 0);
783
- _define_property(this, "videoStream", void 0);
784
- _define_property(this, "spsHeader", void 0);
785
- _define_property(this, "idleTimer", void 0);
786
- _define_property(this, "connectionPromise", void 0);
787
- _define_property(this, "disposed", void 0);
788
- _define_property(this, "isInitialized", void 0);
783
+ _define_property(this, "scrcpyClient", null);
784
+ _define_property(this, "videoStream", null);
785
+ _define_property(this, "spsHeader", null);
786
+ _define_property(this, "idleTimer", null);
787
+ _define_property(this, "connectionPromise", null);
788
+ _define_property(this, "disposed", false);
789
+ _define_property(this, "isInitialized", false);
789
790
  _define_property(this, "options", void 0);
790
- _define_property(this, "ffmpegAvailable", void 0);
791
- _define_property(this, "keyframeResolvers", void 0);
792
- _define_property(this, "keyframeListeners", void 0);
793
- _define_property(this, "lastRawKeyframe", void 0);
794
- _define_property(this, "lastRawKeyframeAt", void 0);
791
+ _define_property(this, "ffmpegAvailable", null);
792
+ _define_property(this, "keyframeResolvers", []);
793
+ _define_property(this, "keyframeListeners", new Set());
794
+ _define_property(this, "lastRawKeyframe", null);
795
+ _define_property(this, "lastRawKeyframeAt", 0);
795
796
  _define_property(this, "lastRawKeyframePtsUs", void 0);
796
797
  _define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
797
- _define_property(this, "videoResolution", void 0);
798
- _define_property(this, "streamReader", void 0);
799
- _define_property(this, "frameFreshnessBarrierPtsUs", void 0);
800
- _define_property(this, "frameFreshnessBarrierReason", void 0);
801
- _define_property(this, "streamStartupWindow", void 0);
802
- _define_property(this, "frameFreshnessBarrierPending", void 0);
803
- _define_property(this, "frameFreshnessBarrierGeneration", void 0);
804
- _define_property(this, "deviceClockCalibration", void 0);
805
- _define_property(this, "deviceClockCalibrationPromise", void 0);
806
- _define_property(this, "lastFramePtsUs", void 0);
807
- _define_property(this, "frameFreshnessError", void 0);
808
- _define_property(this, "lastFrameFreshnessWarningAt", void 0);
809
- _define_property(this, "disposePromise", void 0);
810
- this.pushServer = pushServer;
811
- this.scrcpyClient = null;
812
- this.videoStream = null;
813
- this.spsHeader = null;
814
- this.idleTimer = null;
815
- this.connectionPromise = null;
816
- this.disposed = false;
817
- this.isInitialized = false;
818
- this.ffmpegAvailable = null;
819
- this.keyframeResolvers = [];
820
- this.keyframeListeners = new Set();
821
- this.lastRawKeyframe = null;
822
- this.lastRawKeyframeAt = 0;
823
- this.videoResolution = null;
824
- this.streamReader = null;
825
- this.frameFreshnessBarrierPtsUs = null;
826
- this.frameFreshnessBarrierReason = null;
827
- this.streamStartupWindow = null;
828
- this.frameFreshnessBarrierPending = false;
829
- this.frameFreshnessBarrierGeneration = 0;
830
- this.deviceClockCalibration = null;
831
- this.deviceClockCalibrationPromise = null;
832
- this.lastFramePtsUs = null;
833
- this.frameFreshnessError = null;
834
- this.lastFrameFreshnessWarningAt = 0;
835
- this.disposePromise = null;
798
+ _define_property(this, "videoResolution", null);
799
+ _define_property(this, "streamReader", null);
800
+ _define_property(this, "frameFreshnessBarrierPtsUs", null);
801
+ _define_property(this, "frameFreshnessBarrierReason", null);
802
+ _define_property(this, "streamStartupWindow", null);
803
+ _define_property(this, "frameFreshnessBarrierPending", false);
804
+ _define_property(this, "frameFreshnessBarrierGeneration", 0);
805
+ _define_property(this, "deviceClockCalibration", null);
806
+ _define_property(this, "deviceClockCalibrationPromise", null);
807
+ _define_property(this, "lastFramePtsUs", null);
808
+ _define_property(this, "frameFreshnessError", null);
809
+ _define_property(this, "lastFrameFreshnessWarningAt", 0);
810
+ _define_property(this, "disposePromise", null);
836
811
  this.adb = adb;
837
812
  const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
838
813
  const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
@@ -1068,6 +1043,10 @@ function formatScrcpyFreshFrameFailure(error) {
1068
1043
  const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
1069
1044
  return `No usable scrcpy frame crossed the active freshness target within ${timeoutMs}ms. This can happen when a static screen emits no new encoded frame, or when the video stream or transport is interrupted. This timeout does not by itself identify bandwidth or the configured video bitrate as the cause.${bitRateDescription}`;
1070
1045
  }
1046
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
1047
+ host: '127.0.0.1',
1048
+ port: 5037
1049
+ };
1071
1050
  class ScrcpyDeviceAdapter {
1072
1051
  isEnabled() {
1073
1052
  if (!this.isConfigured()) return false;
@@ -1132,18 +1111,13 @@ class ScrcpyDeviceAdapter {
1132
1111
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
1133
1112
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
1134
1113
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
1135
- const adbBackend = await this.resolveAdbBackend();
1136
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
1137
- host: adbBackend.adbHost ?? '127.0.0.1',
1138
- port: adbBackend.adbPort ?? 5037
1139
- }));
1114
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
1115
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
1140
1116
  adb = new Adb(await adbClient.createTransport({
1141
1117
  serial: this.deviceId
1142
1118
  }));
1143
1119
  const config = this.resolveConfig();
1144
- manager = new ScrcpyManager(adb, async (localPath, remotePath)=>{
1145
- await adbBackend.push(localPath, remotePath);
1146
- }, {
1120
+ manager = new ScrcpyManager(adb, {
1147
1121
  maxSize: config.maxSize,
1148
1122
  videoBitRate: config.videoBitRate,
1149
1123
  idleTimeoutMs: config.idleTimeoutMs
@@ -1337,13 +1311,10 @@ class ScrcpyDeviceAdapter {
1337
1311
  this.resolvedConfig = null;
1338
1312
  this.clearFailure();
1339
1313
  }
1340
- constructor(deviceId, scrcpyConfig, resolveAdbBackend = ()=>adb_createAndroidAdb({
1341
- adbExecTimeout: 60000,
1342
- deviceId
1343
- })){
1314
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
1344
1315
  _define_property(this, "deviceId", void 0);
1345
1316
  _define_property(this, "scrcpyConfig", void 0);
1346
- _define_property(this, "resolveAdbBackend", void 0);
1317
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
1347
1318
  _define_property(this, "manager", void 0);
1348
1319
  _define_property(this, "managerPromise", void 0);
1349
1320
  _define_property(this, "resolvedConfig", void 0);
@@ -1356,7 +1327,7 @@ class ScrcpyDeviceAdapter {
1356
1327
  _define_property(this, "keyframeUnsubscribers", void 0);
1357
1328
  this.deviceId = deviceId;
1358
1329
  this.scrcpyConfig = scrcpyConfig;
1359
- this.resolveAdbBackend = resolveAdbBackend;
1330
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
1360
1331
  this.manager = null;
1361
1332
  this.managerPromise = null;
1362
1333
  this.resolvedConfig = null;
@@ -1856,7 +1827,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1856
1827
  return adapter.getStatus();
1857
1828
  }
1858
1829
  getScrcpyAdapter() {
1859
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, ()=>this.getAdb());
1830
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1831
+ const adb = await this.getAdb();
1832
+ return {
1833
+ host: adb.adbHost ?? '127.0.0.1',
1834
+ port: adb.adbPort ?? 5037
1835
+ };
1836
+ });
1860
1837
  return this.scrcpyAdapter;
1861
1838
  }
1862
1839
  async openScrcpyFrameSource() {
@@ -3228,7 +3205,7 @@ class AndroidMidsceneTools extends BaseMidsceneTools {
3228
3205
  const tools = new AndroidMidsceneTools();
3229
3206
  runToolsCLI(tools, 'midscene-android', {
3230
3207
  stripPrefix: 'android_',
3231
- version: "1.12.1-beta-20260827032340.0",
3208
+ version: "1.12.1",
3232
3209
  extraCommands: createReportCliCommands()
3233
3210
  }).catch((e)=>{
3234
3211
  process.exit(reportCLIError(e));
package/dist/es/index.mjs CHANGED
@@ -31,10 +31,11 @@ var __webpack_modules__ = {
31
31
  ScrcpyScreenshotManager: ()=>ScrcpyScreenshotManager,
32
32
  ov: ()=>DEFAULT_SCRCPY_CONFIG
33
33
  });
34
- var node_module__rspack_import_0 = __webpack_require__("node:module");
35
- var node_path__rspack_import_1 = __webpack_require__("node:path");
36
- var _midscene_shared_logger__rspack_import_2 = __webpack_require__("@midscene/shared/logger");
37
- var _resource_path__rspack_import_3 = __webpack_require__("./src/resource-path.ts");
34
+ var node_fs__rspack_import_0 = __webpack_require__("node:fs");
35
+ var node_module__rspack_import_1 = __webpack_require__("node:module");
36
+ var node_path__rspack_import_2 = __webpack_require__("node:path");
37
+ var _midscene_shared_logger__rspack_import_3 = __webpack_require__("@midscene/shared/logger");
38
+ var _resource_path__rspack_import_4 = __webpack_require__("./src/resource-path.ts");
38
39
  function _define_property(obj, key, value) {
39
40
  if (key in obj) Object.defineProperty(obj, key, {
40
41
  value: value,
@@ -45,8 +46,8 @@ var __webpack_modules__ = {
45
46
  else obj[key] = value;
46
47
  return obj;
47
48
  }
48
- const debugScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy');
49
- const warnScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy', {
49
+ const debugScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy');
50
+ const warnScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy', {
50
51
  console: true
51
52
  });
52
53
  const NAL_TYPE_IDR = 5;
@@ -145,9 +146,10 @@ var __webpack_modules__ = {
145
146
  try {
146
147
  debugScrcpy('Starting scrcpy connection...');
147
148
  const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
149
+ const { ReadableStream } = await import("@yume-chan/stream-extra");
148
150
  const { DefaultServerPath } = await import("@yume-chan/scrcpy");
149
151
  const serverBinPath = this.resolveServerBinPath();
150
- await this.pushServer(serverBinPath, DefaultServerPath);
152
+ await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
151
153
  const scrcpyOptions = await this.createScrcpyOptions();
152
154
  await this.ensureFrameClockCalibration();
153
155
  this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
@@ -231,12 +233,12 @@ var __webpack_modules__ = {
231
233
  return output.filter((line)=>'string' == typeof line);
232
234
  }
233
235
  resolveServerBinPath() {
234
- const androidPkgJson = (0, node_module__rspack_import_0.createRequire)(import.meta.url).resolve('@midscene/android/package.json');
235
- return (0, _resource_path__rspack_import_3.J)(node_path__rspack_import_1["default"].join(node_path__rspack_import_1["default"].dirname(androidPkgJson), 'bin', 'scrcpy-server'));
236
+ const androidPkgJson = (0, node_module__rspack_import_1.createRequire)(import.meta.url).resolve('@midscene/android/package.json');
237
+ return (0, _resource_path__rspack_import_4.J)(node_path__rspack_import_2["default"].join(node_path__rspack_import_2["default"].dirname(androidPkgJson), 'bin', 'scrcpy-server'));
236
238
  }
237
239
  getFfmpegPath() {
238
240
  try {
239
- const dynamicRequire = (0, node_module__rspack_import_0.createRequire)(import.meta.url);
241
+ const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(import.meta.url);
240
242
  const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
241
243
  debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
242
244
  return ffmpegInstaller.path;
@@ -775,63 +777,36 @@ var __webpack_modules__ = {
775
777
  isConnected() {
776
778
  return this.isInitialized && null !== this.scrcpyClient;
777
779
  }
778
- constructor(adb, pushServer, options = {}){
779
- _define_property(this, "pushServer", void 0);
780
+ constructor(adb, options = {}){
780
781
  _define_property(this, "adb", void 0);
781
- _define_property(this, "scrcpyClient", void 0);
782
- _define_property(this, "videoStream", void 0);
783
- _define_property(this, "spsHeader", void 0);
784
- _define_property(this, "idleTimer", void 0);
785
- _define_property(this, "connectionPromise", void 0);
786
- _define_property(this, "disposed", void 0);
787
- _define_property(this, "isInitialized", void 0);
782
+ _define_property(this, "scrcpyClient", null);
783
+ _define_property(this, "videoStream", null);
784
+ _define_property(this, "spsHeader", null);
785
+ _define_property(this, "idleTimer", null);
786
+ _define_property(this, "connectionPromise", null);
787
+ _define_property(this, "disposed", false);
788
+ _define_property(this, "isInitialized", false);
788
789
  _define_property(this, "options", void 0);
789
- _define_property(this, "ffmpegAvailable", void 0);
790
- _define_property(this, "keyframeResolvers", void 0);
791
- _define_property(this, "keyframeListeners", void 0);
792
- _define_property(this, "lastRawKeyframe", void 0);
793
- _define_property(this, "lastRawKeyframeAt", void 0);
790
+ _define_property(this, "ffmpegAvailable", null);
791
+ _define_property(this, "keyframeResolvers", []);
792
+ _define_property(this, "keyframeListeners", new Set());
793
+ _define_property(this, "lastRawKeyframe", null);
794
+ _define_property(this, "lastRawKeyframeAt", 0);
794
795
  _define_property(this, "lastRawKeyframePtsUs", void 0);
795
796
  _define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
796
- _define_property(this, "videoResolution", void 0);
797
- _define_property(this, "streamReader", void 0);
798
- _define_property(this, "frameFreshnessBarrierPtsUs", void 0);
799
- _define_property(this, "frameFreshnessBarrierReason", void 0);
800
- _define_property(this, "streamStartupWindow", void 0);
801
- _define_property(this, "frameFreshnessBarrierPending", void 0);
802
- _define_property(this, "frameFreshnessBarrierGeneration", void 0);
803
- _define_property(this, "deviceClockCalibration", void 0);
804
- _define_property(this, "deviceClockCalibrationPromise", void 0);
805
- _define_property(this, "lastFramePtsUs", void 0);
806
- _define_property(this, "frameFreshnessError", void 0);
807
- _define_property(this, "lastFrameFreshnessWarningAt", void 0);
808
- _define_property(this, "disposePromise", void 0);
809
- this.pushServer = pushServer;
810
- this.scrcpyClient = null;
811
- this.videoStream = null;
812
- this.spsHeader = null;
813
- this.idleTimer = null;
814
- this.connectionPromise = null;
815
- this.disposed = false;
816
- this.isInitialized = false;
817
- this.ffmpegAvailable = null;
818
- this.keyframeResolvers = [];
819
- this.keyframeListeners = new Set();
820
- this.lastRawKeyframe = null;
821
- this.lastRawKeyframeAt = 0;
822
- this.videoResolution = null;
823
- this.streamReader = null;
824
- this.frameFreshnessBarrierPtsUs = null;
825
- this.frameFreshnessBarrierReason = null;
826
- this.streamStartupWindow = null;
827
- this.frameFreshnessBarrierPending = false;
828
- this.frameFreshnessBarrierGeneration = 0;
829
- this.deviceClockCalibration = null;
830
- this.deviceClockCalibrationPromise = null;
831
- this.lastFramePtsUs = null;
832
- this.frameFreshnessError = null;
833
- this.lastFrameFreshnessWarningAt = 0;
834
- this.disposePromise = null;
797
+ _define_property(this, "videoResolution", null);
798
+ _define_property(this, "streamReader", null);
799
+ _define_property(this, "frameFreshnessBarrierPtsUs", null);
800
+ _define_property(this, "frameFreshnessBarrierReason", null);
801
+ _define_property(this, "streamStartupWindow", null);
802
+ _define_property(this, "frameFreshnessBarrierPending", false);
803
+ _define_property(this, "frameFreshnessBarrierGeneration", 0);
804
+ _define_property(this, "deviceClockCalibration", null);
805
+ _define_property(this, "deviceClockCalibrationPromise", null);
806
+ _define_property(this, "lastFramePtsUs", null);
807
+ _define_property(this, "frameFreshnessError", null);
808
+ _define_property(this, "lastFrameFreshnessWarningAt", 0);
809
+ _define_property(this, "disposePromise", null);
835
810
  this.adb = adb;
836
811
  const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
837
812
  const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
@@ -971,6 +946,10 @@ function formatScrcpyFreshFrameFailure(error) {
971
946
  const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
972
947
  return `No usable scrcpy frame crossed the active freshness target within ${timeoutMs}ms. This can happen when a static screen emits no new encoded frame, or when the video stream or transport is interrupted. This timeout does not by itself identify bandwidth or the configured video bitrate as the cause.${bitRateDescription}`;
973
948
  }
949
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
950
+ host: '127.0.0.1',
951
+ port: 5037
952
+ };
974
953
  class ScrcpyDeviceAdapter {
975
954
  isEnabled() {
976
955
  if (!this.isConfigured()) return false;
@@ -1035,18 +1014,13 @@ class ScrcpyDeviceAdapter {
1035
1014
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
1036
1015
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
1037
1016
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
1038
- const adbBackend = await this.resolveAdbBackend();
1039
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
1040
- host: adbBackend.adbHost ?? '127.0.0.1',
1041
- port: adbBackend.adbPort ?? 5037
1042
- }));
1017
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
1018
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
1043
1019
  adb = new Adb(await adbClient.createTransport({
1044
1020
  serial: this.deviceId
1045
1021
  }));
1046
1022
  const config = this.resolveConfig();
1047
- manager = new ScrcpyManager(adb, async (localPath, remotePath)=>{
1048
- await adbBackend.push(localPath, remotePath);
1049
- }, {
1023
+ manager = new ScrcpyManager(adb, {
1050
1024
  maxSize: config.maxSize,
1051
1025
  videoBitRate: config.videoBitRate,
1052
1026
  idleTimeoutMs: config.idleTimeoutMs
@@ -1240,13 +1214,10 @@ class ScrcpyDeviceAdapter {
1240
1214
  this.resolvedConfig = null;
1241
1215
  this.clearFailure();
1242
1216
  }
1243
- constructor(deviceId, scrcpyConfig, resolveAdbBackend = ()=>createAndroidAdb({
1244
- adbExecTimeout: 60000,
1245
- deviceId
1246
- })){
1217
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
1247
1218
  _define_property(this, "deviceId", void 0);
1248
1219
  _define_property(this, "scrcpyConfig", void 0);
1249
- _define_property(this, "resolveAdbBackend", void 0);
1220
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
1250
1221
  _define_property(this, "manager", void 0);
1251
1222
  _define_property(this, "managerPromise", void 0);
1252
1223
  _define_property(this, "resolvedConfig", void 0);
@@ -1259,7 +1230,7 @@ class ScrcpyDeviceAdapter {
1259
1230
  _define_property(this, "keyframeUnsubscribers", void 0);
1260
1231
  this.deviceId = deviceId;
1261
1232
  this.scrcpyConfig = scrcpyConfig;
1262
- this.resolveAdbBackend = resolveAdbBackend;
1233
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
1263
1234
  this.manager = null;
1264
1235
  this.managerPromise = null;
1265
1236
  this.resolvedConfig = null;
@@ -1759,7 +1730,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1759
1730
  return adapter.getStatus();
1760
1731
  }
1761
1732
  getScrcpyAdapter() {
1762
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, ()=>this.getAdb());
1733
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1734
+ const adb = await this.getAdb();
1735
+ return {
1736
+ host: adb.adbHost ?? '127.0.0.1',
1737
+ port: adb.adbPort ?? 5037
1738
+ };
1739
+ });
1763
1740
  return this.scrcpyAdapter;
1764
1741
  }
1765
1742
  async openScrcpyFrameSource() {
package/dist/lib/cli.js CHANGED
@@ -19,11 +19,12 @@ var __webpack_modules__ = {
19
19
  ScrcpyScreenshotManager: ()=>ScrcpyScreenshotManager,
20
20
  ov: ()=>DEFAULT_SCRCPY_CONFIG
21
21
  });
22
- var node_module__rspack_import_0 = __webpack_require__("node:module");
23
- var node_path__rspack_import_1 = __webpack_require__("node:path");
24
- var node_path__rspack_import_1_default = /*#__PURE__*/ __webpack_require__.n(node_path__rspack_import_1);
25
- var _midscene_shared_logger__rspack_import_2 = __webpack_require__("@midscene/shared/logger");
26
- var _resource_path__rspack_import_3 = __webpack_require__("./src/resource-path.ts");
22
+ var node_fs__rspack_import_0 = __webpack_require__("node:fs");
23
+ var node_module__rspack_import_1 = __webpack_require__("node:module");
24
+ var node_path__rspack_import_2 = __webpack_require__("node:path");
25
+ var node_path__rspack_import_2_default = /*#__PURE__*/ __webpack_require__.n(node_path__rspack_import_2);
26
+ var _midscene_shared_logger__rspack_import_3 = __webpack_require__("@midscene/shared/logger");
27
+ var _resource_path__rspack_import_4 = __webpack_require__("./src/resource-path.ts");
27
28
  function _define_property(obj, key, value) {
28
29
  if (key in obj) Object.defineProperty(obj, key, {
29
30
  value: value,
@@ -34,8 +35,8 @@ var __webpack_modules__ = {
34
35
  else obj[key] = value;
35
36
  return obj;
36
37
  }
37
- const debugScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy');
38
- const warnScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy', {
38
+ const debugScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy');
39
+ const warnScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy', {
39
40
  console: true
40
41
  });
41
42
  const NAL_TYPE_IDR = 5;
@@ -134,9 +135,10 @@ var __webpack_modules__ = {
134
135
  try {
135
136
  debugScrcpy('Starting scrcpy connection...');
136
137
  const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
138
+ const { ReadableStream } = await import("@yume-chan/stream-extra");
137
139
  const { DefaultServerPath } = await import("@yume-chan/scrcpy");
138
140
  const serverBinPath = this.resolveServerBinPath();
139
- await this.pushServer(serverBinPath, DefaultServerPath);
141
+ await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
140
142
  const scrcpyOptions = await this.createScrcpyOptions();
141
143
  await this.ensureFrameClockCalibration();
142
144
  this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
@@ -220,12 +222,12 @@ var __webpack_modules__ = {
220
222
  return output.filter((line)=>'string' == typeof line);
221
223
  }
222
224
  resolveServerBinPath() {
223
- const androidPkgJson = (0, node_module__rspack_import_0.createRequire)(__rslib_import_meta_url__).resolve('@midscene/android/package.json');
224
- return (0, _resource_path__rspack_import_3.J)(node_path__rspack_import_1_default().join(node_path__rspack_import_1_default().dirname(androidPkgJson), 'bin', 'scrcpy-server'));
225
+ const androidPkgJson = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__).resolve('@midscene/android/package.json');
226
+ return (0, _resource_path__rspack_import_4.J)(node_path__rspack_import_2_default().join(node_path__rspack_import_2_default().dirname(androidPkgJson), 'bin', 'scrcpy-server'));
225
227
  }
226
228
  getFfmpegPath() {
227
229
  try {
228
- const dynamicRequire = (0, node_module__rspack_import_0.createRequire)(__rslib_import_meta_url__);
230
+ const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
229
231
  const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
230
232
  debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
231
233
  return ffmpegInstaller.path;
@@ -764,63 +766,36 @@ var __webpack_modules__ = {
764
766
  isConnected() {
765
767
  return this.isInitialized && null !== this.scrcpyClient;
766
768
  }
767
- constructor(adb, pushServer, options = {}){
768
- _define_property(this, "pushServer", void 0);
769
+ constructor(adb, options = {}){
769
770
  _define_property(this, "adb", void 0);
770
- _define_property(this, "scrcpyClient", void 0);
771
- _define_property(this, "videoStream", void 0);
772
- _define_property(this, "spsHeader", void 0);
773
- _define_property(this, "idleTimer", void 0);
774
- _define_property(this, "connectionPromise", void 0);
775
- _define_property(this, "disposed", void 0);
776
- _define_property(this, "isInitialized", void 0);
771
+ _define_property(this, "scrcpyClient", null);
772
+ _define_property(this, "videoStream", null);
773
+ _define_property(this, "spsHeader", null);
774
+ _define_property(this, "idleTimer", null);
775
+ _define_property(this, "connectionPromise", null);
776
+ _define_property(this, "disposed", false);
777
+ _define_property(this, "isInitialized", false);
777
778
  _define_property(this, "options", void 0);
778
- _define_property(this, "ffmpegAvailable", void 0);
779
- _define_property(this, "keyframeResolvers", void 0);
780
- _define_property(this, "keyframeListeners", void 0);
781
- _define_property(this, "lastRawKeyframe", void 0);
782
- _define_property(this, "lastRawKeyframeAt", void 0);
779
+ _define_property(this, "ffmpegAvailable", null);
780
+ _define_property(this, "keyframeResolvers", []);
781
+ _define_property(this, "keyframeListeners", new Set());
782
+ _define_property(this, "lastRawKeyframe", null);
783
+ _define_property(this, "lastRawKeyframeAt", 0);
783
784
  _define_property(this, "lastRawKeyframePtsUs", void 0);
784
785
  _define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
785
- _define_property(this, "videoResolution", void 0);
786
- _define_property(this, "streamReader", void 0);
787
- _define_property(this, "frameFreshnessBarrierPtsUs", void 0);
788
- _define_property(this, "frameFreshnessBarrierReason", void 0);
789
- _define_property(this, "streamStartupWindow", void 0);
790
- _define_property(this, "frameFreshnessBarrierPending", void 0);
791
- _define_property(this, "frameFreshnessBarrierGeneration", void 0);
792
- _define_property(this, "deviceClockCalibration", void 0);
793
- _define_property(this, "deviceClockCalibrationPromise", void 0);
794
- _define_property(this, "lastFramePtsUs", void 0);
795
- _define_property(this, "frameFreshnessError", void 0);
796
- _define_property(this, "lastFrameFreshnessWarningAt", void 0);
797
- _define_property(this, "disposePromise", void 0);
798
- this.pushServer = pushServer;
799
- this.scrcpyClient = null;
800
- this.videoStream = null;
801
- this.spsHeader = null;
802
- this.idleTimer = null;
803
- this.connectionPromise = null;
804
- this.disposed = false;
805
- this.isInitialized = false;
806
- this.ffmpegAvailable = null;
807
- this.keyframeResolvers = [];
808
- this.keyframeListeners = new Set();
809
- this.lastRawKeyframe = null;
810
- this.lastRawKeyframeAt = 0;
811
- this.videoResolution = null;
812
- this.streamReader = null;
813
- this.frameFreshnessBarrierPtsUs = null;
814
- this.frameFreshnessBarrierReason = null;
815
- this.streamStartupWindow = null;
816
- this.frameFreshnessBarrierPending = false;
817
- this.frameFreshnessBarrierGeneration = 0;
818
- this.deviceClockCalibration = null;
819
- this.deviceClockCalibrationPromise = null;
820
- this.lastFramePtsUs = null;
821
- this.frameFreshnessError = null;
822
- this.lastFrameFreshnessWarningAt = 0;
823
- this.disposePromise = null;
786
+ _define_property(this, "videoResolution", null);
787
+ _define_property(this, "streamReader", null);
788
+ _define_property(this, "frameFreshnessBarrierPtsUs", null);
789
+ _define_property(this, "frameFreshnessBarrierReason", null);
790
+ _define_property(this, "streamStartupWindow", null);
791
+ _define_property(this, "frameFreshnessBarrierPending", false);
792
+ _define_property(this, "frameFreshnessBarrierGeneration", 0);
793
+ _define_property(this, "deviceClockCalibration", null);
794
+ _define_property(this, "deviceClockCalibrationPromise", null);
795
+ _define_property(this, "lastFramePtsUs", null);
796
+ _define_property(this, "frameFreshnessError", null);
797
+ _define_property(this, "lastFrameFreshnessWarningAt", 0);
798
+ _define_property(this, "disposePromise", null);
824
799
  this.adb = adb;
825
800
  const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
826
801
  const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
@@ -1083,6 +1058,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1083
1058
  const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
1084
1059
  return `No usable scrcpy frame crossed the active freshness target within ${timeoutMs}ms. This can happen when a static screen emits no new encoded frame, or when the video stream or transport is interrupted. This timeout does not by itself identify bandwidth or the configured video bitrate as the cause.${bitRateDescription}`;
1085
1060
  }
1061
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
1062
+ host: '127.0.0.1',
1063
+ port: 5037
1064
+ };
1086
1065
  class ScrcpyDeviceAdapter {
1087
1066
  isEnabled() {
1088
1067
  if (!this.isConfigured()) return false;
@@ -1147,18 +1126,13 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1147
1126
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
1148
1127
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
1149
1128
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
1150
- const adbBackend = await this.resolveAdbBackend();
1151
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
1152
- host: adbBackend.adbHost ?? '127.0.0.1',
1153
- port: adbBackend.adbPort ?? 5037
1154
- }));
1129
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
1130
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
1155
1131
  adb = new Adb(await adbClient.createTransport({
1156
1132
  serial: this.deviceId
1157
1133
  }));
1158
1134
  const config = this.resolveConfig();
1159
- manager = new ScrcpyManager(adb, async (localPath, remotePath)=>{
1160
- await adbBackend.push(localPath, remotePath);
1161
- }, {
1135
+ manager = new ScrcpyManager(adb, {
1162
1136
  maxSize: config.maxSize,
1163
1137
  videoBitRate: config.videoBitRate,
1164
1138
  idleTimeoutMs: config.idleTimeoutMs
@@ -1352,13 +1326,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1352
1326
  this.resolvedConfig = null;
1353
1327
  this.clearFailure();
1354
1328
  }
1355
- constructor(deviceId, scrcpyConfig, resolveAdbBackend = ()=>adb_createAndroidAdb({
1356
- adbExecTimeout: 60000,
1357
- deviceId
1358
- })){
1329
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
1359
1330
  _define_property(this, "deviceId", void 0);
1360
1331
  _define_property(this, "scrcpyConfig", void 0);
1361
- _define_property(this, "resolveAdbBackend", void 0);
1332
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
1362
1333
  _define_property(this, "manager", void 0);
1363
1334
  _define_property(this, "managerPromise", void 0);
1364
1335
  _define_property(this, "resolvedConfig", void 0);
@@ -1371,7 +1342,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1371
1342
  _define_property(this, "keyframeUnsubscribers", void 0);
1372
1343
  this.deviceId = deviceId;
1373
1344
  this.scrcpyConfig = scrcpyConfig;
1374
- this.resolveAdbBackend = resolveAdbBackend;
1345
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
1375
1346
  this.manager = null;
1376
1347
  this.managerPromise = null;
1377
1348
  this.resolvedConfig = null;
@@ -1871,7 +1842,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1871
1842
  return adapter.getStatus();
1872
1843
  }
1873
1844
  getScrcpyAdapter() {
1874
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, ()=>this.getAdb());
1845
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1846
+ const adb = await this.getAdb();
1847
+ return {
1848
+ host: adb.adbHost ?? '127.0.0.1',
1849
+ port: adb.adbPort ?? 5037
1850
+ };
1851
+ });
1875
1852
  return this.scrcpyAdapter;
1876
1853
  }
1877
1854
  async openScrcpyFrameSource() {
@@ -3243,7 +3220,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
3243
3220
  const tools = new AndroidMidsceneTools();
3244
3221
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-android', {
3245
3222
  stripPrefix: 'android_',
3246
- version: "1.12.1-beta-20260827032340.0",
3223
+ version: "1.12.1",
3247
3224
  extraCommands: (0, core_namespaceObject.createReportCliCommands)()
3248
3225
  }).catch((e)=>{
3249
3226
  process.exit((0, cli_namespaceObject.reportCLIError)(e));
package/dist/lib/index.js CHANGED
@@ -19,11 +19,12 @@ var __webpack_modules__ = {
19
19
  ScrcpyScreenshotManager: ()=>ScrcpyScreenshotManager,
20
20
  ov: ()=>DEFAULT_SCRCPY_CONFIG
21
21
  });
22
- var node_module__rspack_import_0 = __webpack_require__("node:module");
23
- var node_path__rspack_import_1 = __webpack_require__("node:path");
24
- var node_path__rspack_import_1_default = /*#__PURE__*/ __webpack_require__.n(node_path__rspack_import_1);
25
- var _midscene_shared_logger__rspack_import_2 = __webpack_require__("@midscene/shared/logger");
26
- var _resource_path__rspack_import_3 = __webpack_require__("./src/resource-path.ts");
22
+ var node_fs__rspack_import_0 = __webpack_require__("node:fs");
23
+ var node_module__rspack_import_1 = __webpack_require__("node:module");
24
+ var node_path__rspack_import_2 = __webpack_require__("node:path");
25
+ var node_path__rspack_import_2_default = /*#__PURE__*/ __webpack_require__.n(node_path__rspack_import_2);
26
+ var _midscene_shared_logger__rspack_import_3 = __webpack_require__("@midscene/shared/logger");
27
+ var _resource_path__rspack_import_4 = __webpack_require__("./src/resource-path.ts");
27
28
  function _define_property(obj, key, value) {
28
29
  if (key in obj) Object.defineProperty(obj, key, {
29
30
  value: value,
@@ -34,8 +35,8 @@ var __webpack_modules__ = {
34
35
  else obj[key] = value;
35
36
  return obj;
36
37
  }
37
- const debugScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy');
38
- const warnScrcpy = (0, _midscene_shared_logger__rspack_import_2.getDebug)('android:scrcpy', {
38
+ const debugScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy');
39
+ const warnScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy', {
39
40
  console: true
40
41
  });
41
42
  const NAL_TYPE_IDR = 5;
@@ -134,9 +135,10 @@ var __webpack_modules__ = {
134
135
  try {
135
136
  debugScrcpy('Starting scrcpy connection...');
136
137
  const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
138
+ const { ReadableStream } = await import("@yume-chan/stream-extra");
137
139
  const { DefaultServerPath } = await import("@yume-chan/scrcpy");
138
140
  const serverBinPath = this.resolveServerBinPath();
139
- await this.pushServer(serverBinPath, DefaultServerPath);
141
+ await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
140
142
  const scrcpyOptions = await this.createScrcpyOptions();
141
143
  await this.ensureFrameClockCalibration();
142
144
  this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
@@ -220,12 +222,12 @@ var __webpack_modules__ = {
220
222
  return output.filter((line)=>'string' == typeof line);
221
223
  }
222
224
  resolveServerBinPath() {
223
- const androidPkgJson = (0, node_module__rspack_import_0.createRequire)(__rslib_import_meta_url__).resolve('@midscene/android/package.json');
224
- return (0, _resource_path__rspack_import_3.J)(node_path__rspack_import_1_default().join(node_path__rspack_import_1_default().dirname(androidPkgJson), 'bin', 'scrcpy-server'));
225
+ const androidPkgJson = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__).resolve('@midscene/android/package.json');
226
+ return (0, _resource_path__rspack_import_4.J)(node_path__rspack_import_2_default().join(node_path__rspack_import_2_default().dirname(androidPkgJson), 'bin', 'scrcpy-server'));
225
227
  }
226
228
  getFfmpegPath() {
227
229
  try {
228
- const dynamicRequire = (0, node_module__rspack_import_0.createRequire)(__rslib_import_meta_url__);
230
+ const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
229
231
  const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
230
232
  debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
231
233
  return ffmpegInstaller.path;
@@ -764,63 +766,36 @@ var __webpack_modules__ = {
764
766
  isConnected() {
765
767
  return this.isInitialized && null !== this.scrcpyClient;
766
768
  }
767
- constructor(adb, pushServer, options = {}){
768
- _define_property(this, "pushServer", void 0);
769
+ constructor(adb, options = {}){
769
770
  _define_property(this, "adb", void 0);
770
- _define_property(this, "scrcpyClient", void 0);
771
- _define_property(this, "videoStream", void 0);
772
- _define_property(this, "spsHeader", void 0);
773
- _define_property(this, "idleTimer", void 0);
774
- _define_property(this, "connectionPromise", void 0);
775
- _define_property(this, "disposed", void 0);
776
- _define_property(this, "isInitialized", void 0);
771
+ _define_property(this, "scrcpyClient", null);
772
+ _define_property(this, "videoStream", null);
773
+ _define_property(this, "spsHeader", null);
774
+ _define_property(this, "idleTimer", null);
775
+ _define_property(this, "connectionPromise", null);
776
+ _define_property(this, "disposed", false);
777
+ _define_property(this, "isInitialized", false);
777
778
  _define_property(this, "options", void 0);
778
- _define_property(this, "ffmpegAvailable", void 0);
779
- _define_property(this, "keyframeResolvers", void 0);
780
- _define_property(this, "keyframeListeners", void 0);
781
- _define_property(this, "lastRawKeyframe", void 0);
782
- _define_property(this, "lastRawKeyframeAt", void 0);
779
+ _define_property(this, "ffmpegAvailable", null);
780
+ _define_property(this, "keyframeResolvers", []);
781
+ _define_property(this, "keyframeListeners", new Set());
782
+ _define_property(this, "lastRawKeyframe", null);
783
+ _define_property(this, "lastRawKeyframeAt", 0);
783
784
  _define_property(this, "lastRawKeyframePtsUs", void 0);
784
785
  _define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
785
- _define_property(this, "videoResolution", void 0);
786
- _define_property(this, "streamReader", void 0);
787
- _define_property(this, "frameFreshnessBarrierPtsUs", void 0);
788
- _define_property(this, "frameFreshnessBarrierReason", void 0);
789
- _define_property(this, "streamStartupWindow", void 0);
790
- _define_property(this, "frameFreshnessBarrierPending", void 0);
791
- _define_property(this, "frameFreshnessBarrierGeneration", void 0);
792
- _define_property(this, "deviceClockCalibration", void 0);
793
- _define_property(this, "deviceClockCalibrationPromise", void 0);
794
- _define_property(this, "lastFramePtsUs", void 0);
795
- _define_property(this, "frameFreshnessError", void 0);
796
- _define_property(this, "lastFrameFreshnessWarningAt", void 0);
797
- _define_property(this, "disposePromise", void 0);
798
- this.pushServer = pushServer;
799
- this.scrcpyClient = null;
800
- this.videoStream = null;
801
- this.spsHeader = null;
802
- this.idleTimer = null;
803
- this.connectionPromise = null;
804
- this.disposed = false;
805
- this.isInitialized = false;
806
- this.ffmpegAvailable = null;
807
- this.keyframeResolvers = [];
808
- this.keyframeListeners = new Set();
809
- this.lastRawKeyframe = null;
810
- this.lastRawKeyframeAt = 0;
811
- this.videoResolution = null;
812
- this.streamReader = null;
813
- this.frameFreshnessBarrierPtsUs = null;
814
- this.frameFreshnessBarrierReason = null;
815
- this.streamStartupWindow = null;
816
- this.frameFreshnessBarrierPending = false;
817
- this.frameFreshnessBarrierGeneration = 0;
818
- this.deviceClockCalibration = null;
819
- this.deviceClockCalibrationPromise = null;
820
- this.lastFramePtsUs = null;
821
- this.frameFreshnessError = null;
822
- this.lastFrameFreshnessWarningAt = 0;
823
- this.disposePromise = null;
786
+ _define_property(this, "videoResolution", null);
787
+ _define_property(this, "streamReader", null);
788
+ _define_property(this, "frameFreshnessBarrierPtsUs", null);
789
+ _define_property(this, "frameFreshnessBarrierReason", null);
790
+ _define_property(this, "streamStartupWindow", null);
791
+ _define_property(this, "frameFreshnessBarrierPending", false);
792
+ _define_property(this, "frameFreshnessBarrierGeneration", 0);
793
+ _define_property(this, "deviceClockCalibration", null);
794
+ _define_property(this, "deviceClockCalibrationPromise", null);
795
+ _define_property(this, "lastFramePtsUs", null);
796
+ _define_property(this, "frameFreshnessError", null);
797
+ _define_property(this, "lastFrameFreshnessWarningAt", 0);
798
+ _define_property(this, "disposePromise", null);
824
799
  this.adb = adb;
825
800
  const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
826
801
  const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
@@ -1004,6 +979,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1004
979
  const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
1005
980
  return `No usable scrcpy frame crossed the active freshness target within ${timeoutMs}ms. This can happen when a static screen emits no new encoded frame, or when the video stream or transport is interrupted. This timeout does not by itself identify bandwidth or the configured video bitrate as the cause.${bitRateDescription}`;
1006
981
  }
982
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
983
+ host: '127.0.0.1',
984
+ port: 5037
985
+ };
1007
986
  class ScrcpyDeviceAdapter {
1008
987
  isEnabled() {
1009
988
  if (!this.isConfigured()) return false;
@@ -1068,18 +1047,13 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1068
1047
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
1069
1048
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
1070
1049
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
1071
- const adbBackend = await this.resolveAdbBackend();
1072
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
1073
- host: adbBackend.adbHost ?? '127.0.0.1',
1074
- port: adbBackend.adbPort ?? 5037
1075
- }));
1050
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
1051
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
1076
1052
  adb = new Adb(await adbClient.createTransport({
1077
1053
  serial: this.deviceId
1078
1054
  }));
1079
1055
  const config = this.resolveConfig();
1080
- manager = new ScrcpyManager(adb, async (localPath, remotePath)=>{
1081
- await adbBackend.push(localPath, remotePath);
1082
- }, {
1056
+ manager = new ScrcpyManager(adb, {
1083
1057
  maxSize: config.maxSize,
1084
1058
  videoBitRate: config.videoBitRate,
1085
1059
  idleTimeoutMs: config.idleTimeoutMs
@@ -1273,13 +1247,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1273
1247
  this.resolvedConfig = null;
1274
1248
  this.clearFailure();
1275
1249
  }
1276
- constructor(deviceId, scrcpyConfig, resolveAdbBackend = ()=>createAndroidAdb({
1277
- adbExecTimeout: 60000,
1278
- deviceId
1279
- })){
1250
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
1280
1251
  _define_property(this, "deviceId", void 0);
1281
1252
  _define_property(this, "scrcpyConfig", void 0);
1282
- _define_property(this, "resolveAdbBackend", void 0);
1253
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
1283
1254
  _define_property(this, "manager", void 0);
1284
1255
  _define_property(this, "managerPromise", void 0);
1285
1256
  _define_property(this, "resolvedConfig", void 0);
@@ -1292,7 +1263,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
1292
1263
  _define_property(this, "keyframeUnsubscribers", void 0);
1293
1264
  this.deviceId = deviceId;
1294
1265
  this.scrcpyConfig = scrcpyConfig;
1295
- this.resolveAdbBackend = resolveAdbBackend;
1266
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
1296
1267
  this.manager = null;
1297
1268
  this.managerPromise = null;
1298
1269
  this.resolvedConfig = null;
@@ -1792,7 +1763,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1792
1763
  return adapter.getStatus();
1793
1764
  }
1794
1765
  getScrcpyAdapter() {
1795
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, ()=>this.getAdb());
1766
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1767
+ const adb = await this.getAdb();
1768
+ return {
1769
+ host: adb.adbHost ?? '127.0.0.1',
1770
+ port: adb.adbPort ?? 5037
1771
+ };
1772
+ });
1796
1773
  return this.scrcpyAdapter;
1797
1774
  }
1798
1775
  async openScrcpyFrameSource() {
@@ -23,6 +23,11 @@ import { UITreeSnapshot } from '@midscene/core';
23
23
 
24
24
  declare type ActionArgs<T extends DeviceAction> = [ActionParam<T>] extends [undefined] ? [] : [ActionParam<T>];
25
25
 
26
+ declare interface AdbServerEndpoint {
27
+ host: string;
28
+ port: number;
29
+ }
30
+
26
31
  export declare function agentFromAdbDevice(deviceId?: string, opts?: AndroidAgentOpt & AndroidDeviceOpt): Promise<AndroidAgent>;
27
32
 
28
33
  export declare class AndroidAgent extends Agent<AndroidDevice> {
@@ -388,6 +393,8 @@ declare interface RawKeyframe {
388
393
  capturedAt: number;
389
394
  }
390
395
 
396
+ declare type ResolveAdbServerEndpoint = () => AdbServerEndpoint | Promise<AdbServerEndpoint>;
397
+
391
398
  declare interface ResolvedScrcpyConfig {
392
399
  enabled: boolean;
393
400
  maxSize: number;
@@ -395,8 +402,6 @@ declare interface ResolvedScrcpyConfig {
395
402
  idleTimeoutMs: number;
396
403
  }
397
404
 
398
- export declare type ResolveScrcpyAdbBackend = () => ScrcpyAdbBackend | Promise<ScrcpyAdbBackend>;
399
-
400
405
  declare type RunAdbShellOpt = {
401
406
  /**
402
407
  * ADB shell command execution timeout in milliseconds.
@@ -404,13 +409,6 @@ declare type RunAdbShellOpt = {
404
409
  timeout?: number;
405
410
  };
406
411
 
407
- /** ADB capabilities scrcpy needs from the canonical Appium transport. */
408
- export declare interface ScrcpyAdbBackend {
409
- adbHost?: string;
410
- adbPort?: number;
411
- push(localPath: string, remotePath: string): Promise<unknown>;
412
- }
413
-
414
412
  declare interface ScrcpyConfig {
415
413
  enabled?: boolean;
416
414
  maxSize?: number;
@@ -425,7 +423,7 @@ declare interface ScrcpyConfig {
425
423
  export declare class ScrcpyDeviceAdapter {
426
424
  private deviceId;
427
425
  private scrcpyConfig;
428
- private resolveAdbBackend;
426
+ private resolveAdbServerEndpoint;
429
427
  private manager;
430
428
  private managerPromise;
431
429
  private resolvedConfig;
@@ -436,7 +434,7 @@ export declare class ScrcpyDeviceAdapter {
436
434
  private pendingActionBarrierAtHostUs;
437
435
  private keyframeListeners;
438
436
  private keyframeUnsubscribers;
439
- constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined, resolveAdbBackend?: ResolveScrcpyAdbBackend);
437
+ constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined, resolveAdbServerEndpoint?: ResolveAdbServerEndpoint);
440
438
  isEnabled(): boolean;
441
439
  getStatus(): ScrcpyStatus;
442
440
  private isConfigured;
@@ -529,7 +527,6 @@ declare interface ScrcpyFreshnessBarrierOptions {
529
527
  }
530
528
 
531
529
  declare class ScrcpyScreenshotManager {
532
- private readonly pushServer;
533
530
  private adb;
534
531
  private scrcpyClient;
535
532
  private videoStream;
@@ -559,7 +556,7 @@ declare class ScrcpyScreenshotManager {
559
556
  private frameFreshnessError;
560
557
  private lastFrameFreshnessWarningAt;
561
558
  private disposePromise;
562
- constructor(adb: Adb, pushServer: ScrcpyServerPusher, options?: ScrcpyScreenshotOptions);
559
+ constructor(adb: Adb, options?: ScrcpyScreenshotOptions);
563
560
  /**
564
561
  * Validate environment prerequisites (ffmpeg, scrcpy-server, etc.)
565
562
  * Must be called once after construction, before any screenshot operations.
@@ -722,9 +719,6 @@ declare interface ScrcpyScreenshotOptions {
722
719
  idleTimeoutMs?: number;
723
720
  }
724
721
 
725
- /** Transfers the local scrcpy server binary to its device path. */
726
- declare type ScrcpyServerPusher = (localPath: string, remotePath: string) => Promise<void>;
727
-
728
722
  export declare interface ScrcpyStatus {
729
723
  enabled: boolean;
730
724
  connected: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/android",
3
- "version": "1.12.1-beta-20260827032340.0",
3
+ "version": "1.12.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/midscene.git",
@@ -41,8 +41,8 @@
41
41
  "@yume-chan/stream-extra": "2.6.1",
42
42
  "appium-adb": "12.12.1",
43
43
  "sharp": "^0.34.3",
44
- "@midscene/shared": "1.12.1-beta-20260827032340.0",
45
- "@midscene/core": "1.12.1-beta-20260827032340.0"
44
+ "@midscene/shared": "1.12.1",
45
+ "@midscene/core": "1.12.1"
46
46
  },
47
47
  "optionalDependencies": {
48
48
  "@ffmpeg-installer/ffmpeg": "^1.1.0"
@@ -56,7 +56,7 @@
56
56
  "typescript": "^5.8.3",
57
57
  "undici": "^6.0.0",
58
58
  "zod": "^3.25.1",
59
- "@midscene/playground": "1.12.1-beta-20260827032340.0"
59
+ "@midscene/playground": "1.12.1"
60
60
  },
61
61
  "license": "MIT",
62
62
  "scripts": {