@midscene/android 1.11.1-beta-20260821125003.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/cli.mjs +8 -27
- package/dist/es/index.mjs +7 -26
- package/dist/lib/cli.js +7 -26
- package/dist/lib/index.js +6 -25
- package/dist/types/index.d.ts +1 -7
- package/package.json +4 -4
package/dist/es/cli.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { execFile } from "node:child_process";
|
|
|
13
13
|
import { createDefaultMobileActions, defineAction } from "@midscene/core/device";
|
|
14
14
|
import { getTmpFile, sleep } from "@midscene/core/utils";
|
|
15
15
|
import { MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, MIDSCENE_ANDROID_SCREENSHOT_STRATEGY, globalConfigManager } from "@midscene/shared/env";
|
|
16
|
-
import { createImgBase64ByFormat,
|
|
16
|
+
import { createImgBase64ByFormat, validateScreenshotBuffer } from "@midscene/shared/img";
|
|
17
17
|
import { ADB, getSdkRootFromEnv } from "appium-adb";
|
|
18
18
|
var __webpack_modules__ = {
|
|
19
19
|
"./src/resource-path.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -1077,11 +1077,10 @@ class ScrcpyDeviceAdapter {
|
|
|
1077
1077
|
if (null === this.retryAfter || Date.now() >= this.retryAfter) return;
|
|
1078
1078
|
throw new Error(`scrcpy retry is cooling down until ${new Date(this.retryAfter).toISOString()}. Last error: ${this.lastError}`);
|
|
1079
1079
|
}
|
|
1080
|
-
resolveConfig() {
|
|
1080
|
+
resolveConfig(deviceInfo) {
|
|
1081
1081
|
if (this.resolvedConfig) return this.resolvedConfig;
|
|
1082
1082
|
const config = this.scrcpyConfig;
|
|
1083
1083
|
const maxSize = config?.maxSize ?? scrcpy_manager.ov.maxSize;
|
|
1084
|
-
if (!Number.isInteger(maxSize) || maxSize < 0) throw new Error(`Invalid scrcpyConfig.maxSize: expected a non-negative integer, received ${maxSize}`);
|
|
1085
1084
|
const videoBitRate = config?.videoBitRate ?? scrcpy_manager.ov.videoBitRate;
|
|
1086
1085
|
this.resolvedConfig = {
|
|
1087
1086
|
enabled: this.isConfigured(),
|
|
@@ -1091,24 +1090,6 @@ class ScrcpyDeviceAdapter {
|
|
|
1091
1090
|
};
|
|
1092
1091
|
return this.resolvedConfig;
|
|
1093
1092
|
}
|
|
1094
|
-
async prepareFallbackScreenshot(screenshotBase64) {
|
|
1095
|
-
if (!this.isConfigured()) return screenshotBase64;
|
|
1096
|
-
const { maxSize } = this.resolveConfig();
|
|
1097
|
-
if (0 === maxSize) return screenshotBase64;
|
|
1098
|
-
const sourceSize = await imageInfoOfBase64(screenshotBase64);
|
|
1099
|
-
const largestDimension = Math.max(sourceSize.width, sourceSize.height);
|
|
1100
|
-
if (largestDimension <= maxSize) return screenshotBase64;
|
|
1101
|
-
const scale = maxSize / largestDimension;
|
|
1102
|
-
const targetSize = {
|
|
1103
|
-
width: Math.max(1, Math.round(sourceSize.width * scale)),
|
|
1104
|
-
height: Math.max(1, Math.round(sourceSize.height * scale))
|
|
1105
|
-
};
|
|
1106
|
-
debugAdapter(`Applying scrcpy maxSize to fallback screenshot: ${sourceSize.width}x${sourceSize.height} -> ${targetSize.width}x${targetSize.height}`);
|
|
1107
|
-
return resizeBase64ImageToJpeg(screenshotBase64, {
|
|
1108
|
-
sourceSize,
|
|
1109
|
-
targetSize
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
1093
|
async ensureManager(deviceInfo) {
|
|
1113
1094
|
if (this.manager) return this.manager;
|
|
1114
1095
|
debugAdapter('Initializing Scrcpy manager...');
|
|
@@ -1121,7 +1102,7 @@ class ScrcpyDeviceAdapter {
|
|
|
1121
1102
|
const adb = new Adb(await adbClient.createTransport({
|
|
1122
1103
|
serial: this.deviceId
|
|
1123
1104
|
}));
|
|
1124
|
-
const config = this.resolveConfig();
|
|
1105
|
+
const config = this.resolveConfig(deviceInfo);
|
|
1125
1106
|
const manager = new ScrcpyManager(adb, {
|
|
1126
1107
|
maxSize: config.maxSize,
|
|
1127
1108
|
videoBitRate: config.videoBitRate,
|
|
@@ -2172,9 +2153,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2172
2153
|
}
|
|
2173
2154
|
async screenshotBase64() {
|
|
2174
2155
|
debugDevice('screenshotBase64 begin');
|
|
2175
|
-
const adapter = this.getScrcpyAdapter();
|
|
2176
2156
|
const screenshotStrategy = this.options?.screenshotStrategy || globalConfigManager.getEnvConfigValue(MIDSCENE_ANDROID_SCREENSHOT_STRATEGY) || SCREENSHOT_STRATEGY_AUTO;
|
|
2177
|
-
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return
|
|
2157
|
+
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return this.screenshotBase64ViaYadb();
|
|
2158
|
+
const adapter = this.getScrcpyAdapter();
|
|
2178
2159
|
let scrcpyDeviceInfo = null;
|
|
2179
2160
|
if (adapter.isEnabled()) try {
|
|
2180
2161
|
debugDevice('Attempting scrcpy screenshot...');
|
|
@@ -2225,14 +2206,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2225
2206
|
});
|
|
2226
2207
|
debugDevice('screenshotBase64 end (fallback)');
|
|
2227
2208
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2228
|
-
return
|
|
2209
|
+
return result;
|
|
2229
2210
|
}
|
|
2230
2211
|
if (!screenshotBuffer) throw new Error('Failed to capture screenshot: all methods failed');
|
|
2231
2212
|
debugDevice('Converting to base64');
|
|
2232
2213
|
const result = createImgBase64ByFormat('png', screenshotBuffer.toString('base64'));
|
|
2233
2214
|
debugDevice('screenshotBase64 end');
|
|
2234
2215
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2235
|
-
return
|
|
2216
|
+
return result;
|
|
2236
2217
|
}
|
|
2237
2218
|
async captureScreenshotBase64FromDeviceFile(label, capture) {
|
|
2238
2219
|
const adb = await this.getAdb();
|
|
@@ -3193,7 +3174,7 @@ class AndroidMidsceneTools extends BaseMidsceneTools {
|
|
|
3193
3174
|
const tools = new AndroidMidsceneTools();
|
|
3194
3175
|
runToolsCLI(tools, 'midscene-android', {
|
|
3195
3176
|
stripPrefix: 'android_',
|
|
3196
|
-
version: "1.
|
|
3177
|
+
version: "1.12.0",
|
|
3197
3178
|
extraCommands: createReportCliCommands()
|
|
3198
3179
|
}).catch((e)=>{
|
|
3199
3180
|
process.exit(reportCLIError(e));
|
package/dist/es/index.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import { getMidsceneLocationSchema, z } from "@midscene/core";
|
|
|
8
8
|
import { createDefaultMobileActions, defineAction } from "@midscene/core/device";
|
|
9
9
|
import { getTmpFile, sleep } from "@midscene/core/utils";
|
|
10
10
|
import { MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, MIDSCENE_ANDROID_SCREENSHOT_STRATEGY, globalConfigManager, overrideAIConfig } from "@midscene/shared/env";
|
|
11
|
-
import { createImgBase64ByFormat,
|
|
11
|
+
import { createImgBase64ByFormat, validateScreenshotBuffer } from "@midscene/shared/img";
|
|
12
12
|
import { mergeAndNormalizeAppNameMapping, normalizeForComparison, repeat } from "@midscene/shared/utils";
|
|
13
13
|
import { ADB, getSdkRootFromEnv } from "appium-adb";
|
|
14
14
|
import { Agent } from "@midscene/core/agent";
|
|
@@ -980,11 +980,10 @@ class ScrcpyDeviceAdapter {
|
|
|
980
980
|
if (null === this.retryAfter || Date.now() >= this.retryAfter) return;
|
|
981
981
|
throw new Error(`scrcpy retry is cooling down until ${new Date(this.retryAfter).toISOString()}. Last error: ${this.lastError}`);
|
|
982
982
|
}
|
|
983
|
-
resolveConfig() {
|
|
983
|
+
resolveConfig(deviceInfo) {
|
|
984
984
|
if (this.resolvedConfig) return this.resolvedConfig;
|
|
985
985
|
const config = this.scrcpyConfig;
|
|
986
986
|
const maxSize = config?.maxSize ?? scrcpy_manager.ov.maxSize;
|
|
987
|
-
if (!Number.isInteger(maxSize) || maxSize < 0) throw new Error(`Invalid scrcpyConfig.maxSize: expected a non-negative integer, received ${maxSize}`);
|
|
988
987
|
const videoBitRate = config?.videoBitRate ?? scrcpy_manager.ov.videoBitRate;
|
|
989
988
|
this.resolvedConfig = {
|
|
990
989
|
enabled: this.isConfigured(),
|
|
@@ -994,24 +993,6 @@ class ScrcpyDeviceAdapter {
|
|
|
994
993
|
};
|
|
995
994
|
return this.resolvedConfig;
|
|
996
995
|
}
|
|
997
|
-
async prepareFallbackScreenshot(screenshotBase64) {
|
|
998
|
-
if (!this.isConfigured()) return screenshotBase64;
|
|
999
|
-
const { maxSize } = this.resolveConfig();
|
|
1000
|
-
if (0 === maxSize) return screenshotBase64;
|
|
1001
|
-
const sourceSize = await imageInfoOfBase64(screenshotBase64);
|
|
1002
|
-
const largestDimension = Math.max(sourceSize.width, sourceSize.height);
|
|
1003
|
-
if (largestDimension <= maxSize) return screenshotBase64;
|
|
1004
|
-
const scale = maxSize / largestDimension;
|
|
1005
|
-
const targetSize = {
|
|
1006
|
-
width: Math.max(1, Math.round(sourceSize.width * scale)),
|
|
1007
|
-
height: Math.max(1, Math.round(sourceSize.height * scale))
|
|
1008
|
-
};
|
|
1009
|
-
debugAdapter(`Applying scrcpy maxSize to fallback screenshot: ${sourceSize.width}x${sourceSize.height} -> ${targetSize.width}x${targetSize.height}`);
|
|
1010
|
-
return resizeBase64ImageToJpeg(screenshotBase64, {
|
|
1011
|
-
sourceSize,
|
|
1012
|
-
targetSize
|
|
1013
|
-
});
|
|
1014
|
-
}
|
|
1015
996
|
async ensureManager(deviceInfo) {
|
|
1016
997
|
if (this.manager) return this.manager;
|
|
1017
998
|
debugAdapter('Initializing Scrcpy manager...');
|
|
@@ -1024,7 +1005,7 @@ class ScrcpyDeviceAdapter {
|
|
|
1024
1005
|
const adb = new Adb(await adbClient.createTransport({
|
|
1025
1006
|
serial: this.deviceId
|
|
1026
1007
|
}));
|
|
1027
|
-
const config = this.resolveConfig();
|
|
1008
|
+
const config = this.resolveConfig(deviceInfo);
|
|
1028
1009
|
const manager = new ScrcpyManager(adb, {
|
|
1029
1010
|
maxSize: config.maxSize,
|
|
1030
1011
|
videoBitRate: config.videoBitRate,
|
|
@@ -2075,9 +2056,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2075
2056
|
}
|
|
2076
2057
|
async screenshotBase64() {
|
|
2077
2058
|
debugDevice('screenshotBase64 begin');
|
|
2078
|
-
const adapter = this.getScrcpyAdapter();
|
|
2079
2059
|
const screenshotStrategy = this.options?.screenshotStrategy || globalConfigManager.getEnvConfigValue(MIDSCENE_ANDROID_SCREENSHOT_STRATEGY) || SCREENSHOT_STRATEGY_AUTO;
|
|
2080
|
-
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return
|
|
2060
|
+
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return this.screenshotBase64ViaYadb();
|
|
2061
|
+
const adapter = this.getScrcpyAdapter();
|
|
2081
2062
|
let scrcpyDeviceInfo = null;
|
|
2082
2063
|
if (adapter.isEnabled()) try {
|
|
2083
2064
|
debugDevice('Attempting scrcpy screenshot...');
|
|
@@ -2128,14 +2109,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2128
2109
|
});
|
|
2129
2110
|
debugDevice('screenshotBase64 end (fallback)');
|
|
2130
2111
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2131
|
-
return
|
|
2112
|
+
return result;
|
|
2132
2113
|
}
|
|
2133
2114
|
if (!screenshotBuffer) throw new Error('Failed to capture screenshot: all methods failed');
|
|
2134
2115
|
debugDevice('Converting to base64');
|
|
2135
2116
|
const result = createImgBase64ByFormat('png', screenshotBuffer.toString('base64'));
|
|
2136
2117
|
debugDevice('screenshotBase64 end');
|
|
2137
2118
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2138
|
-
return
|
|
2119
|
+
return result;
|
|
2139
2120
|
}
|
|
2140
2121
|
async captureScreenshotBase64FromDeviceFile(label, capture) {
|
|
2141
2122
|
const adb = await this.getAdb();
|
package/dist/lib/cli.js
CHANGED
|
@@ -1092,11 +1092,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1092
1092
|
if (null === this.retryAfter || Date.now() >= this.retryAfter) return;
|
|
1093
1093
|
throw new Error(`scrcpy retry is cooling down until ${new Date(this.retryAfter).toISOString()}. Last error: ${this.lastError}`);
|
|
1094
1094
|
}
|
|
1095
|
-
resolveConfig() {
|
|
1095
|
+
resolveConfig(deviceInfo) {
|
|
1096
1096
|
if (this.resolvedConfig) return this.resolvedConfig;
|
|
1097
1097
|
const config = this.scrcpyConfig;
|
|
1098
1098
|
const maxSize = config?.maxSize ?? scrcpy_manager.ov.maxSize;
|
|
1099
|
-
if (!Number.isInteger(maxSize) || maxSize < 0) throw new Error(`Invalid scrcpyConfig.maxSize: expected a non-negative integer, received ${maxSize}`);
|
|
1100
1099
|
const videoBitRate = config?.videoBitRate ?? scrcpy_manager.ov.videoBitRate;
|
|
1101
1100
|
this.resolvedConfig = {
|
|
1102
1101
|
enabled: this.isConfigured(),
|
|
@@ -1106,24 +1105,6 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1106
1105
|
};
|
|
1107
1106
|
return this.resolvedConfig;
|
|
1108
1107
|
}
|
|
1109
|
-
async prepareFallbackScreenshot(screenshotBase64) {
|
|
1110
|
-
if (!this.isConfigured()) return screenshotBase64;
|
|
1111
|
-
const { maxSize } = this.resolveConfig();
|
|
1112
|
-
if (0 === maxSize) return screenshotBase64;
|
|
1113
|
-
const sourceSize = await (0, img_namespaceObject.imageInfoOfBase64)(screenshotBase64);
|
|
1114
|
-
const largestDimension = Math.max(sourceSize.width, sourceSize.height);
|
|
1115
|
-
if (largestDimension <= maxSize) return screenshotBase64;
|
|
1116
|
-
const scale = maxSize / largestDimension;
|
|
1117
|
-
const targetSize = {
|
|
1118
|
-
width: Math.max(1, Math.round(sourceSize.width * scale)),
|
|
1119
|
-
height: Math.max(1, Math.round(sourceSize.height * scale))
|
|
1120
|
-
};
|
|
1121
|
-
debugAdapter(`Applying scrcpy maxSize to fallback screenshot: ${sourceSize.width}x${sourceSize.height} -> ${targetSize.width}x${targetSize.height}`);
|
|
1122
|
-
return (0, img_namespaceObject.resizeBase64ImageToJpeg)(screenshotBase64, {
|
|
1123
|
-
sourceSize,
|
|
1124
|
-
targetSize
|
|
1125
|
-
});
|
|
1126
|
-
}
|
|
1127
1108
|
async ensureManager(deviceInfo) {
|
|
1128
1109
|
if (this.manager) return this.manager;
|
|
1129
1110
|
debugAdapter('Initializing Scrcpy manager...');
|
|
@@ -1136,7 +1117,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1136
1117
|
const adb = new Adb(await adbClient.createTransport({
|
|
1137
1118
|
serial: this.deviceId
|
|
1138
1119
|
}));
|
|
1139
|
-
const config = this.resolveConfig();
|
|
1120
|
+
const config = this.resolveConfig(deviceInfo);
|
|
1140
1121
|
const manager = new ScrcpyManager(adb, {
|
|
1141
1122
|
maxSize: config.maxSize,
|
|
1142
1123
|
videoBitRate: config.videoBitRate,
|
|
@@ -2187,9 +2168,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2187
2168
|
}
|
|
2188
2169
|
async screenshotBase64() {
|
|
2189
2170
|
debugDevice('screenshotBase64 begin');
|
|
2190
|
-
const adapter = this.getScrcpyAdapter();
|
|
2191
2171
|
const screenshotStrategy = this.options?.screenshotStrategy || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ANDROID_SCREENSHOT_STRATEGY) || SCREENSHOT_STRATEGY_AUTO;
|
|
2192
|
-
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return
|
|
2172
|
+
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return this.screenshotBase64ViaYadb();
|
|
2173
|
+
const adapter = this.getScrcpyAdapter();
|
|
2193
2174
|
let scrcpyDeviceInfo = null;
|
|
2194
2175
|
if (adapter.isEnabled()) try {
|
|
2195
2176
|
debugDevice('Attempting scrcpy screenshot...');
|
|
@@ -2240,14 +2221,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2240
2221
|
});
|
|
2241
2222
|
debugDevice('screenshotBase64 end (fallback)');
|
|
2242
2223
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2243
|
-
return
|
|
2224
|
+
return result;
|
|
2244
2225
|
}
|
|
2245
2226
|
if (!screenshotBuffer) throw new Error('Failed to capture screenshot: all methods failed');
|
|
2246
2227
|
debugDevice('Converting to base64');
|
|
2247
2228
|
const result = (0, img_namespaceObject.createImgBase64ByFormat)('png', screenshotBuffer.toString('base64'));
|
|
2248
2229
|
debugDevice('screenshotBase64 end');
|
|
2249
2230
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2250
|
-
return
|
|
2231
|
+
return result;
|
|
2251
2232
|
}
|
|
2252
2233
|
async captureScreenshotBase64FromDeviceFile(label, capture) {
|
|
2253
2234
|
const adb = await this.getAdb();
|
|
@@ -3208,7 +3189,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
3208
3189
|
const tools = new AndroidMidsceneTools();
|
|
3209
3190
|
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-android', {
|
|
3210
3191
|
stripPrefix: 'android_',
|
|
3211
|
-
version: "1.
|
|
3192
|
+
version: "1.12.0",
|
|
3212
3193
|
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
3213
3194
|
}).catch((e)=>{
|
|
3214
3195
|
process.exit((0, cli_namespaceObject.reportCLIError)(e));
|
package/dist/lib/index.js
CHANGED
|
@@ -1013,11 +1013,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1013
1013
|
if (null === this.retryAfter || Date.now() >= this.retryAfter) return;
|
|
1014
1014
|
throw new Error(`scrcpy retry is cooling down until ${new Date(this.retryAfter).toISOString()}. Last error: ${this.lastError}`);
|
|
1015
1015
|
}
|
|
1016
|
-
resolveConfig() {
|
|
1016
|
+
resolveConfig(deviceInfo) {
|
|
1017
1017
|
if (this.resolvedConfig) return this.resolvedConfig;
|
|
1018
1018
|
const config = this.scrcpyConfig;
|
|
1019
1019
|
const maxSize = config?.maxSize ?? scrcpy_manager.ov.maxSize;
|
|
1020
|
-
if (!Number.isInteger(maxSize) || maxSize < 0) throw new Error(`Invalid scrcpyConfig.maxSize: expected a non-negative integer, received ${maxSize}`);
|
|
1021
1020
|
const videoBitRate = config?.videoBitRate ?? scrcpy_manager.ov.videoBitRate;
|
|
1022
1021
|
this.resolvedConfig = {
|
|
1023
1022
|
enabled: this.isConfigured(),
|
|
@@ -1027,24 +1026,6 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1027
1026
|
};
|
|
1028
1027
|
return this.resolvedConfig;
|
|
1029
1028
|
}
|
|
1030
|
-
async prepareFallbackScreenshot(screenshotBase64) {
|
|
1031
|
-
if (!this.isConfigured()) return screenshotBase64;
|
|
1032
|
-
const { maxSize } = this.resolveConfig();
|
|
1033
|
-
if (0 === maxSize) return screenshotBase64;
|
|
1034
|
-
const sourceSize = await (0, img_namespaceObject.imageInfoOfBase64)(screenshotBase64);
|
|
1035
|
-
const largestDimension = Math.max(sourceSize.width, sourceSize.height);
|
|
1036
|
-
if (largestDimension <= maxSize) return screenshotBase64;
|
|
1037
|
-
const scale = maxSize / largestDimension;
|
|
1038
|
-
const targetSize = {
|
|
1039
|
-
width: Math.max(1, Math.round(sourceSize.width * scale)),
|
|
1040
|
-
height: Math.max(1, Math.round(sourceSize.height * scale))
|
|
1041
|
-
};
|
|
1042
|
-
debugAdapter(`Applying scrcpy maxSize to fallback screenshot: ${sourceSize.width}x${sourceSize.height} -> ${targetSize.width}x${targetSize.height}`);
|
|
1043
|
-
return (0, img_namespaceObject.resizeBase64ImageToJpeg)(screenshotBase64, {
|
|
1044
|
-
sourceSize,
|
|
1045
|
-
targetSize
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
1029
|
async ensureManager(deviceInfo) {
|
|
1049
1030
|
if (this.manager) return this.manager;
|
|
1050
1031
|
debugAdapter('Initializing Scrcpy manager...');
|
|
@@ -1057,7 +1038,7 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
|
|
|
1057
1038
|
const adb = new Adb(await adbClient.createTransport({
|
|
1058
1039
|
serial: this.deviceId
|
|
1059
1040
|
}));
|
|
1060
|
-
const config = this.resolveConfig();
|
|
1041
|
+
const config = this.resolveConfig(deviceInfo);
|
|
1061
1042
|
const manager = new ScrcpyManager(adb, {
|
|
1062
1043
|
maxSize: config.maxSize,
|
|
1063
1044
|
videoBitRate: config.videoBitRate,
|
|
@@ -2108,9 +2089,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2108
2089
|
}
|
|
2109
2090
|
async screenshotBase64() {
|
|
2110
2091
|
debugDevice('screenshotBase64 begin');
|
|
2111
|
-
const adapter = this.getScrcpyAdapter();
|
|
2112
2092
|
const screenshotStrategy = this.options?.screenshotStrategy || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ANDROID_SCREENSHOT_STRATEGY) || SCREENSHOT_STRATEGY_AUTO;
|
|
2113
|
-
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return
|
|
2093
|
+
if (screenshotStrategy === SCREENSHOT_STRATEGY_ALWAYS_YADB) return this.screenshotBase64ViaYadb();
|
|
2094
|
+
const adapter = this.getScrcpyAdapter();
|
|
2114
2095
|
let scrcpyDeviceInfo = null;
|
|
2115
2096
|
if (adapter.isEnabled()) try {
|
|
2116
2097
|
debugDevice('Attempting scrcpy screenshot...');
|
|
@@ -2161,14 +2142,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
|
|
|
2161
2142
|
});
|
|
2162
2143
|
debugDevice('screenshotBase64 end (fallback)');
|
|
2163
2144
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2164
|
-
return
|
|
2145
|
+
return result;
|
|
2165
2146
|
}
|
|
2166
2147
|
if (!screenshotBuffer) throw new Error('Failed to capture screenshot: all methods failed');
|
|
2167
2148
|
debugDevice('Converting to base64');
|
|
2168
2149
|
const result = (0, img_namespaceObject.createImgBase64ByFormat)('png', screenshotBuffer.toString('base64'));
|
|
2169
2150
|
debugDevice('screenshotBase64 end');
|
|
2170
2151
|
if (scrcpyDeviceInfo) adapter.recoverAfterAdbScreenshot(scrcpyDeviceInfo);
|
|
2171
|
-
return
|
|
2152
|
+
return result;
|
|
2172
2153
|
}
|
|
2173
2154
|
async captureScreenshotBase64FromDeviceFile(label, capture) {
|
|
2174
2155
|
const adb = await this.getAdb();
|
package/dist/types/index.d.ts
CHANGED
|
@@ -451,13 +451,7 @@ export declare class ScrcpyDeviceAdapter {
|
|
|
451
451
|
* receives the highest quality image for AI processing.
|
|
452
452
|
* videoBitRate uses the shared default unless explicitly configured.
|
|
453
453
|
*/
|
|
454
|
-
resolveConfig(): ResolvedScrcpyConfig;
|
|
455
|
-
/**
|
|
456
|
-
* Apply the configured scrcpy video bound to an independently captured
|
|
457
|
-
* fallback screenshot. This prevents planning and report images from returning
|
|
458
|
-
* to full device resolution while the scrcpy stream is temporarily unavailable.
|
|
459
|
-
*/
|
|
460
|
-
prepareFallbackScreenshot(screenshotBase64: string): Promise<string>;
|
|
454
|
+
resolveConfig(deviceInfo: DevicePhysicalInfo): ResolvedScrcpyConfig;
|
|
461
455
|
/**
|
|
462
456
|
* Get or create the ScrcpyScreenshotManager.
|
|
463
457
|
* Uses dynamic import for @yume-chan packages (ESM-only, must use await import in CJS builds).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/android",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
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.1.0",
|
|
42
42
|
"appium-adb": "12.12.1",
|
|
43
43
|
"sharp": "^0.34.3",
|
|
44
|
-
"@midscene/core": "1.
|
|
45
|
-
"@midscene/shared": "1.
|
|
44
|
+
"@midscene/core": "1.12.0",
|
|
45
|
+
"@midscene/shared": "1.12.0"
|
|
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.
|
|
59
|
+
"@midscene/playground": "1.12.0"
|
|
60
60
|
},
|
|
61
61
|
"license": "MIT",
|
|
62
62
|
"scripts": {
|