@midscene/android 1.12.1-beta-20260826131413.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 +45 -94
- package/dist/es/index.mjs +44 -93
- package/dist/lib/cli.js +46 -95
- package/dist/lib/index.js +45 -94
- package/dist/types/index.d.ts +4 -11
- package/package.json +4 -4
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
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
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,
|
|
50
|
-
const warnScrcpy = (0,
|
|
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;
|
|
@@ -80,9 +81,6 @@ var __webpack_modules__ = {
|
|
|
80
81
|
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
81
82
|
videoBitRate: DEFAULT_VIDEO_BIT_RATE
|
|
82
83
|
};
|
|
83
|
-
const missingScrcpyServerPusher = async ()=>{
|
|
84
|
-
throw new Error('Scrcpy server pusher is not configured');
|
|
85
|
-
};
|
|
86
84
|
const SCRCPY_FRESH_FRAME_UNAVAILABLE_ERROR_CODE = 'ERR_SCRCPY_FRESH_FRAME_UNAVAILABLE';
|
|
87
85
|
class ScrcpyFreshFrameUnavailableError extends Error {
|
|
88
86
|
constructor(message, options){
|
|
@@ -149,9 +147,10 @@ var __webpack_modules__ = {
|
|
|
149
147
|
try {
|
|
150
148
|
debugScrcpy('Starting scrcpy connection...');
|
|
151
149
|
const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
|
|
150
|
+
const { ReadableStream } = await import("@yume-chan/stream-extra");
|
|
152
151
|
const { DefaultServerPath } = await import("@yume-chan/scrcpy");
|
|
153
152
|
const serverBinPath = this.resolveServerBinPath();
|
|
154
|
-
await this.
|
|
153
|
+
await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
|
|
155
154
|
const scrcpyOptions = await this.createScrcpyOptions();
|
|
156
155
|
await this.ensureFrameClockCalibration();
|
|
157
156
|
this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
|
|
@@ -182,9 +181,6 @@ var __webpack_modules__ = {
|
|
|
182
181
|
throw this.createConnectionError(error, serverOutput);
|
|
183
182
|
}
|
|
184
183
|
}
|
|
185
|
-
async pushServerBinary(serverBinPath, remoteServerPath) {
|
|
186
|
-
await this.pushServer(serverBinPath, remoteServerPath);
|
|
187
|
-
}
|
|
188
184
|
async createScrcpyOptions() {
|
|
189
185
|
const [{ AdbScrcpyOptions3_3_3 }, { ScrcpyInstanceId }] = await Promise.all([
|
|
190
186
|
import("@yume-chan/adb-scrcpy"),
|
|
@@ -238,12 +234,12 @@ var __webpack_modules__ = {
|
|
|
238
234
|
return output.filter((line)=>'string' == typeof line);
|
|
239
235
|
}
|
|
240
236
|
resolveServerBinPath() {
|
|
241
|
-
const androidPkgJson = (0,
|
|
242
|
-
return (0,
|
|
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'));
|
|
243
239
|
}
|
|
244
240
|
getFfmpegPath() {
|
|
245
241
|
try {
|
|
246
|
-
const dynamicRequire = (0,
|
|
242
|
+
const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(import.meta.url);
|
|
247
243
|
const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
|
|
248
244
|
debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
|
|
249
245
|
return ffmpegInstaller.path;
|
|
@@ -782,63 +778,36 @@ var __webpack_modules__ = {
|
|
|
782
778
|
isConnected() {
|
|
783
779
|
return this.isInitialized && null !== this.scrcpyClient;
|
|
784
780
|
}
|
|
785
|
-
constructor(adb, options = {}
|
|
786
|
-
_define_property(this, "pushServer", void 0);
|
|
781
|
+
constructor(adb, options = {}){
|
|
787
782
|
_define_property(this, "adb", void 0);
|
|
788
|
-
_define_property(this, "scrcpyClient",
|
|
789
|
-
_define_property(this, "videoStream",
|
|
790
|
-
_define_property(this, "spsHeader",
|
|
791
|
-
_define_property(this, "idleTimer",
|
|
792
|
-
_define_property(this, "connectionPromise",
|
|
793
|
-
_define_property(this, "disposed",
|
|
794
|
-
_define_property(this, "isInitialized",
|
|
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);
|
|
795
790
|
_define_property(this, "options", void 0);
|
|
796
|
-
_define_property(this, "ffmpegAvailable",
|
|
797
|
-
_define_property(this, "keyframeResolvers",
|
|
798
|
-
_define_property(this, "keyframeListeners",
|
|
799
|
-
_define_property(this, "lastRawKeyframe",
|
|
800
|
-
_define_property(this, "lastRawKeyframeAt",
|
|
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);
|
|
801
796
|
_define_property(this, "lastRawKeyframePtsUs", void 0);
|
|
802
797
|
_define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
|
|
803
|
-
_define_property(this, "videoResolution",
|
|
804
|
-
_define_property(this, "streamReader",
|
|
805
|
-
_define_property(this, "frameFreshnessBarrierPtsUs",
|
|
806
|
-
_define_property(this, "frameFreshnessBarrierReason",
|
|
807
|
-
_define_property(this, "streamStartupWindow",
|
|
808
|
-
_define_property(this, "frameFreshnessBarrierPending",
|
|
809
|
-
_define_property(this, "frameFreshnessBarrierGeneration",
|
|
810
|
-
_define_property(this, "deviceClockCalibration",
|
|
811
|
-
_define_property(this, "deviceClockCalibrationPromise",
|
|
812
|
-
_define_property(this, "lastFramePtsUs",
|
|
813
|
-
_define_property(this, "frameFreshnessError",
|
|
814
|
-
_define_property(this, "lastFrameFreshnessWarningAt",
|
|
815
|
-
_define_property(this, "disposePromise",
|
|
816
|
-
this.pushServer = pushServer;
|
|
817
|
-
this.scrcpyClient = null;
|
|
818
|
-
this.videoStream = null;
|
|
819
|
-
this.spsHeader = null;
|
|
820
|
-
this.idleTimer = null;
|
|
821
|
-
this.connectionPromise = null;
|
|
822
|
-
this.disposed = false;
|
|
823
|
-
this.isInitialized = false;
|
|
824
|
-
this.ffmpegAvailable = null;
|
|
825
|
-
this.keyframeResolvers = [];
|
|
826
|
-
this.keyframeListeners = new Set();
|
|
827
|
-
this.lastRawKeyframe = null;
|
|
828
|
-
this.lastRawKeyframeAt = 0;
|
|
829
|
-
this.videoResolution = null;
|
|
830
|
-
this.streamReader = null;
|
|
831
|
-
this.frameFreshnessBarrierPtsUs = null;
|
|
832
|
-
this.frameFreshnessBarrierReason = null;
|
|
833
|
-
this.streamStartupWindow = null;
|
|
834
|
-
this.frameFreshnessBarrierPending = false;
|
|
835
|
-
this.frameFreshnessBarrierGeneration = 0;
|
|
836
|
-
this.deviceClockCalibration = null;
|
|
837
|
-
this.deviceClockCalibrationPromise = null;
|
|
838
|
-
this.lastFramePtsUs = null;
|
|
839
|
-
this.frameFreshnessError = null;
|
|
840
|
-
this.lastFrameFreshnessWarningAt = 0;
|
|
841
|
-
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);
|
|
842
811
|
this.adb = adb;
|
|
843
812
|
const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
|
|
844
813
|
const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
|
|
@@ -1074,7 +1043,7 @@ function formatScrcpyFreshFrameFailure(error) {
|
|
|
1074
1043
|
const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
|
|
1075
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}`;
|
|
1076
1045
|
}
|
|
1077
|
-
const
|
|
1046
|
+
const DEFAULT_ADB_SERVER_ENDPOINT = {
|
|
1078
1047
|
host: '127.0.0.1',
|
|
1079
1048
|
port: 5037
|
|
1080
1049
|
};
|
|
@@ -1142,21 +1111,17 @@ class ScrcpyDeviceAdapter {
|
|
|
1142
1111
|
const { Adb, AdbServerClient } = await import("@yume-chan/adb");
|
|
1143
1112
|
const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
|
|
1144
1113
|
const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
|
|
1145
|
-
const
|
|
1146
|
-
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(
|
|
1147
|
-
host: adbServerConnection.host,
|
|
1148
|
-
port: adbServerConnection.port
|
|
1149
|
-
}));
|
|
1114
|
+
const adbServerEndpoint = await this.resolveAdbServerEndpoint();
|
|
1115
|
+
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
|
|
1150
1116
|
adb = new Adb(await adbClient.createTransport({
|
|
1151
1117
|
serial: this.deviceId
|
|
1152
1118
|
}));
|
|
1153
1119
|
const config = this.resolveConfig();
|
|
1154
|
-
const serverPusher = adbServerConnection.pushServer ?? this.createDefaultServerPusher(adbServerConnection);
|
|
1155
1120
|
manager = new ScrcpyManager(adb, {
|
|
1156
1121
|
maxSize: config.maxSize,
|
|
1157
1122
|
videoBitRate: config.videoBitRate,
|
|
1158
1123
|
idleTimeoutMs: config.idleTimeoutMs
|
|
1159
|
-
}
|
|
1124
|
+
});
|
|
1160
1125
|
await manager.validateEnvironment();
|
|
1161
1126
|
if (generation !== this.lifecycleGeneration) throw new Error('Scrcpy manager initialization was superseded by device cleanup');
|
|
1162
1127
|
this.manager = manager;
|
|
@@ -1180,17 +1145,6 @@ class ScrcpyDeviceAdapter {
|
|
|
1180
1145
|
if (this.managerPromise === managerPromise) this.managerPromise = null;
|
|
1181
1146
|
}
|
|
1182
1147
|
}
|
|
1183
|
-
createDefaultServerPusher(endpoint) {
|
|
1184
|
-
let fileTransferAdb;
|
|
1185
|
-
return async (localPath, remotePath)=>{
|
|
1186
|
-
fileTransferAdb ??= new ADB({
|
|
1187
|
-
udid: this.deviceId,
|
|
1188
|
-
remoteAdbHost: endpoint.host,
|
|
1189
|
-
remoteAdbPort: endpoint.port
|
|
1190
|
-
});
|
|
1191
|
-
await fileTransferAdb.push(localPath, remotePath);
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
1148
|
async ensureConnectedManager(deviceInfo) {
|
|
1195
1149
|
const manager = await this.ensureManager(deviceInfo);
|
|
1196
1150
|
const wasConnected = manager.isConnected();
|
|
@@ -1357,7 +1311,7 @@ class ScrcpyDeviceAdapter {
|
|
|
1357
1311
|
this.resolvedConfig = null;
|
|
1358
1312
|
this.clearFailure();
|
|
1359
1313
|
}
|
|
1360
|
-
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>
|
|
1314
|
+
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
|
|
1361
1315
|
_define_property(this, "deviceId", void 0);
|
|
1362
1316
|
_define_property(this, "scrcpyConfig", void 0);
|
|
1363
1317
|
_define_property(this, "resolveAdbServerEndpoint", void 0);
|
|
@@ -1877,10 +1831,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
1877
1831
|
const adb = await this.getAdb();
|
|
1878
1832
|
return {
|
|
1879
1833
|
host: adb.adbHost ?? '127.0.0.1',
|
|
1880
|
-
port: adb.adbPort ?? 5037
|
|
1881
|
-
pushServer: async (localPath, remotePath)=>{
|
|
1882
|
-
await adb.push(localPath, remotePath);
|
|
1883
|
-
}
|
|
1834
|
+
port: adb.adbPort ?? 5037
|
|
1884
1835
|
};
|
|
1885
1836
|
});
|
|
1886
1837
|
return this.scrcpyAdapter;
|
|
@@ -3254,7 +3205,7 @@ class AndroidMidsceneTools extends BaseMidsceneTools {
|
|
|
3254
3205
|
const tools = new AndroidMidsceneTools();
|
|
3255
3206
|
runToolsCLI(tools, 'midscene-android', {
|
|
3256
3207
|
stripPrefix: 'android_',
|
|
3257
|
-
version: "1.12.1
|
|
3208
|
+
version: "1.12.1",
|
|
3258
3209
|
extraCommands: createReportCliCommands()
|
|
3259
3210
|
}).catch((e)=>{
|
|
3260
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
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var
|
|
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,
|
|
49
|
-
const warnScrcpy = (0,
|
|
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;
|
|
@@ -79,9 +80,6 @@ var __webpack_modules__ = {
|
|
|
79
80
|
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
80
81
|
videoBitRate: DEFAULT_VIDEO_BIT_RATE
|
|
81
82
|
};
|
|
82
|
-
const missingScrcpyServerPusher = async ()=>{
|
|
83
|
-
throw new Error('Scrcpy server pusher is not configured');
|
|
84
|
-
};
|
|
85
83
|
const SCRCPY_FRESH_FRAME_UNAVAILABLE_ERROR_CODE = 'ERR_SCRCPY_FRESH_FRAME_UNAVAILABLE';
|
|
86
84
|
class ScrcpyFreshFrameUnavailableError extends Error {
|
|
87
85
|
constructor(message, options){
|
|
@@ -148,9 +146,10 @@ var __webpack_modules__ = {
|
|
|
148
146
|
try {
|
|
149
147
|
debugScrcpy('Starting scrcpy connection...');
|
|
150
148
|
const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
|
|
149
|
+
const { ReadableStream } = await import("@yume-chan/stream-extra");
|
|
151
150
|
const { DefaultServerPath } = await import("@yume-chan/scrcpy");
|
|
152
151
|
const serverBinPath = this.resolveServerBinPath();
|
|
153
|
-
await this.
|
|
152
|
+
await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
|
|
154
153
|
const scrcpyOptions = await this.createScrcpyOptions();
|
|
155
154
|
await this.ensureFrameClockCalibration();
|
|
156
155
|
this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
|
|
@@ -181,9 +180,6 @@ var __webpack_modules__ = {
|
|
|
181
180
|
throw this.createConnectionError(error, serverOutput);
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
|
-
async pushServerBinary(serverBinPath, remoteServerPath) {
|
|
185
|
-
await this.pushServer(serverBinPath, remoteServerPath);
|
|
186
|
-
}
|
|
187
183
|
async createScrcpyOptions() {
|
|
188
184
|
const [{ AdbScrcpyOptions3_3_3 }, { ScrcpyInstanceId }] = await Promise.all([
|
|
189
185
|
import("@yume-chan/adb-scrcpy"),
|
|
@@ -237,12 +233,12 @@ var __webpack_modules__ = {
|
|
|
237
233
|
return output.filter((line)=>'string' == typeof line);
|
|
238
234
|
}
|
|
239
235
|
resolveServerBinPath() {
|
|
240
|
-
const androidPkgJson = (0,
|
|
241
|
-
return (0,
|
|
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'));
|
|
242
238
|
}
|
|
243
239
|
getFfmpegPath() {
|
|
244
240
|
try {
|
|
245
|
-
const dynamicRequire = (0,
|
|
241
|
+
const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(import.meta.url);
|
|
246
242
|
const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
|
|
247
243
|
debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
|
|
248
244
|
return ffmpegInstaller.path;
|
|
@@ -781,63 +777,36 @@ var __webpack_modules__ = {
|
|
|
781
777
|
isConnected() {
|
|
782
778
|
return this.isInitialized && null !== this.scrcpyClient;
|
|
783
779
|
}
|
|
784
|
-
constructor(adb, options = {}
|
|
785
|
-
_define_property(this, "pushServer", void 0);
|
|
780
|
+
constructor(adb, options = {}){
|
|
786
781
|
_define_property(this, "adb", void 0);
|
|
787
|
-
_define_property(this, "scrcpyClient",
|
|
788
|
-
_define_property(this, "videoStream",
|
|
789
|
-
_define_property(this, "spsHeader",
|
|
790
|
-
_define_property(this, "idleTimer",
|
|
791
|
-
_define_property(this, "connectionPromise",
|
|
792
|
-
_define_property(this, "disposed",
|
|
793
|
-
_define_property(this, "isInitialized",
|
|
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);
|
|
794
789
|
_define_property(this, "options", void 0);
|
|
795
|
-
_define_property(this, "ffmpegAvailable",
|
|
796
|
-
_define_property(this, "keyframeResolvers",
|
|
797
|
-
_define_property(this, "keyframeListeners",
|
|
798
|
-
_define_property(this, "lastRawKeyframe",
|
|
799
|
-
_define_property(this, "lastRawKeyframeAt",
|
|
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);
|
|
800
795
|
_define_property(this, "lastRawKeyframePtsUs", void 0);
|
|
801
796
|
_define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
|
|
802
|
-
_define_property(this, "videoResolution",
|
|
803
|
-
_define_property(this, "streamReader",
|
|
804
|
-
_define_property(this, "frameFreshnessBarrierPtsUs",
|
|
805
|
-
_define_property(this, "frameFreshnessBarrierReason",
|
|
806
|
-
_define_property(this, "streamStartupWindow",
|
|
807
|
-
_define_property(this, "frameFreshnessBarrierPending",
|
|
808
|
-
_define_property(this, "frameFreshnessBarrierGeneration",
|
|
809
|
-
_define_property(this, "deviceClockCalibration",
|
|
810
|
-
_define_property(this, "deviceClockCalibrationPromise",
|
|
811
|
-
_define_property(this, "lastFramePtsUs",
|
|
812
|
-
_define_property(this, "frameFreshnessError",
|
|
813
|
-
_define_property(this, "lastFrameFreshnessWarningAt",
|
|
814
|
-
_define_property(this, "disposePromise",
|
|
815
|
-
this.pushServer = pushServer;
|
|
816
|
-
this.scrcpyClient = null;
|
|
817
|
-
this.videoStream = null;
|
|
818
|
-
this.spsHeader = null;
|
|
819
|
-
this.idleTimer = null;
|
|
820
|
-
this.connectionPromise = null;
|
|
821
|
-
this.disposed = false;
|
|
822
|
-
this.isInitialized = false;
|
|
823
|
-
this.ffmpegAvailable = null;
|
|
824
|
-
this.keyframeResolvers = [];
|
|
825
|
-
this.keyframeListeners = new Set();
|
|
826
|
-
this.lastRawKeyframe = null;
|
|
827
|
-
this.lastRawKeyframeAt = 0;
|
|
828
|
-
this.videoResolution = null;
|
|
829
|
-
this.streamReader = null;
|
|
830
|
-
this.frameFreshnessBarrierPtsUs = null;
|
|
831
|
-
this.frameFreshnessBarrierReason = null;
|
|
832
|
-
this.streamStartupWindow = null;
|
|
833
|
-
this.frameFreshnessBarrierPending = false;
|
|
834
|
-
this.frameFreshnessBarrierGeneration = 0;
|
|
835
|
-
this.deviceClockCalibration = null;
|
|
836
|
-
this.deviceClockCalibrationPromise = null;
|
|
837
|
-
this.lastFramePtsUs = null;
|
|
838
|
-
this.frameFreshnessError = null;
|
|
839
|
-
this.lastFrameFreshnessWarningAt = 0;
|
|
840
|
-
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);
|
|
841
810
|
this.adb = adb;
|
|
842
811
|
const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
|
|
843
812
|
const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
|
|
@@ -977,7 +946,7 @@ function formatScrcpyFreshFrameFailure(error) {
|
|
|
977
946
|
const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
|
|
978
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}`;
|
|
979
948
|
}
|
|
980
|
-
const
|
|
949
|
+
const DEFAULT_ADB_SERVER_ENDPOINT = {
|
|
981
950
|
host: '127.0.0.1',
|
|
982
951
|
port: 5037
|
|
983
952
|
};
|
|
@@ -1045,21 +1014,17 @@ class ScrcpyDeviceAdapter {
|
|
|
1045
1014
|
const { Adb, AdbServerClient } = await import("@yume-chan/adb");
|
|
1046
1015
|
const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
|
|
1047
1016
|
const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
|
|
1048
|
-
const
|
|
1049
|
-
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(
|
|
1050
|
-
host: adbServerConnection.host,
|
|
1051
|
-
port: adbServerConnection.port
|
|
1052
|
-
}));
|
|
1017
|
+
const adbServerEndpoint = await this.resolveAdbServerEndpoint();
|
|
1018
|
+
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
|
|
1053
1019
|
adb = new Adb(await adbClient.createTransport({
|
|
1054
1020
|
serial: this.deviceId
|
|
1055
1021
|
}));
|
|
1056
1022
|
const config = this.resolveConfig();
|
|
1057
|
-
const serverPusher = adbServerConnection.pushServer ?? this.createDefaultServerPusher(adbServerConnection);
|
|
1058
1023
|
manager = new ScrcpyManager(adb, {
|
|
1059
1024
|
maxSize: config.maxSize,
|
|
1060
1025
|
videoBitRate: config.videoBitRate,
|
|
1061
1026
|
idleTimeoutMs: config.idleTimeoutMs
|
|
1062
|
-
}
|
|
1027
|
+
});
|
|
1063
1028
|
await manager.validateEnvironment();
|
|
1064
1029
|
if (generation !== this.lifecycleGeneration) throw new Error('Scrcpy manager initialization was superseded by device cleanup');
|
|
1065
1030
|
this.manager = manager;
|
|
@@ -1083,17 +1048,6 @@ class ScrcpyDeviceAdapter {
|
|
|
1083
1048
|
if (this.managerPromise === managerPromise) this.managerPromise = null;
|
|
1084
1049
|
}
|
|
1085
1050
|
}
|
|
1086
|
-
createDefaultServerPusher(endpoint) {
|
|
1087
|
-
let fileTransferAdb;
|
|
1088
|
-
return async (localPath, remotePath)=>{
|
|
1089
|
-
fileTransferAdb ??= new ADB({
|
|
1090
|
-
udid: this.deviceId,
|
|
1091
|
-
remoteAdbHost: endpoint.host,
|
|
1092
|
-
remoteAdbPort: endpoint.port
|
|
1093
|
-
});
|
|
1094
|
-
await fileTransferAdb.push(localPath, remotePath);
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
1051
|
async ensureConnectedManager(deviceInfo) {
|
|
1098
1052
|
const manager = await this.ensureManager(deviceInfo);
|
|
1099
1053
|
const wasConnected = manager.isConnected();
|
|
@@ -1260,7 +1214,7 @@ class ScrcpyDeviceAdapter {
|
|
|
1260
1214
|
this.resolvedConfig = null;
|
|
1261
1215
|
this.clearFailure();
|
|
1262
1216
|
}
|
|
1263
|
-
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>
|
|
1217
|
+
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
|
|
1264
1218
|
_define_property(this, "deviceId", void 0);
|
|
1265
1219
|
_define_property(this, "scrcpyConfig", void 0);
|
|
1266
1220
|
_define_property(this, "resolveAdbServerEndpoint", void 0);
|
|
@@ -1780,10 +1734,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
1780
1734
|
const adb = await this.getAdb();
|
|
1781
1735
|
return {
|
|
1782
1736
|
host: adb.adbHost ?? '127.0.0.1',
|
|
1783
|
-
port: adb.adbPort ?? 5037
|
|
1784
|
-
pushServer: async (localPath, remotePath)=>{
|
|
1785
|
-
await adb.push(localPath, remotePath);
|
|
1786
|
-
}
|
|
1737
|
+
port: adb.adbPort ?? 5037
|
|
1787
1738
|
};
|
|
1788
1739
|
});
|
|
1789
1740
|
return this.scrcpyAdapter;
|
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
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
var
|
|
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,
|
|
38
|
-
const warnScrcpy = (0,
|
|
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;
|
|
@@ -68,9 +69,6 @@ var __webpack_modules__ = {
|
|
|
68
69
|
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
69
70
|
videoBitRate: DEFAULT_VIDEO_BIT_RATE
|
|
70
71
|
};
|
|
71
|
-
const missingScrcpyServerPusher = async ()=>{
|
|
72
|
-
throw new Error('Scrcpy server pusher is not configured');
|
|
73
|
-
};
|
|
74
72
|
const SCRCPY_FRESH_FRAME_UNAVAILABLE_ERROR_CODE = 'ERR_SCRCPY_FRESH_FRAME_UNAVAILABLE';
|
|
75
73
|
class ScrcpyFreshFrameUnavailableError extends Error {
|
|
76
74
|
constructor(message, options){
|
|
@@ -137,9 +135,10 @@ var __webpack_modules__ = {
|
|
|
137
135
|
try {
|
|
138
136
|
debugScrcpy('Starting scrcpy connection...');
|
|
139
137
|
const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
|
|
138
|
+
const { ReadableStream } = await import("@yume-chan/stream-extra");
|
|
140
139
|
const { DefaultServerPath } = await import("@yume-chan/scrcpy");
|
|
141
140
|
const serverBinPath = this.resolveServerBinPath();
|
|
142
|
-
await this.
|
|
141
|
+
await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
|
|
143
142
|
const scrcpyOptions = await this.createScrcpyOptions();
|
|
144
143
|
await this.ensureFrameClockCalibration();
|
|
145
144
|
this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
|
|
@@ -170,9 +169,6 @@ var __webpack_modules__ = {
|
|
|
170
169
|
throw this.createConnectionError(error, serverOutput);
|
|
171
170
|
}
|
|
172
171
|
}
|
|
173
|
-
async pushServerBinary(serverBinPath, remoteServerPath) {
|
|
174
|
-
await this.pushServer(serverBinPath, remoteServerPath);
|
|
175
|
-
}
|
|
176
172
|
async createScrcpyOptions() {
|
|
177
173
|
const [{ AdbScrcpyOptions3_3_3 }, { ScrcpyInstanceId }] = await Promise.all([
|
|
178
174
|
import("@yume-chan/adb-scrcpy"),
|
|
@@ -226,12 +222,12 @@ var __webpack_modules__ = {
|
|
|
226
222
|
return output.filter((line)=>'string' == typeof line);
|
|
227
223
|
}
|
|
228
224
|
resolveServerBinPath() {
|
|
229
|
-
const androidPkgJson = (0,
|
|
230
|
-
return (0,
|
|
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'));
|
|
231
227
|
}
|
|
232
228
|
getFfmpegPath() {
|
|
233
229
|
try {
|
|
234
|
-
const dynamicRequire = (0,
|
|
230
|
+
const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
|
|
235
231
|
const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
|
|
236
232
|
debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
|
|
237
233
|
return ffmpegInstaller.path;
|
|
@@ -770,63 +766,36 @@ var __webpack_modules__ = {
|
|
|
770
766
|
isConnected() {
|
|
771
767
|
return this.isInitialized && null !== this.scrcpyClient;
|
|
772
768
|
}
|
|
773
|
-
constructor(adb, options = {}
|
|
774
|
-
_define_property(this, "pushServer", void 0);
|
|
769
|
+
constructor(adb, options = {}){
|
|
775
770
|
_define_property(this, "adb", void 0);
|
|
776
|
-
_define_property(this, "scrcpyClient",
|
|
777
|
-
_define_property(this, "videoStream",
|
|
778
|
-
_define_property(this, "spsHeader",
|
|
779
|
-
_define_property(this, "idleTimer",
|
|
780
|
-
_define_property(this, "connectionPromise",
|
|
781
|
-
_define_property(this, "disposed",
|
|
782
|
-
_define_property(this, "isInitialized",
|
|
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);
|
|
783
778
|
_define_property(this, "options", void 0);
|
|
784
|
-
_define_property(this, "ffmpegAvailable",
|
|
785
|
-
_define_property(this, "keyframeResolvers",
|
|
786
|
-
_define_property(this, "keyframeListeners",
|
|
787
|
-
_define_property(this, "lastRawKeyframe",
|
|
788
|
-
_define_property(this, "lastRawKeyframeAt",
|
|
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);
|
|
789
784
|
_define_property(this, "lastRawKeyframePtsUs", void 0);
|
|
790
785
|
_define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
|
|
791
|
-
_define_property(this, "videoResolution",
|
|
792
|
-
_define_property(this, "streamReader",
|
|
793
|
-
_define_property(this, "frameFreshnessBarrierPtsUs",
|
|
794
|
-
_define_property(this, "frameFreshnessBarrierReason",
|
|
795
|
-
_define_property(this, "streamStartupWindow",
|
|
796
|
-
_define_property(this, "frameFreshnessBarrierPending",
|
|
797
|
-
_define_property(this, "frameFreshnessBarrierGeneration",
|
|
798
|
-
_define_property(this, "deviceClockCalibration",
|
|
799
|
-
_define_property(this, "deviceClockCalibrationPromise",
|
|
800
|
-
_define_property(this, "lastFramePtsUs",
|
|
801
|
-
_define_property(this, "frameFreshnessError",
|
|
802
|
-
_define_property(this, "lastFrameFreshnessWarningAt",
|
|
803
|
-
_define_property(this, "disposePromise",
|
|
804
|
-
this.pushServer = pushServer;
|
|
805
|
-
this.scrcpyClient = null;
|
|
806
|
-
this.videoStream = null;
|
|
807
|
-
this.spsHeader = null;
|
|
808
|
-
this.idleTimer = null;
|
|
809
|
-
this.connectionPromise = null;
|
|
810
|
-
this.disposed = false;
|
|
811
|
-
this.isInitialized = false;
|
|
812
|
-
this.ffmpegAvailable = null;
|
|
813
|
-
this.keyframeResolvers = [];
|
|
814
|
-
this.keyframeListeners = new Set();
|
|
815
|
-
this.lastRawKeyframe = null;
|
|
816
|
-
this.lastRawKeyframeAt = 0;
|
|
817
|
-
this.videoResolution = null;
|
|
818
|
-
this.streamReader = null;
|
|
819
|
-
this.frameFreshnessBarrierPtsUs = null;
|
|
820
|
-
this.frameFreshnessBarrierReason = null;
|
|
821
|
-
this.streamStartupWindow = null;
|
|
822
|
-
this.frameFreshnessBarrierPending = false;
|
|
823
|
-
this.frameFreshnessBarrierGeneration = 0;
|
|
824
|
-
this.deviceClockCalibration = null;
|
|
825
|
-
this.deviceClockCalibrationPromise = null;
|
|
826
|
-
this.lastFramePtsUs = null;
|
|
827
|
-
this.frameFreshnessError = null;
|
|
828
|
-
this.lastFrameFreshnessWarningAt = 0;
|
|
829
|
-
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);
|
|
830
799
|
this.adb = adb;
|
|
831
800
|
const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
|
|
832
801
|
const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
|
|
@@ -1089,7 +1058,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1089
1058
|
const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
|
|
1090
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}`;
|
|
1091
1060
|
}
|
|
1092
|
-
const
|
|
1061
|
+
const DEFAULT_ADB_SERVER_ENDPOINT = {
|
|
1093
1062
|
host: '127.0.0.1',
|
|
1094
1063
|
port: 5037
|
|
1095
1064
|
};
|
|
@@ -1157,21 +1126,17 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1157
1126
|
const { Adb, AdbServerClient } = await import("@yume-chan/adb");
|
|
1158
1127
|
const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
|
|
1159
1128
|
const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
|
|
1160
|
-
const
|
|
1161
|
-
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(
|
|
1162
|
-
host: adbServerConnection.host,
|
|
1163
|
-
port: adbServerConnection.port
|
|
1164
|
-
}));
|
|
1129
|
+
const adbServerEndpoint = await this.resolveAdbServerEndpoint();
|
|
1130
|
+
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
|
|
1165
1131
|
adb = new Adb(await adbClient.createTransport({
|
|
1166
1132
|
serial: this.deviceId
|
|
1167
1133
|
}));
|
|
1168
1134
|
const config = this.resolveConfig();
|
|
1169
|
-
const serverPusher = adbServerConnection.pushServer ?? this.createDefaultServerPusher(adbServerConnection);
|
|
1170
1135
|
manager = new ScrcpyManager(adb, {
|
|
1171
1136
|
maxSize: config.maxSize,
|
|
1172
1137
|
videoBitRate: config.videoBitRate,
|
|
1173
1138
|
idleTimeoutMs: config.idleTimeoutMs
|
|
1174
|
-
}
|
|
1139
|
+
});
|
|
1175
1140
|
await manager.validateEnvironment();
|
|
1176
1141
|
if (generation !== this.lifecycleGeneration) throw new Error('Scrcpy manager initialization was superseded by device cleanup');
|
|
1177
1142
|
this.manager = manager;
|
|
@@ -1195,17 +1160,6 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1195
1160
|
if (this.managerPromise === managerPromise) this.managerPromise = null;
|
|
1196
1161
|
}
|
|
1197
1162
|
}
|
|
1198
|
-
createDefaultServerPusher(endpoint) {
|
|
1199
|
-
let fileTransferAdb;
|
|
1200
|
-
return async (localPath, remotePath)=>{
|
|
1201
|
-
fileTransferAdb ??= new external_appium_adb_namespaceObject.ADB({
|
|
1202
|
-
udid: this.deviceId,
|
|
1203
|
-
remoteAdbHost: endpoint.host,
|
|
1204
|
-
remoteAdbPort: endpoint.port
|
|
1205
|
-
});
|
|
1206
|
-
await fileTransferAdb.push(localPath, remotePath);
|
|
1207
|
-
};
|
|
1208
|
-
}
|
|
1209
1163
|
async ensureConnectedManager(deviceInfo) {
|
|
1210
1164
|
const manager = await this.ensureManager(deviceInfo);
|
|
1211
1165
|
const wasConnected = manager.isConnected();
|
|
@@ -1372,7 +1326,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1372
1326
|
this.resolvedConfig = null;
|
|
1373
1327
|
this.clearFailure();
|
|
1374
1328
|
}
|
|
1375
|
-
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>
|
|
1329
|
+
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
|
|
1376
1330
|
_define_property(this, "deviceId", void 0);
|
|
1377
1331
|
_define_property(this, "scrcpyConfig", void 0);
|
|
1378
1332
|
_define_property(this, "resolveAdbServerEndpoint", void 0);
|
|
@@ -1892,10 +1846,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
1892
1846
|
const adb = await this.getAdb();
|
|
1893
1847
|
return {
|
|
1894
1848
|
host: adb.adbHost ?? '127.0.0.1',
|
|
1895
|
-
port: adb.adbPort ?? 5037
|
|
1896
|
-
pushServer: async (localPath, remotePath)=>{
|
|
1897
|
-
await adb.push(localPath, remotePath);
|
|
1898
|
-
}
|
|
1849
|
+
port: adb.adbPort ?? 5037
|
|
1899
1850
|
};
|
|
1900
1851
|
});
|
|
1901
1852
|
return this.scrcpyAdapter;
|
|
@@ -3269,7 +3220,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
3269
3220
|
const tools = new AndroidMidsceneTools();
|
|
3270
3221
|
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-android', {
|
|
3271
3222
|
stripPrefix: 'android_',
|
|
3272
|
-
version: "1.12.1
|
|
3223
|
+
version: "1.12.1",
|
|
3273
3224
|
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
3274
3225
|
}).catch((e)=>{
|
|
3275
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
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
var
|
|
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,
|
|
38
|
-
const warnScrcpy = (0,
|
|
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;
|
|
@@ -68,9 +69,6 @@ var __webpack_modules__ = {
|
|
|
68
69
|
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
69
70
|
videoBitRate: DEFAULT_VIDEO_BIT_RATE
|
|
70
71
|
};
|
|
71
|
-
const missingScrcpyServerPusher = async ()=>{
|
|
72
|
-
throw new Error('Scrcpy server pusher is not configured');
|
|
73
|
-
};
|
|
74
72
|
const SCRCPY_FRESH_FRAME_UNAVAILABLE_ERROR_CODE = 'ERR_SCRCPY_FRESH_FRAME_UNAVAILABLE';
|
|
75
73
|
class ScrcpyFreshFrameUnavailableError extends Error {
|
|
76
74
|
constructor(message, options){
|
|
@@ -137,9 +135,10 @@ var __webpack_modules__ = {
|
|
|
137
135
|
try {
|
|
138
136
|
debugScrcpy('Starting scrcpy connection...');
|
|
139
137
|
const { AdbScrcpyClient } = await import("@yume-chan/adb-scrcpy");
|
|
138
|
+
const { ReadableStream } = await import("@yume-chan/stream-extra");
|
|
140
139
|
const { DefaultServerPath } = await import("@yume-chan/scrcpy");
|
|
141
140
|
const serverBinPath = this.resolveServerBinPath();
|
|
142
|
-
await this.
|
|
141
|
+
await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
|
|
143
142
|
const scrcpyOptions = await this.createScrcpyOptions();
|
|
144
143
|
await this.ensureFrameClockCalibration();
|
|
145
144
|
this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
|
|
@@ -170,9 +169,6 @@ var __webpack_modules__ = {
|
|
|
170
169
|
throw this.createConnectionError(error, serverOutput);
|
|
171
170
|
}
|
|
172
171
|
}
|
|
173
|
-
async pushServerBinary(serverBinPath, remoteServerPath) {
|
|
174
|
-
await this.pushServer(serverBinPath, remoteServerPath);
|
|
175
|
-
}
|
|
176
172
|
async createScrcpyOptions() {
|
|
177
173
|
const [{ AdbScrcpyOptions3_3_3 }, { ScrcpyInstanceId }] = await Promise.all([
|
|
178
174
|
import("@yume-chan/adb-scrcpy"),
|
|
@@ -226,12 +222,12 @@ var __webpack_modules__ = {
|
|
|
226
222
|
return output.filter((line)=>'string' == typeof line);
|
|
227
223
|
}
|
|
228
224
|
resolveServerBinPath() {
|
|
229
|
-
const androidPkgJson = (0,
|
|
230
|
-
return (0,
|
|
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'));
|
|
231
227
|
}
|
|
232
228
|
getFfmpegPath() {
|
|
233
229
|
try {
|
|
234
|
-
const dynamicRequire = (0,
|
|
230
|
+
const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
|
|
235
231
|
const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
|
|
236
232
|
debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
|
|
237
233
|
return ffmpegInstaller.path;
|
|
@@ -770,63 +766,36 @@ var __webpack_modules__ = {
|
|
|
770
766
|
isConnected() {
|
|
771
767
|
return this.isInitialized && null !== this.scrcpyClient;
|
|
772
768
|
}
|
|
773
|
-
constructor(adb, options = {}
|
|
774
|
-
_define_property(this, "pushServer", void 0);
|
|
769
|
+
constructor(adb, options = {}){
|
|
775
770
|
_define_property(this, "adb", void 0);
|
|
776
|
-
_define_property(this, "scrcpyClient",
|
|
777
|
-
_define_property(this, "videoStream",
|
|
778
|
-
_define_property(this, "spsHeader",
|
|
779
|
-
_define_property(this, "idleTimer",
|
|
780
|
-
_define_property(this, "connectionPromise",
|
|
781
|
-
_define_property(this, "disposed",
|
|
782
|
-
_define_property(this, "isInitialized",
|
|
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);
|
|
783
778
|
_define_property(this, "options", void 0);
|
|
784
|
-
_define_property(this, "ffmpegAvailable",
|
|
785
|
-
_define_property(this, "keyframeResolvers",
|
|
786
|
-
_define_property(this, "keyframeListeners",
|
|
787
|
-
_define_property(this, "lastRawKeyframe",
|
|
788
|
-
_define_property(this, "lastRawKeyframeAt",
|
|
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);
|
|
789
784
|
_define_property(this, "lastRawKeyframePtsUs", void 0);
|
|
790
785
|
_define_property(this, "lastRawKeyframeEstimatedAgeMs", void 0);
|
|
791
|
-
_define_property(this, "videoResolution",
|
|
792
|
-
_define_property(this, "streamReader",
|
|
793
|
-
_define_property(this, "frameFreshnessBarrierPtsUs",
|
|
794
|
-
_define_property(this, "frameFreshnessBarrierReason",
|
|
795
|
-
_define_property(this, "streamStartupWindow",
|
|
796
|
-
_define_property(this, "frameFreshnessBarrierPending",
|
|
797
|
-
_define_property(this, "frameFreshnessBarrierGeneration",
|
|
798
|
-
_define_property(this, "deviceClockCalibration",
|
|
799
|
-
_define_property(this, "deviceClockCalibrationPromise",
|
|
800
|
-
_define_property(this, "lastFramePtsUs",
|
|
801
|
-
_define_property(this, "frameFreshnessError",
|
|
802
|
-
_define_property(this, "lastFrameFreshnessWarningAt",
|
|
803
|
-
_define_property(this, "disposePromise",
|
|
804
|
-
this.pushServer = pushServer;
|
|
805
|
-
this.scrcpyClient = null;
|
|
806
|
-
this.videoStream = null;
|
|
807
|
-
this.spsHeader = null;
|
|
808
|
-
this.idleTimer = null;
|
|
809
|
-
this.connectionPromise = null;
|
|
810
|
-
this.disposed = false;
|
|
811
|
-
this.isInitialized = false;
|
|
812
|
-
this.ffmpegAvailable = null;
|
|
813
|
-
this.keyframeResolvers = [];
|
|
814
|
-
this.keyframeListeners = new Set();
|
|
815
|
-
this.lastRawKeyframe = null;
|
|
816
|
-
this.lastRawKeyframeAt = 0;
|
|
817
|
-
this.videoResolution = null;
|
|
818
|
-
this.streamReader = null;
|
|
819
|
-
this.frameFreshnessBarrierPtsUs = null;
|
|
820
|
-
this.frameFreshnessBarrierReason = null;
|
|
821
|
-
this.streamStartupWindow = null;
|
|
822
|
-
this.frameFreshnessBarrierPending = false;
|
|
823
|
-
this.frameFreshnessBarrierGeneration = 0;
|
|
824
|
-
this.deviceClockCalibration = null;
|
|
825
|
-
this.deviceClockCalibrationPromise = null;
|
|
826
|
-
this.lastFramePtsUs = null;
|
|
827
|
-
this.frameFreshnessError = null;
|
|
828
|
-
this.lastFrameFreshnessWarningAt = 0;
|
|
829
|
-
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);
|
|
830
799
|
this.adb = adb;
|
|
831
800
|
const requestedBitRate = options.videoBitRate ?? DEFAULT_VIDEO_BIT_RATE;
|
|
832
801
|
const clampedBitRate = Math.min(requestedBitRate, MAX_VIDEO_BIT_RATE);
|
|
@@ -1010,7 +979,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1010
979
|
const bitRateDescription = Number.isFinite(videoBitRate) ? ` Current videoBitRate: ${videoBitRate} bps (${videoBitRate / 1000000} Mbps).` : '';
|
|
1011
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}`;
|
|
1012
981
|
}
|
|
1013
|
-
const
|
|
982
|
+
const DEFAULT_ADB_SERVER_ENDPOINT = {
|
|
1014
983
|
host: '127.0.0.1',
|
|
1015
984
|
port: 5037
|
|
1016
985
|
};
|
|
@@ -1078,21 +1047,17 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1078
1047
|
const { Adb, AdbServerClient } = await import("@yume-chan/adb");
|
|
1079
1048
|
const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
|
|
1080
1049
|
const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
|
|
1081
|
-
const
|
|
1082
|
-
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(
|
|
1083
|
-
host: adbServerConnection.host,
|
|
1084
|
-
port: adbServerConnection.port
|
|
1085
|
-
}));
|
|
1050
|
+
const adbServerEndpoint = await this.resolveAdbServerEndpoint();
|
|
1051
|
+
const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
|
|
1086
1052
|
adb = new Adb(await adbClient.createTransport({
|
|
1087
1053
|
serial: this.deviceId
|
|
1088
1054
|
}));
|
|
1089
1055
|
const config = this.resolveConfig();
|
|
1090
|
-
const serverPusher = adbServerConnection.pushServer ?? this.createDefaultServerPusher(adbServerConnection);
|
|
1091
1056
|
manager = new ScrcpyManager(adb, {
|
|
1092
1057
|
maxSize: config.maxSize,
|
|
1093
1058
|
videoBitRate: config.videoBitRate,
|
|
1094
1059
|
idleTimeoutMs: config.idleTimeoutMs
|
|
1095
|
-
}
|
|
1060
|
+
});
|
|
1096
1061
|
await manager.validateEnvironment();
|
|
1097
1062
|
if (generation !== this.lifecycleGeneration) throw new Error('Scrcpy manager initialization was superseded by device cleanup');
|
|
1098
1063
|
this.manager = manager;
|
|
@@ -1116,17 +1081,6 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1116
1081
|
if (this.managerPromise === managerPromise) this.managerPromise = null;
|
|
1117
1082
|
}
|
|
1118
1083
|
}
|
|
1119
|
-
createDefaultServerPusher(endpoint) {
|
|
1120
|
-
let fileTransferAdb;
|
|
1121
|
-
return async (localPath, remotePath)=>{
|
|
1122
|
-
fileTransferAdb ??= new external_appium_adb_namespaceObject.ADB({
|
|
1123
|
-
udid: this.deviceId,
|
|
1124
|
-
remoteAdbHost: endpoint.host,
|
|
1125
|
-
remoteAdbPort: endpoint.port
|
|
1126
|
-
});
|
|
1127
|
-
await fileTransferAdb.push(localPath, remotePath);
|
|
1128
|
-
};
|
|
1129
|
-
}
|
|
1130
1084
|
async ensureConnectedManager(deviceInfo) {
|
|
1131
1085
|
const manager = await this.ensureManager(deviceInfo);
|
|
1132
1086
|
const wasConnected = manager.isConnected();
|
|
@@ -1293,7 +1247,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1293
1247
|
this.resolvedConfig = null;
|
|
1294
1248
|
this.clearFailure();
|
|
1295
1249
|
}
|
|
1296
|
-
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>
|
|
1250
|
+
constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
|
|
1297
1251
|
_define_property(this, "deviceId", void 0);
|
|
1298
1252
|
_define_property(this, "scrcpyConfig", void 0);
|
|
1299
1253
|
_define_property(this, "resolveAdbServerEndpoint", void 0);
|
|
@@ -1813,10 +1767,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
1813
1767
|
const adb = await this.getAdb();
|
|
1814
1768
|
return {
|
|
1815
1769
|
host: adb.adbHost ?? '127.0.0.1',
|
|
1816
|
-
port: adb.adbPort ?? 5037
|
|
1817
|
-
pushServer: async (localPath, remotePath)=>{
|
|
1818
|
-
await adb.push(localPath, remotePath);
|
|
1819
|
-
}
|
|
1770
|
+
port: adb.adbPort ?? 5037
|
|
1820
1771
|
};
|
|
1821
1772
|
});
|
|
1822
1773
|
return this.scrcpyAdapter;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -23,10 +23,9 @@ 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
|
|
26
|
+
declare interface AdbServerEndpoint {
|
|
27
27
|
host: string;
|
|
28
28
|
port: number;
|
|
29
|
-
pushServer?: ScrcpyServerPusher;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export declare function agentFromAdbDevice(deviceId?: string, opts?: AndroidAgentOpt & AndroidDeviceOpt): Promise<AndroidAgent>;
|
|
@@ -394,7 +393,7 @@ declare interface RawKeyframe {
|
|
|
394
393
|
capturedAt: number;
|
|
395
394
|
}
|
|
396
395
|
|
|
397
|
-
declare type
|
|
396
|
+
declare type ResolveAdbServerEndpoint = () => AdbServerEndpoint | Promise<AdbServerEndpoint>;
|
|
398
397
|
|
|
399
398
|
declare interface ResolvedScrcpyConfig {
|
|
400
399
|
enabled: boolean;
|
|
@@ -435,7 +434,7 @@ export declare class ScrcpyDeviceAdapter {
|
|
|
435
434
|
private pendingActionBarrierAtHostUs;
|
|
436
435
|
private keyframeListeners;
|
|
437
436
|
private keyframeUnsubscribers;
|
|
438
|
-
constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined, resolveAdbServerEndpoint?:
|
|
437
|
+
constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined, resolveAdbServerEndpoint?: ResolveAdbServerEndpoint);
|
|
439
438
|
isEnabled(): boolean;
|
|
440
439
|
getStatus(): ScrcpyStatus;
|
|
441
440
|
private isConfigured;
|
|
@@ -463,7 +462,6 @@ export declare class ScrcpyDeviceAdapter {
|
|
|
463
462
|
* Uses dynamic import for @yume-chan packages (ESM-only, must use await import in CJS builds).
|
|
464
463
|
*/
|
|
465
464
|
ensureManager(_deviceInfo: DevicePhysicalInfo): Promise<ScrcpyScreenshotManager>;
|
|
466
|
-
private createDefaultServerPusher;
|
|
467
465
|
/**
|
|
468
466
|
* Connect the current manager and restore adapter-owned frame subscriptions
|
|
469
467
|
* whenever this call establishes a new stream epoch. Existing connections
|
|
@@ -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, 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.
|
|
@@ -571,7 +568,6 @@ declare class ScrcpyScreenshotManager {
|
|
|
571
568
|
*/
|
|
572
569
|
ensureConnected(): Promise<void>;
|
|
573
570
|
private connectScrcpy;
|
|
574
|
-
private pushServerBinary;
|
|
575
571
|
private createScrcpyOptions;
|
|
576
572
|
private collectServerOutput;
|
|
577
573
|
private createConnectionError;
|
|
@@ -723,9 +719,6 @@ declare interface ScrcpyScreenshotOptions {
|
|
|
723
719
|
idleTimeoutMs?: number;
|
|
724
720
|
}
|
|
725
721
|
|
|
726
|
-
/** Transfers the local scrcpy server binary to its device path. */
|
|
727
|
-
declare type ScrcpyServerPusher = (localPath: string, remotePath: string) => Promise<void>;
|
|
728
|
-
|
|
729
722
|
export declare interface ScrcpyStatus {
|
|
730
723
|
enabled: boolean;
|
|
731
724
|
connected: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/android",
|
|
3
|
-
"version": "1.12.1
|
|
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/
|
|
45
|
-
"@midscene/
|
|
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
|
|
59
|
+
"@midscene/playground": "1.12.1"
|
|
60
60
|
},
|
|
61
61
|
"license": "MIT",
|
|
62
62
|
"scripts": {
|