UNPKG

@u4/adbkit

Version:

A Typescript client for the Android Debug Bridge.

172 lines 5.96 kB
import EventEmitter from 'node:events'; import { Buffer } from 'node:buffer'; import PromiseDuplex from 'promise-duplex'; import DeviceClient from '../../DeviceClient.js'; import { Duplex } from 'node:stream'; import { type MotionEvent } from './ScrcpyConst.js'; import { KeyCodes } from '../../keycode.js'; import { Point, ScrcpyOptions, H264Configuration, VideoStreamFramePacket } from './ScrcpyModels.js'; /** * usage reference fron app/src/server.c in scrcpy * https://github.com/Genymobile/scrcpy/blob/master/app/src/server.c */ /** * by hand start: * * adb push scrcpy-server-v1.8.jar /data/local/tmp/scrcpy-server.jar * adb push scrcpy-server-v1.20.jar /data/local/tmp/scrcpy-server.jar * * CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 600 1000 true 9999:9999:0:0 true * * adb forward tcp:8099 localabstract:scrcpy */ /** * enforce EventEmitter typing */ interface IEmissions { frame: (data: VideoStreamFramePacket) => void; config: (data: H264Configuration) => void; raw: (data: Buffer) => void; error: (error: Error) => void; disconnect: () => void; } /** * How scrcpy works? * * Its a jar file that runs on an adb shell. It records the screen in h264 and offers it in a given tcp port. * * scrcpy params * maxSize (integer, multiple of 8) 0 * bitRate (integer) * tunnelForward (optional, bool) use "adb forward" instead of "adb tunnel" * crop (optional, string) "width:height:x:y" * sendFrameMeta (optional, bool) * * The video stream contains raw packets, without time information. If sendFrameMeta is enabled a meta header is added * before each packet. * The "meta" header length is 12 bytes * [. . . . . . . .|. . . .]. . . . . . . . . . . . . . . ... * <-------------> <-----> <-----------------------------... * PTS size raw packet (of size len) * * WARNING: * Need USB Debug checked in developper option for MIUI */ export default class Scrcpy extends EventEmitter { private client; private config; private videoSocket; private audioSocket; private controlSocket; /** * used to recive Process Error */ private scrcpyServer; private _name; private _codec; private _width; private _height; private _onTermination; private _firstFrame; private setCodec; private setName; private setWidth; private setHeight; private setFatalError?; private setFirstFrame?; private lastConf?; /** * closed had been call stop all new activity */ private closed; constructor(client: DeviceClient, config?: Partial<ScrcpyOptions>); readonly strVersion: string; readonly major: number; readonly minor: number; readonly patch: number; on: <K extends keyof IEmissions>(event: K, listener: IEmissions[K]) => this; off: <K extends keyof IEmissions>(event: K, listener: IEmissions[K]) => this; once: <K extends keyof IEmissions>(event: K, listener: IEmissions[K]) => this; emit: <K extends keyof IEmissions>(event: K, ...args: Parameters<IEmissions[K]>) => boolean; get name(): Promise<string>; get width(): Promise<number>; get height(): Promise<number>; /** * Clever way to detect Termination. * return the Ending message. */ get onTermination(): Promise<string>; /** * Promise to the first emited frame * can be used to unsure that scrcpy propery start */ get firstFrame(): Promise<void>; /** * return the used codex can be "H264", "H265", "AV1", "AAC" or "OPUS" */ get codec(): Promise<string>; /** * emit scrcpyServer output as Error * @param duplex * @returns */ ListenErrors(duplex: PromiseDuplex<Duplex>): Promise<void>; private _setFatalError; /** * get last current video config */ get videoConfig(): H264Configuration | undefined; /** * Read a message from the contoler Duplex * * @param duplex only supoport clipboard * @returns */ readOneMessage(duplex: PromiseDuplex<Duplex>): Promise<string>; private _getStartupLine; /** * Will connect to the android device, send & run the server and return deviceName, width and height. * After that data will be offered as a 'data' event. */ start(): Promise<this>; stop(): boolean; isRunning(): boolean; private startStreamRaw; /** * capture all video trafique in a loop * get resolve once capture stop */ private startStreamWithMeta; /** * // will be convert in a android.view.KeyEvent * https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/KeyEvent.java * @param action * @param keyCode * @param repeatCount * @param metaState combinaison of KeyEventMeta */ injectKeycodeEvent(action: MotionEvent, keyCode: KeyCodes, repeatCount: number, metaState: number): Promise<void>; injectText(text: string): Promise<void>; /** * android.view.MotionEvent; * https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/MotionEvent.java * @param action * @param pointerId * @param position * @param screenSize * @param pressure * * see parseInjectTouchEvent() */ injectTouchEvent(action: MotionEvent, pointerId: bigint, position: Point, screenSize: Point, pressure?: number): Promise<boolean>; injectScrollEvent(position: Point, screenSize: Point, HScroll: number, VScroll: number): Promise<void>; injectBackOrScreenOn(): Promise<void>; expandNotificationPanel(): Promise<void>; collapsePannels(): Promise<void>; getClipboard(): Promise<string>; setClipboard(text: string): Promise<void>; setScreenPowerMode(): Promise<void>; rotateDevice(): Promise<void>; } export {}; //# sourceMappingURL=Scrcpy.d.ts.map