@ph-qa/midscene-android 1.6.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/README.md +5 -0
- package/bin/.yadb-version +1 -0
- package/bin/midscene-android +2 -0
- package/bin/scrcpy-server +0 -0
- package/bin/scrcpy-server.version +1 -0
- package/bin/yadb +0 -0
- package/dist/es/cli.mjs +2087 -0
- package/dist/es/index.mjs +2146 -0
- package/dist/es/mcp-server.mjs +2109 -0
- package/dist/lib/cli.js +2107 -0
- package/dist/lib/index.js +2203 -0
- package/dist/lib/mcp-server.js +2151 -0
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/index.d.ts +454 -0
- package/dist/types/mcp-server.d.ts +279 -0
- package/package.json +76 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { }
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { AbstractInterface } from '@midscene/core/device';
|
|
2
|
+
import type { ActionParam } from '@midscene/core';
|
|
3
|
+
import type { ActionReturn } from '@midscene/core';
|
|
4
|
+
import { ADB } from 'appium-adb';
|
|
5
|
+
import type { Adb } from '@yume-chan/adb';
|
|
6
|
+
import { Agent } from '@midscene/core/agent';
|
|
7
|
+
import { AgentOpt } from '@midscene/core/agent';
|
|
8
|
+
import { AndroidDeviceInputOpt } from '@midscene/core/device';
|
|
9
|
+
import { AndroidDeviceOpt } from '@midscene/core/device';
|
|
10
|
+
import { BaseMidsceneTools } from '@midscene/shared/mcp';
|
|
11
|
+
import { Device } from 'appium-adb';
|
|
12
|
+
import { DeviceAction } from '@midscene/core';
|
|
13
|
+
import type { ElementInfo } from '@midscene/shared/extractor';
|
|
14
|
+
import { InterfaceType } from '@midscene/core';
|
|
15
|
+
import { overrideAIConfig } from '@midscene/shared/env';
|
|
16
|
+
import { Point } from '@midscene/core';
|
|
17
|
+
import { Size } from '@midscene/core';
|
|
18
|
+
import { ToolDefinition } from '@midscene/shared/mcp';
|
|
19
|
+
|
|
20
|
+
declare type ActionArgs<T extends DeviceAction> = [ActionParam<T>] extends [undefined] ? [] : [ActionParam<T>];
|
|
21
|
+
|
|
22
|
+
export declare function agentFromAdbDevice(deviceId?: string, opts?: AndroidAgentOpt & AndroidDeviceOpt): Promise<AndroidAgent>;
|
|
23
|
+
|
|
24
|
+
export declare class AndroidAgent extends Agent<AndroidDevice> {
|
|
25
|
+
/**
|
|
26
|
+
* Trigger the system back operation on Android devices
|
|
27
|
+
*/
|
|
28
|
+
back: WrappedAction<DeviceActionAndroidBackButton>;
|
|
29
|
+
/**
|
|
30
|
+
* Trigger the system home operation on Android devices
|
|
31
|
+
*/
|
|
32
|
+
home: WrappedAction<DeviceActionAndroidHomeButton>;
|
|
33
|
+
/**
|
|
34
|
+
* Trigger the system recent apps operation on Android devices
|
|
35
|
+
*/
|
|
36
|
+
recentApps: WrappedAction<DeviceActionAndroidRecentAppsButton>;
|
|
37
|
+
/**
|
|
38
|
+
* User-provided app name to package name mapping
|
|
39
|
+
*/
|
|
40
|
+
private appNameMapping;
|
|
41
|
+
constructor(device: AndroidDevice, opts?: AndroidAgentOpt);
|
|
42
|
+
/**
|
|
43
|
+
* Launch an Android app or URL
|
|
44
|
+
* @param uri - App package name, URL, or app name to launch
|
|
45
|
+
*/
|
|
46
|
+
launch(uri: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Execute ADB shell command on Android device
|
|
49
|
+
* @param command - ADB shell command to execute
|
|
50
|
+
*/
|
|
51
|
+
runAdbShell(command: string): Promise<string>;
|
|
52
|
+
private createActionWrapper;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export declare type AndroidAgentOpt = AgentOpt & {
|
|
56
|
+
/**
|
|
57
|
+
* Custom mapping of app names to package names
|
|
58
|
+
* User-provided mappings will take precedence over default mappings
|
|
59
|
+
*/
|
|
60
|
+
appNameMapping?: Record<string, string>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export declare interface AndroidConnectedDevice extends Device {
|
|
64
|
+
model?: string;
|
|
65
|
+
brand?: string;
|
|
66
|
+
resolution?: string;
|
|
67
|
+
density?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare class AndroidDevice implements AbstractInterface {
|
|
71
|
+
private deviceId;
|
|
72
|
+
private yadbPushed;
|
|
73
|
+
private devicePixelRatio;
|
|
74
|
+
private devicePixelRatioInitialized;
|
|
75
|
+
private adb;
|
|
76
|
+
private connectingAdb;
|
|
77
|
+
private destroyed;
|
|
78
|
+
private description;
|
|
79
|
+
private customActions?;
|
|
80
|
+
private cachedScreenSize;
|
|
81
|
+
private cachedOrientation;
|
|
82
|
+
private cachedPhysicalDisplayId;
|
|
83
|
+
private scrcpyAdapter;
|
|
84
|
+
private appNameMapping;
|
|
85
|
+
private cachedAdjustScale;
|
|
86
|
+
private takeScreenshotFailCount;
|
|
87
|
+
private static readonly TAKE_SCREENSHOT_FAIL_THRESHOLD;
|
|
88
|
+
private uiautomatorProcess;
|
|
89
|
+
private uiautomatorConfirmedUnavailable;
|
|
90
|
+
private uiautomatorKnownHealthy;
|
|
91
|
+
interfaceType: InterfaceType;
|
|
92
|
+
uri: string | undefined;
|
|
93
|
+
options?: AndroidDeviceOpt;
|
|
94
|
+
actionSpace(): DeviceAction<any>[];
|
|
95
|
+
constructor(deviceId: string, options?: AndroidDeviceOpt);
|
|
96
|
+
describe(): string;
|
|
97
|
+
connect(): Promise<ADB>;
|
|
98
|
+
getAdb(): Promise<ADB>;
|
|
99
|
+
private createAdbProxy;
|
|
100
|
+
/**
|
|
101
|
+
* Get or create the scrcpy adapter (lazy initialization)
|
|
102
|
+
*/
|
|
103
|
+
private getScrcpyAdapter;
|
|
104
|
+
/**
|
|
105
|
+
* Get device physical info needed by scrcpy adapter
|
|
106
|
+
*/
|
|
107
|
+
private getDevicePhysicalInfo;
|
|
108
|
+
/**
|
|
109
|
+
* Set the app name to package name mapping
|
|
110
|
+
*/
|
|
111
|
+
setAppNameMapping(mapping: Record<string, string>): void;
|
|
112
|
+
/**
|
|
113
|
+
* Resolve app name to package name using the mapping
|
|
114
|
+
* Comparison is case-insensitive and ignores spaces, dashes, and underscores.
|
|
115
|
+
* Keys in appNameMapping are pre-normalized, so we only need to normalize the input.
|
|
116
|
+
* @param appName The app name to resolve
|
|
117
|
+
*/
|
|
118
|
+
private resolvePackageName;
|
|
119
|
+
launch(uri: string): Promise<AndroidDevice>;
|
|
120
|
+
execYadb(keyboardContent: string): Promise<void>;
|
|
121
|
+
getElementsInfo(): Promise<ElementInfo[]>;
|
|
122
|
+
getElementsNodeTree(): Promise<any>;
|
|
123
|
+
getScreenSize(): Promise<{
|
|
124
|
+
override: string;
|
|
125
|
+
physical: string;
|
|
126
|
+
orientation: number;
|
|
127
|
+
isCurrentOrientation?: boolean;
|
|
128
|
+
}>;
|
|
129
|
+
private initializeDevicePixelRatio;
|
|
130
|
+
getDisplayDensity(): Promise<number>;
|
|
131
|
+
getDisplayOrientation(): Promise<number>;
|
|
132
|
+
/**
|
|
133
|
+
* Get physical screen dimensions adjusted for current orientation.
|
|
134
|
+
* Swaps width/height when the device is in landscape and the reported
|
|
135
|
+
* dimensions do not already reflect the current orientation.
|
|
136
|
+
*/
|
|
137
|
+
private getOrientedPhysicalSize;
|
|
138
|
+
size(): Promise<Size>;
|
|
139
|
+
/**
|
|
140
|
+
* Compute and cache the coordinate adjustment scale by comparing
|
|
141
|
+
* physical dimensions with logical dimensions from size().
|
|
142
|
+
* Cached after first call; invalidated on destroy().
|
|
143
|
+
*/
|
|
144
|
+
private getAdjustScale;
|
|
145
|
+
/**
|
|
146
|
+
* Convert logical coordinates (from AI) back to physical coordinates (for ADB).
|
|
147
|
+
* The ratio is derived from size(), so overriding size() alone is sufficient.
|
|
148
|
+
*/
|
|
149
|
+
private adjustCoordinates;
|
|
150
|
+
/**
|
|
151
|
+
* Calculate the end point for scroll operations based on start point, scroll delta, and screen boundaries.
|
|
152
|
+
* This method ensures that scroll operations stay within screen bounds and maintain a minimum scroll distance
|
|
153
|
+
* for effective scrolling gestures on Android devices.
|
|
154
|
+
*
|
|
155
|
+
* @param start - The starting point of the scroll gesture
|
|
156
|
+
* @param deltaX - The horizontal scroll distance (positive = scroll right, negative = scroll left)
|
|
157
|
+
* @param deltaY - The vertical scroll distance (positive = scroll down, negative = scroll up)
|
|
158
|
+
* @param maxWidth - The maximum width boundary (screen width)
|
|
159
|
+
* @param maxHeight - The maximum height boundary (screen height)
|
|
160
|
+
* @returns The calculated end point for the scroll gesture
|
|
161
|
+
*/
|
|
162
|
+
private calculateScrollEndPoint;
|
|
163
|
+
screenshotBase64(): Promise<string>;
|
|
164
|
+
clearInput(element?: ElementInfo): Promise<void>;
|
|
165
|
+
forceScreenshot(path: string): Promise<void>;
|
|
166
|
+
url(): Promise<string>;
|
|
167
|
+
scrollUntilTop(startPoint?: Point): Promise<void>;
|
|
168
|
+
scrollUntilBottom(startPoint?: Point): Promise<void>;
|
|
169
|
+
scrollUntilLeft(startPoint?: Point): Promise<void>;
|
|
170
|
+
scrollUntilRight(startPoint?: Point): Promise<void>;
|
|
171
|
+
scrollUp(distance?: number, startPoint?: Point): Promise<void>;
|
|
172
|
+
scrollDown(distance?: number, startPoint?: Point): Promise<void>;
|
|
173
|
+
scrollLeft(distance?: number, startPoint?: Point): Promise<void>;
|
|
174
|
+
scrollRight(distance?: number, startPoint?: Point): Promise<void>;
|
|
175
|
+
ensureYadb(): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Check if text contains characters that may cause issues with ADB inputText.
|
|
178
|
+
* appium-adb's inputText has known bugs with certain characters:
|
|
179
|
+
* - Backslash causes broken shell quoting
|
|
180
|
+
* - Backtick is not escaped at all
|
|
181
|
+
* - Text containing both " and ' throws an error
|
|
182
|
+
* - Dollar sign can cause variable expansion issues
|
|
183
|
+
*
|
|
184
|
+
* For these characters, we route through yadb which handles them correctly
|
|
185
|
+
* via escapeForShell + double-quoted shell context.
|
|
186
|
+
*/
|
|
187
|
+
private shouldUseYadbForText;
|
|
188
|
+
keyboardType(text: string, options?: AndroidDeviceInputOpt): Promise<void>;
|
|
189
|
+
private normalizeKeyName;
|
|
190
|
+
keyboardPress(key: string): Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* Start the UIAutomator2 server process on the device.
|
|
193
|
+
*/
|
|
194
|
+
private startUIAutomatorProcess;
|
|
195
|
+
/**
|
|
196
|
+
* Ensure the UIAutomator2 HTTP server is alive and ready.
|
|
197
|
+
* Returns true if UIAutomator2 is ready to accept requests, false otherwise.
|
|
198
|
+
*/
|
|
199
|
+
private ensureUIAutomatorReady;
|
|
200
|
+
mouseClick(x: number, y: number): Promise<void>;
|
|
201
|
+
mouseDoubleClick(x: number, y: number): Promise<void>;
|
|
202
|
+
mouseMove(): Promise<void>;
|
|
203
|
+
mouseDrag(from: {
|
|
204
|
+
x: number;
|
|
205
|
+
y: number;
|
|
206
|
+
}, to: {
|
|
207
|
+
x: number;
|
|
208
|
+
y: number;
|
|
209
|
+
}, duration?: number): Promise<void>;
|
|
210
|
+
scroll(deltaX: number, deltaY: number, duration?: number): Promise<void>;
|
|
211
|
+
destroy(): Promise<void>;
|
|
212
|
+
/**
|
|
213
|
+
* Get the current time from the Android device.
|
|
214
|
+
* Returns the device's current timestamp in milliseconds.
|
|
215
|
+
* This is useful when the system time and device time are not synchronized.
|
|
216
|
+
*/
|
|
217
|
+
getTimestamp(): Promise<number>;
|
|
218
|
+
back(): Promise<void>;
|
|
219
|
+
home(): Promise<void>;
|
|
220
|
+
recentApps(): Promise<void>;
|
|
221
|
+
longPress(x: number, y: number, duration?: number): Promise<void>;
|
|
222
|
+
pullDown(startPoint?: Point, distance?: number, duration?: number): Promise<void>;
|
|
223
|
+
pullDrag(from: {
|
|
224
|
+
x: number;
|
|
225
|
+
y: number;
|
|
226
|
+
}, to: {
|
|
227
|
+
x: number;
|
|
228
|
+
y: number;
|
|
229
|
+
}, duration: number): Promise<void>;
|
|
230
|
+
pullUp(startPoint?: Point, distance?: number, duration?: number): Promise<void>;
|
|
231
|
+
private getDisplayArg;
|
|
232
|
+
getPhysicalDisplayId(): Promise<string | null>;
|
|
233
|
+
hideKeyboard(options?: AndroidDeviceInputOpt, timeoutMs?: number): Promise<boolean>;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Android-specific tools manager
|
|
238
|
+
* Extends BaseMidsceneTools to provide Android ADB device connection tools
|
|
239
|
+
*/
|
|
240
|
+
export declare class AndroidMidsceneTools extends BaseMidsceneTools<AndroidAgent> {
|
|
241
|
+
protected createTemporaryDevice(): AndroidDevice;
|
|
242
|
+
protected ensureAgent(deviceId?: string): Promise<AndroidAgent>;
|
|
243
|
+
/**
|
|
244
|
+
* Provide Android-specific platform tools
|
|
245
|
+
*/
|
|
246
|
+
protected preparePlatformTools(): ToolDefinition[];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
declare type DeviceActionAndroidBackButton = DeviceAction<undefined, void>;
|
|
250
|
+
|
|
251
|
+
declare type DeviceActionAndroidHomeButton = DeviceAction<undefined, void>;
|
|
252
|
+
|
|
253
|
+
declare type DeviceActionAndroidRecentAppsButton = DeviceAction<undefined, void>;
|
|
254
|
+
|
|
255
|
+
declare interface DevicePhysicalInfo {
|
|
256
|
+
physicalWidth: number;
|
|
257
|
+
physicalHeight: number;
|
|
258
|
+
dpr: number;
|
|
259
|
+
orientation: number;
|
|
260
|
+
isCurrentOrientation?: boolean;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export declare function getConnectedDevices(): Promise<Device[]>;
|
|
264
|
+
|
|
265
|
+
export declare function getConnectedDevicesWithDetails(): Promise<AndroidConnectedDevice[]>;
|
|
266
|
+
|
|
267
|
+
export { overrideAIConfig }
|
|
268
|
+
|
|
269
|
+
declare interface ResolvedScrcpyConfig {
|
|
270
|
+
enabled: boolean;
|
|
271
|
+
maxSize: number;
|
|
272
|
+
videoBitRate: number;
|
|
273
|
+
idleTimeoutMs: number;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
declare interface ScrcpyConfig {
|
|
277
|
+
enabled?: boolean;
|
|
278
|
+
maxSize?: number;
|
|
279
|
+
videoBitRate?: number;
|
|
280
|
+
idleTimeoutMs?: number;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Adapter that encapsulates all scrcpy-related logic for AndroidDevice.
|
|
285
|
+
* Handles config normalization, manager lifecycle, screenshot, and resolution.
|
|
286
|
+
*/
|
|
287
|
+
export declare class ScrcpyDeviceAdapter {
|
|
288
|
+
private deviceId;
|
|
289
|
+
private scrcpyConfig;
|
|
290
|
+
private manager;
|
|
291
|
+
private resolvedConfig;
|
|
292
|
+
private initFailed;
|
|
293
|
+
constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined);
|
|
294
|
+
isEnabled(): boolean;
|
|
295
|
+
/**
|
|
296
|
+
* Initialize scrcpy connection. Called once during device.connect().
|
|
297
|
+
* If initialization fails, marks scrcpy as permanently disabled (no further retries).
|
|
298
|
+
*/
|
|
299
|
+
initialize(deviceInfo: DevicePhysicalInfo): Promise<void>;
|
|
300
|
+
/**
|
|
301
|
+
* Resolve scrcpy config.
|
|
302
|
+
* maxSize defaults to 0 (no scaling, full physical resolution) so the Agent layer
|
|
303
|
+
* receives the highest quality image for AI processing.
|
|
304
|
+
* videoBitRate is auto-scaled based on physical pixel count to ensure
|
|
305
|
+
* sufficient quality for all-I-frame H.264 encoding.
|
|
306
|
+
*/
|
|
307
|
+
resolveConfig(deviceInfo: DevicePhysicalInfo): ResolvedScrcpyConfig;
|
|
308
|
+
/**
|
|
309
|
+
* Get or create the ScrcpyScreenshotManager.
|
|
310
|
+
* Uses dynamic import for @yume-chan packages (ESM-only, must use await import in CJS builds).
|
|
311
|
+
*/
|
|
312
|
+
ensureManager(deviceInfo: DevicePhysicalInfo): Promise<ScrcpyScreenshotManager>;
|
|
313
|
+
/**
|
|
314
|
+
* Take a screenshot via scrcpy, returns base64 string.
|
|
315
|
+
* Throws on failure (caller should fallback to ADB).
|
|
316
|
+
*/
|
|
317
|
+
screenshotBase64(deviceInfo: DevicePhysicalInfo): Promise<string>;
|
|
318
|
+
/**
|
|
319
|
+
* Get scrcpy's actual video resolution.
|
|
320
|
+
* Returns null if scrcpy is not connected yet.
|
|
321
|
+
*/
|
|
322
|
+
getResolution(): {
|
|
323
|
+
width: number;
|
|
324
|
+
height: number;
|
|
325
|
+
} | null;
|
|
326
|
+
/**
|
|
327
|
+
* Compute size from scrcpy resolution.
|
|
328
|
+
* Returns null if scrcpy is not connected.
|
|
329
|
+
*/
|
|
330
|
+
getSize(deviceInfo: DevicePhysicalInfo): Size | null;
|
|
331
|
+
/**
|
|
332
|
+
* Calculate the scaling ratio from physical to scrcpy resolution.
|
|
333
|
+
*/
|
|
334
|
+
getScalingRatio(physicalWidth: number): number | null;
|
|
335
|
+
disconnect(): Promise<void>;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
declare class ScrcpyScreenshotManager {
|
|
339
|
+
private adb;
|
|
340
|
+
private scrcpyClient;
|
|
341
|
+
private videoStream;
|
|
342
|
+
private spsHeader;
|
|
343
|
+
private idleTimer;
|
|
344
|
+
private isConnecting;
|
|
345
|
+
private isInitialized;
|
|
346
|
+
private options;
|
|
347
|
+
private ffmpegAvailable;
|
|
348
|
+
private keyframeResolvers;
|
|
349
|
+
private lastRawKeyframe;
|
|
350
|
+
private videoResolution;
|
|
351
|
+
private streamReader;
|
|
352
|
+
constructor(adb: Adb, options?: ScrcpyScreenshotOptions);
|
|
353
|
+
/**
|
|
354
|
+
* Validate environment prerequisites (ffmpeg, scrcpy-server, etc.)
|
|
355
|
+
* Must be called once after construction, before any screenshot operations.
|
|
356
|
+
* Throws if prerequisites are not met.
|
|
357
|
+
*/
|
|
358
|
+
validateEnvironment(): Promise<void>;
|
|
359
|
+
/**
|
|
360
|
+
* Ensure scrcpy connection is active
|
|
361
|
+
*/
|
|
362
|
+
ensureConnected(): Promise<void>;
|
|
363
|
+
/**
|
|
364
|
+
* Resolve path to scrcpy server binary
|
|
365
|
+
*/
|
|
366
|
+
private resolveServerBinPath;
|
|
367
|
+
/**
|
|
368
|
+
* Get ffmpeg executable path
|
|
369
|
+
* Priority: @ffmpeg-installer/ffmpeg > system ffmpeg
|
|
370
|
+
*/
|
|
371
|
+
private getFfmpegPath;
|
|
372
|
+
/**
|
|
373
|
+
* Consume video frames and keep latest frame
|
|
374
|
+
*/
|
|
375
|
+
private startFrameConsumer;
|
|
376
|
+
/**
|
|
377
|
+
* Main frame consumption loop
|
|
378
|
+
* Includes busy-loop detection: if reader.read() resolves too fast
|
|
379
|
+
* (e.g. broken stream returning immediately), we throttle to prevent 100% CPU.
|
|
380
|
+
*/
|
|
381
|
+
private consumeFramesLoop;
|
|
382
|
+
/**
|
|
383
|
+
* Process a single video packet from the scrcpy stream.
|
|
384
|
+
* With sendFrameMeta: true, the stream emits properly framed packets:
|
|
385
|
+
* - "configuration" packets contain SPS/PPS header data
|
|
386
|
+
* - "data" packets contain complete video frames with correct boundaries
|
|
387
|
+
* This avoids the frame-splitting issue that occurs with sendFrameMeta: false
|
|
388
|
+
* at high resolutions where raw chunks may not align with frame boundaries.
|
|
389
|
+
*/
|
|
390
|
+
private processFrame;
|
|
391
|
+
/**
|
|
392
|
+
* Get screenshot as JPEG.
|
|
393
|
+
* Tries to get a fresh frame within a short timeout. If the screen is static
|
|
394
|
+
* (no new frames arrive), falls back to the latest cached keyframe.
|
|
395
|
+
*/
|
|
396
|
+
getScreenshotJpeg(): Promise<Buffer>;
|
|
397
|
+
/**
|
|
398
|
+
* Get the actual video stream resolution
|
|
399
|
+
* Returns null if scrcpy is not connected yet
|
|
400
|
+
*/
|
|
401
|
+
getResolution(): {
|
|
402
|
+
width: number;
|
|
403
|
+
height: number;
|
|
404
|
+
} | null;
|
|
405
|
+
/**
|
|
406
|
+
* Notify all pending keyframe waiters
|
|
407
|
+
*/
|
|
408
|
+
private notifyKeyframeWaiters;
|
|
409
|
+
/**
|
|
410
|
+
* Wait for the next keyframe to arrive
|
|
411
|
+
*/
|
|
412
|
+
private waitForNextKeyframe;
|
|
413
|
+
/**
|
|
414
|
+
* Ensure ffmpeg is available for PNG conversion
|
|
415
|
+
*/
|
|
416
|
+
private ensureFfmpegAvailable;
|
|
417
|
+
/**
|
|
418
|
+
* Wait for first keyframe with SPS/PPS header
|
|
419
|
+
*/
|
|
420
|
+
private waitForKeyframe;
|
|
421
|
+
/**
|
|
422
|
+
* Check if ffmpeg is available in the system
|
|
423
|
+
*/
|
|
424
|
+
private checkFfmpegAvailable;
|
|
425
|
+
/**
|
|
426
|
+
* Decode H.264 data to JPEG using ffmpeg
|
|
427
|
+
*/
|
|
428
|
+
private decodeH264ToJpeg;
|
|
429
|
+
/**
|
|
430
|
+
* Reset idle timeout timer
|
|
431
|
+
*/
|
|
432
|
+
private resetIdleTimer;
|
|
433
|
+
/**
|
|
434
|
+
* Disconnect scrcpy
|
|
435
|
+
*/
|
|
436
|
+
disconnect(): Promise<void>;
|
|
437
|
+
/**
|
|
438
|
+
* Check if scrcpy is initialized and connected
|
|
439
|
+
*/
|
|
440
|
+
isConnected(): boolean;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
declare interface ScrcpyScreenshotOptions {
|
|
444
|
+
maxSize?: number;
|
|
445
|
+
videoBitRate?: number;
|
|
446
|
+
idleTimeoutMs?: number;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Helper type to convert DeviceAction to wrapped method signature
|
|
451
|
+
*/
|
|
452
|
+
declare type WrappedAction<T extends DeviceAction> = (...args: ActionArgs<T>) => Promise<ActionReturn<T>>;
|
|
453
|
+
|
|
454
|
+
export { }
|