@yume-chan/scrcpy 0.0.18 → 0.0.20
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/CHANGELOG.json +33 -0
- package/CHANGELOG.md +18 -1
- package/README.md +157 -183
- package/bin/scrcpy-server +0 -0
- package/bin/version.d.ts +1 -1
- package/bin/version.js +1 -1
- package/esm/codec/av1.d.ts +33 -0
- package/esm/codec/av1.d.ts.map +1 -0
- package/esm/codec/av1.js +35 -0
- package/esm/codec/av1.js.map +1 -0
- package/esm/codec/h264.d.ts +78 -0
- package/esm/codec/h264.d.ts.map +1 -0
- package/esm/codec/h264.js +256 -0
- package/esm/codec/h264.js.map +1 -0
- package/esm/codec/h265.d.ts +490 -0
- package/esm/codec/h265.d.ts.map +1 -0
- package/esm/codec/h265.js +1098 -0
- package/esm/codec/h265.js.map +1 -0
- package/esm/codec/index.d.ts +5 -0
- package/esm/codec/index.d.ts.map +1 -0
- package/esm/codec/index.js +5 -0
- package/esm/codec/index.js.map +1 -0
- package/esm/codec/nalu.d.ts +44 -0
- package/esm/codec/nalu.d.ts.map +1 -0
- package/esm/codec/nalu.js +310 -0
- package/esm/codec/nalu.js.map +1 -0
- package/esm/control/back-or-screen-on.d.ts +2 -2
- package/esm/control/back-or-screen-on.d.ts.map +1 -1
- package/esm/control/back-or-screen-on.js +1 -1
- package/esm/control/basic.d.ts +5 -0
- package/esm/control/basic.d.ts.map +1 -0
- package/esm/control/basic.js +3 -0
- package/esm/control/basic.js.map +1 -0
- package/esm/control/hover-helper.d.ts +17 -17
- package/esm/control/hover-helper.d.ts.map +1 -1
- package/esm/control/hover-helper.js +43 -43
- package/esm/control/hover-helper.js.map +1 -1
- package/esm/control/index.d.ts +13 -11
- package/esm/control/index.d.ts.map +1 -1
- package/esm/control/index.js +13 -11
- package/esm/control/index.js.map +1 -1
- package/esm/control/inject-keycode.d.ts +193 -60
- package/esm/control/inject-keycode.d.ts.map +1 -1
- package/esm/control/inject-keycode.js +198 -61
- package/esm/control/inject-keycode.js.map +1 -1
- package/esm/control/inject-scroll.d.ts +2 -2
- package/esm/control/inject-scroll.d.ts.map +1 -1
- package/esm/control/inject-scroll.js +1 -1
- package/esm/control/inject-text.d.ts +7 -8
- package/esm/control/inject-text.d.ts.map +1 -1
- package/esm/control/inject-text.js +5 -6
- package/esm/control/inject-text.js.map +1 -1
- package/esm/control/inject-touch.d.ts +32 -37
- package/esm/control/inject-touch.d.ts.map +1 -1
- package/esm/control/inject-touch.js +35 -62
- package/esm/control/inject-touch.js.map +1 -1
- package/esm/control/rotate-device.d.ts +4 -6
- package/esm/control/rotate-device.d.ts.map +1 -1
- package/esm/control/rotate-device.js +2 -4
- package/esm/control/rotate-device.js.map +1 -1
- package/esm/control/serializer.d.ts +25 -33
- package/esm/control/serializer.d.ts.map +1 -1
- package/esm/control/serializer.js +53 -78
- package/esm/control/serializer.js.map +1 -1
- package/esm/control/set-clipboard.d.ts +2 -2
- package/esm/control/set-clipboard.d.ts.map +1 -1
- package/esm/control/set-clipboard.js +1 -1
- package/esm/control/set-screen-power-mode.d.ts +10 -11
- package/esm/control/set-screen-power-mode.d.ts.map +1 -1
- package/esm/control/set-screen-power-mode.js +10 -11
- package/esm/control/set-screen-power-mode.js.map +1 -1
- package/esm/control/type.d.ts +28 -14
- package/esm/control/type.d.ts.map +1 -1
- package/esm/control/type.js +40 -18
- package/esm/control/type.js.map +1 -1
- package/esm/control/writer.d.ts +28 -0
- package/esm/control/writer.d.ts.map +1 -0
- package/esm/control/writer.js +53 -0
- package/esm/control/writer.js.map +1 -0
- package/esm/device-message/ack-clipboard.d.ts +8 -8
- package/esm/device-message/ack-clipboard.d.ts.map +1 -1
- package/esm/device-message/ack-clipboard.js +5 -5
- package/esm/device-message/clipboard.d.ts +9 -9
- package/esm/device-message/clipboard.d.ts.map +1 -1
- package/esm/device-message/clipboard.js +6 -6
- package/esm/device-message/index.d.ts +4 -4
- package/esm/device-message/index.js +4 -4
- package/esm/device-message/stream.d.ts +7 -7
- package/esm/device-message/stream.d.ts.map +1 -1
- package/esm/device-message/stream.js +34 -19
- package/esm/device-message/stream.js.map +1 -1
- package/esm/device-message/type.d.ts +4 -4
- package/esm/device-message/type.js +6 -6
- package/esm/index.d.ts +4 -5
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +4 -5
- package/esm/index.js.map +1 -1
- package/esm/options/1_16/codec-options.d.ts +19 -19
- package/esm/options/1_16/codec-options.d.ts.map +1 -1
- package/esm/options/1_16/codec-options.js +25 -25
- package/esm/options/1_16/codec-options.js.map +1 -1
- package/esm/options/1_16/float-to-uint16.d.ts +5 -0
- package/esm/options/1_16/float-to-uint16.d.ts.map +1 -0
- package/esm/options/1_16/float-to-uint16.js +27 -0
- package/esm/options/1_16/float-to-uint16.js.map +1 -0
- package/esm/options/1_16/index.d.ts +6 -4
- package/esm/options/1_16/index.d.ts.map +1 -1
- package/esm/options/1_16/index.js +6 -4
- package/esm/options/1_16/index.js.map +1 -1
- package/esm/options/1_16/init.d.ts +66 -0
- package/esm/options/1_16/init.d.ts.map +1 -0
- package/esm/options/1_16/init.js +16 -0
- package/esm/options/1_16/init.js.map +1 -0
- package/esm/options/1_16/message.d.ts +32 -0
- package/esm/options/1_16/message.d.ts.map +1 -0
- package/esm/options/1_16/message.js +37 -0
- package/esm/options/1_16/message.js.map +1 -0
- package/esm/options/1_16/options.d.ts +48 -93
- package/esm/options/1_16/options.d.ts.map +1 -1
- package/esm/options/1_16/options.js +152 -189
- package/esm/options/1_16/options.js.map +1 -1
- package/esm/options/1_16/scroll.d.ts +26 -26
- package/esm/options/1_16/scroll.d.ts.map +1 -1
- package/esm/options/1_16/scroll.js +54 -55
- package/esm/options/1_16/scroll.js.map +1 -1
- package/esm/options/1_17.d.ts +33 -0
- package/esm/options/1_17.d.ts.map +1 -0
- package/esm/options/1_17.js +42 -0
- package/esm/options/1_17.js.map +1 -0
- package/esm/options/1_18.d.ts +59 -19
- package/esm/options/1_18.d.ts.map +1 -1
- package/esm/options/1_18.js +78 -45
- package/esm/options/1_18.js.map +1 -1
- package/esm/options/1_21.d.ts +41 -20
- package/esm/options/1_21.d.ts.map +1 -1
- package/esm/options/1_21.js +51 -36
- package/esm/options/1_21.js.map +1 -1
- package/esm/options/1_22/index.d.ts +3 -2
- package/esm/options/1_22/index.d.ts.map +1 -1
- package/esm/options/1_22/index.js +3 -2
- package/esm/options/1_22/index.js.map +1 -1
- package/esm/options/1_22/init.d.ts +17 -0
- package/esm/options/1_22/init.d.ts.map +1 -0
- package/esm/options/1_22/init.js +2 -0
- package/esm/options/1_22/init.js.map +1 -0
- package/esm/options/1_22/options.d.ts +35 -28
- package/esm/options/1_22/options.d.ts.map +1 -1
- package/esm/options/1_22/options.js +36 -25
- package/esm/options/1_22/options.js.map +1 -1
- package/esm/options/1_22/scroll.d.ts +16 -16
- package/esm/options/1_22/scroll.d.ts.map +1 -1
- package/esm/options/1_22/scroll.js +14 -14
- package/esm/options/1_23.d.ts +36 -11
- package/esm/options/1_23.d.ts.map +1 -1
- package/esm/options/1_23.js +44 -34
- package/esm/options/1_23.js.map +1 -1
- package/esm/options/1_24.d.ts +34 -8
- package/esm/options/1_24.d.ts.map +1 -1
- package/esm/options/1_24.js +22 -12
- package/esm/options/1_24.js.map +1 -1
- package/esm/options/1_25/index.d.ts +2 -2
- package/esm/options/1_25/index.js +2 -2
- package/esm/options/1_25/options.d.ts +10 -5
- package/esm/options/1_25/options.d.ts.map +1 -1
- package/esm/options/1_25/options.js +21 -7
- package/esm/options/1_25/options.js.map +1 -1
- package/esm/options/1_25/scroll.d.ts +19 -18
- package/esm/options/1_25/scroll.d.ts.map +1 -1
- package/esm/options/1_25/scroll.js +33 -32
- package/esm/options/1_25/scroll.js.map +1 -1
- package/esm/options/2_0.d.ts +91 -0
- package/esm/options/2_0.d.ts.map +1 -0
- package/esm/options/2_0.js +244 -0
- package/esm/options/2_0.js.map +1 -0
- package/esm/options/codec.d.ts +52 -0
- package/esm/options/codec.d.ts.map +1 -0
- package/esm/options/codec.js +26 -0
- package/esm/options/codec.js.map +1 -0
- package/esm/options/index.d.ts +12 -8
- package/esm/options/index.d.ts.map +1 -1
- package/esm/options/index.js +12 -8
- package/esm/options/index.js.map +1 -1
- package/esm/options/latest.d.ts +12 -0
- package/esm/options/latest.d.ts.map +1 -0
- package/esm/options/latest.js +8 -0
- package/esm/options/latest.js.map +1 -0
- package/esm/options/types.d.ts +86 -46
- package/esm/options/types.d.ts.map +1 -1
- package/esm/options/types.js +69 -17
- package/esm/options/types.js.map +1 -1
- package/package.json +10 -16
- package/src/codec/av1.ts +33 -0
- package/src/codec/h264.ts +317 -0
- package/src/codec/h265.ts +1375 -0
- package/src/codec/index.ts +4 -0
- package/src/codec/nalu.ts +373 -0
- package/src/control/back-or-screen-on.ts +1 -1
- package/src/control/basic.ts +3 -0
- package/src/control/hover-helper.ts +2 -4
- package/src/control/index.ts +2 -0
- package/src/control/inject-keycode.ts +194 -51
- package/src/control/inject-scroll.ts +1 -1
- package/src/control/inject-text.ts +6 -9
- package/src/control/inject-touch.ts +16 -55
- package/src/control/rotate-device.ts +3 -7
- package/src/control/serializer.ts +49 -105
- package/src/control/set-clipboard.ts +1 -1
- package/src/control/set-screen-power-mode.ts +6 -9
- package/src/control/type.ts +32 -0
- package/src/control/writer.ts +87 -0
- package/src/device-message/ack-clipboard.ts +1 -1
- package/src/device-message/clipboard.ts +1 -1
- package/src/device-message/stream.ts +32 -12
- package/src/index.ts +4 -5
- package/src/options/1_16/codec-options.ts +5 -8
- package/src/options/1_16/float-to-uint16.ts +33 -0
- package/src/options/1_16/index.ts +3 -1
- package/src/options/1_16/init.ts +80 -0
- package/src/options/1_16/message.ts +55 -0
- package/src/options/1_16/options.ts +152 -256
- package/src/options/1_16/scroll.ts +2 -5
- package/src/options/1_17.ts +66 -0
- package/src/options/1_18.ts +106 -42
- package/src/options/1_21.ts +51 -30
- package/src/options/1_22/index.ts +1 -0
- package/src/options/1_22/init.ts +19 -0
- package/src/options/1_22/options.ts +40 -46
- package/src/options/1_22/scroll.ts +2 -2
- package/src/options/1_23.ts +33 -23
- package/src/options/1_24.ts +25 -11
- package/src/options/1_25/options.ts +25 -6
- package/src/options/1_25/scroll.ts +5 -7
- package/src/options/2_0.ts +342 -0
- package/src/options/codec.ts +98 -0
- package/src/options/index.ts +7 -3
- package/src/options/latest.ts +14 -0
- package/src/options/types.ts +158 -48
- package/tsconfig.build.json +9 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/adb/client.d.ts +0 -41
- package/esm/adb/client.d.ts.map +0 -1
- package/esm/adb/client.js +0 -243
- package/esm/adb/client.js.map +0 -1
- package/esm/adb/connection.d.ts +0 -47
- package/esm/adb/connection.d.ts.map +0 -1
- package/esm/adb/connection.js +0 -110
- package/esm/adb/connection.js.map +0 -1
- package/esm/adb/index.d.ts +0 -4
- package/esm/adb/index.d.ts.map +0 -1
- package/esm/adb/index.js +0 -4
- package/esm/adb/index.js.map +0 -1
- package/esm/adb/options/1_16.d.ts +0 -8
- package/esm/adb/options/1_16.d.ts.map +0 -1
- package/esm/adb/options/1_16.js +0 -20
- package/esm/adb/options/1_16.js.map +0 -1
- package/esm/adb/options/1_22.d.ts +0 -8
- package/esm/adb/options/1_22.d.ts.map +0 -1
- package/esm/adb/options/1_22.js +0 -17
- package/esm/adb/options/1_22.js.map +0 -1
- package/esm/adb/options/index.d.ts +0 -4
- package/esm/adb/options/index.d.ts.map +0 -1
- package/esm/adb/options/index.js +0 -4
- package/esm/adb/options/index.js.map +0 -1
- package/esm/adb/options/types.d.ts +0 -24
- package/esm/adb/options/types.d.ts.map +0 -1
- package/esm/adb/options/types.js +0 -37
- package/esm/adb/options/types.js.map +0 -1
- package/esm/codec.d.ts +0 -34
- package/esm/codec.d.ts.map +0 -1
- package/esm/codec.js +0 -37
- package/esm/codec.js.map +0 -1
- package/esm/options/1_16/h264-configuration.d.ts +0 -49
- package/esm/options/1_16/h264-configuration.d.ts.map +0 -1
- package/esm/options/1_16/h264-configuration.js +0 -414
- package/esm/options/1_16/h264-configuration.js.map +0 -1
- package/esm/options/1_16/sps.d.ts +0 -22
- package/esm/options/1_16/sps.d.ts.map +0 -1
- package/esm/options/1_16/sps.js +0 -263
- package/esm/options/1_16/sps.js.map +0 -1
- package/src/adb/client.ts +0 -345
- package/src/adb/connection.ts +0 -192
- package/src/adb/index.ts +0 -3
- package/src/adb/options/1_16.ts +0 -30
- package/src/adb/options/1_22.ts +0 -26
- package/src/adb/options/index.ts +0 -3
- package/src/adb/options/types.ts +0 -75
- package/src/codec.ts +0 -35
- package/src/options/1_16/h264-configuration.ts +0 -485
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { CodecOptions } from "./codec-options.js";
|
|
2
|
+
|
|
3
|
+
export enum ScrcpyLogLevel1_16 {
|
|
4
|
+
Debug = "debug",
|
|
5
|
+
Info = "info",
|
|
6
|
+
Warn = "warn",
|
|
7
|
+
Error = "error",
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export enum ScrcpyVideoOrientation1_16 {
|
|
11
|
+
Unlocked = -1,
|
|
12
|
+
Portrait = 0,
|
|
13
|
+
Landscape = 1,
|
|
14
|
+
PortraitFlipped = 2,
|
|
15
|
+
LandscapeFlipped = 3,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ScrcpyOptionsInit1_16 {
|
|
19
|
+
logLevel?: ScrcpyLogLevel1_16;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The maximum value of both width and height.
|
|
23
|
+
*/
|
|
24
|
+
maxSize?: number;
|
|
25
|
+
|
|
26
|
+
bitRate?: number;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 0 for unlimited.
|
|
30
|
+
*
|
|
31
|
+
* @default 0
|
|
32
|
+
*/
|
|
33
|
+
maxFps?: number;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The orientation of the video stream.
|
|
37
|
+
*
|
|
38
|
+
* It will not keep the device screen in specific orientation,
|
|
39
|
+
* only the captured video will in this orientation.
|
|
40
|
+
*/
|
|
41
|
+
lockVideoOrientation?: ScrcpyVideoOrientation1_16;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Use ADB forward tunnel instead of reverse tunnel.
|
|
45
|
+
*
|
|
46
|
+
* This option is mainly used for working around the bug that on Android <9,
|
|
47
|
+
* ADB daemon can't create reverse tunnels if connected wirelessly (ADB over WiFi).
|
|
48
|
+
*
|
|
49
|
+
* When using `AdbScrcpyClient`, it can detect this situation and enable this option automatically.
|
|
50
|
+
*/
|
|
51
|
+
tunnelForward?: boolean;
|
|
52
|
+
|
|
53
|
+
crop?: string | undefined;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Send PTS so that the client may record properly
|
|
57
|
+
*
|
|
58
|
+
* Note: When `sendFrameMeta: false` is specified,
|
|
59
|
+
* the video stream will not contain `configuration` typed packets,
|
|
60
|
+
* which means it can't be decoded by the companion decoders.
|
|
61
|
+
* It's still possible to record the stream into a file,
|
|
62
|
+
* or to decode it with a more tolerant decoder like FFMpeg.
|
|
63
|
+
*
|
|
64
|
+
* @default true
|
|
65
|
+
*/
|
|
66
|
+
sendFrameMeta?: boolean;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
control?: boolean;
|
|
72
|
+
|
|
73
|
+
displayId?: number;
|
|
74
|
+
|
|
75
|
+
showTouches?: boolean;
|
|
76
|
+
|
|
77
|
+
stayAwake?: boolean;
|
|
78
|
+
|
|
79
|
+
codecOptions?: CodecOptions;
|
|
80
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import Struct, { placeholder } from "@yume-chan/struct";
|
|
2
|
+
|
|
3
|
+
import type { AndroidMotionEventAction } from "../../control/index.js";
|
|
4
|
+
import {
|
|
5
|
+
BasicControlMessage,
|
|
6
|
+
ScrcpyControlMessageType,
|
|
7
|
+
} from "../../control/index.js";
|
|
8
|
+
|
|
9
|
+
import { ScrcpyFloatToUint16FieldDefinition } from "./float-to-uint16.js";
|
|
10
|
+
|
|
11
|
+
export const SCRCPY_CONTROL_MESSAGE_TYPES_1_16: readonly ScrcpyControlMessageType[] =
|
|
12
|
+
[
|
|
13
|
+
/* 0 */ ScrcpyControlMessageType.InjectKeyCode,
|
|
14
|
+
/* 1 */ ScrcpyControlMessageType.InjectText,
|
|
15
|
+
/* 2 */ ScrcpyControlMessageType.InjectTouch,
|
|
16
|
+
/* 3 */ ScrcpyControlMessageType.InjectScroll,
|
|
17
|
+
/* 4 */ ScrcpyControlMessageType.BackOrScreenOn,
|
|
18
|
+
/* 5 */ ScrcpyControlMessageType.ExpandNotificationPanel,
|
|
19
|
+
/* 6 */ ScrcpyControlMessageType.CollapseNotificationPanel,
|
|
20
|
+
/* 7 */ ScrcpyControlMessageType.GetClipboard,
|
|
21
|
+
/* 8 */ ScrcpyControlMessageType.SetClipboard,
|
|
22
|
+
/* 9 */ ScrcpyControlMessageType.SetScreenPowerMode,
|
|
23
|
+
/* 10 */ ScrcpyControlMessageType.RotateDevice,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export const ScrcpyMediaStreamRawPacket = new Struct()
|
|
27
|
+
.uint64("pts")
|
|
28
|
+
.uint32("size")
|
|
29
|
+
.uint8Array("data", { lengthField: "size" });
|
|
30
|
+
|
|
31
|
+
export const SCRCPY_MEDIA_PACKET_FLAG_CONFIG = 1n << 63n;
|
|
32
|
+
|
|
33
|
+
export const ScrcpyInjectTouchControlMessage1_16 = new Struct()
|
|
34
|
+
.uint8("type")
|
|
35
|
+
.uint8("action", placeholder<AndroidMotionEventAction>())
|
|
36
|
+
.uint64("pointerId")
|
|
37
|
+
.uint32("pointerX")
|
|
38
|
+
.uint32("pointerY")
|
|
39
|
+
.uint16("screenWidth")
|
|
40
|
+
.uint16("screenHeight")
|
|
41
|
+
.field("pressure", ScrcpyFloatToUint16FieldDefinition)
|
|
42
|
+
.uint32("buttons");
|
|
43
|
+
|
|
44
|
+
export type ScrcpyInjectTouchControlMessage1_16 =
|
|
45
|
+
(typeof ScrcpyInjectTouchControlMessage1_16)["TInit"];
|
|
46
|
+
|
|
47
|
+
export const ScrcpyBackOrScreenOnControlMessage1_16 = BasicControlMessage;
|
|
48
|
+
|
|
49
|
+
export const ScrcpySetClipboardControlMessage1_15 = new Struct()
|
|
50
|
+
.uint8("type")
|
|
51
|
+
.uint32("length")
|
|
52
|
+
.string("content", { lengthField: "length" });
|
|
53
|
+
|
|
54
|
+
export type ScrcpySetClipboardControlMessage1_15 =
|
|
55
|
+
(typeof ScrcpySetClipboardControlMessage1_15)["TInit"];
|
|
@@ -1,299 +1,205 @@
|
|
|
1
|
+
import type { ReadableStream } from "@yume-chan/stream-extra";
|
|
1
2
|
import {
|
|
3
|
+
BufferedReadableStream,
|
|
2
4
|
StructDeserializeStream,
|
|
3
5
|
TransformStream,
|
|
4
6
|
} from "@yume-chan/stream-extra";
|
|
5
|
-
import
|
|
7
|
+
import type { AsyncExactReadable, ValueOrPromise } from "@yume-chan/struct";
|
|
8
|
+
import { NumberFieldType, decodeUtf8 } from "@yume-chan/struct";
|
|
6
9
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
10
|
+
import type {
|
|
11
|
+
ScrcpyBackOrScreenOnControlMessage,
|
|
9
12
|
ScrcpyControlMessageType,
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
ScrcpyInjectTouchControlMessage,
|
|
14
|
+
ScrcpySetClipboardControlMessage,
|
|
12
15
|
} from "../../control/index.js";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
import { AndroidKeyEventAction } from "../../control/index.js";
|
|
17
|
+
import type {
|
|
18
|
+
ScrcpyMediaStreamPacket,
|
|
19
|
+
ScrcpyVideoStream,
|
|
20
|
+
ScrcpyVideoStreamMetadata,
|
|
21
|
+
} from "../codec.js";
|
|
22
|
+
import { ScrcpyVideoCodecId } from "../codec.js";
|
|
23
|
+
import type { ScrcpyDisplay, ScrcpyEncoder, ScrcpyOptions } from "../types.js";
|
|
24
|
+
import { toScrcpyOptionValue } from "../types.js";
|
|
18
25
|
|
|
19
26
|
import { CodecOptions } from "./codec-options.js";
|
|
27
|
+
import type { ScrcpyOptionsInit1_16 } from "./init.js";
|
|
28
|
+
import { ScrcpyLogLevel1_16, ScrcpyVideoOrientation1_16 } from "./init.js";
|
|
20
29
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} from "./scroll.js";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* It will not keep the device screen in specific orientation,
|
|
68
|
-
* only the captured video will in this orientation.
|
|
69
|
-
*/
|
|
70
|
-
lockVideoOrientation: ScrcpyVideoOrientation;
|
|
71
|
-
|
|
72
|
-
tunnelForward: boolean;
|
|
73
|
-
|
|
74
|
-
crop: string;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Send PTS so that the client may record properly
|
|
78
|
-
*
|
|
79
|
-
* Note: When `sendFrameMeta: false` is specified,
|
|
80
|
-
* `onChangeEncoding` event won't fire and `onVideoData` event doesn't
|
|
81
|
-
* merge sps/pps frame and first video frame. Which means you can't use
|
|
82
|
-
* the shipped decoders to render the video
|
|
83
|
-
* (You can still record the stream into a file).
|
|
84
|
-
*
|
|
85
|
-
* @default true
|
|
86
|
-
*/
|
|
87
|
-
sendFrameMeta: boolean;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* @default true
|
|
91
|
-
*/
|
|
92
|
-
control: boolean;
|
|
93
|
-
|
|
94
|
-
displayId: number;
|
|
95
|
-
|
|
96
|
-
showTouches: boolean;
|
|
97
|
-
|
|
98
|
-
stayAwake: boolean;
|
|
99
|
-
|
|
100
|
-
codecOptions: CodecOptions;
|
|
30
|
+
SCRCPY_CONTROL_MESSAGE_TYPES_1_16,
|
|
31
|
+
SCRCPY_MEDIA_PACKET_FLAG_CONFIG,
|
|
32
|
+
ScrcpyBackOrScreenOnControlMessage1_16,
|
|
33
|
+
ScrcpyInjectTouchControlMessage1_16,
|
|
34
|
+
ScrcpyMediaStreamRawPacket,
|
|
35
|
+
ScrcpySetClipboardControlMessage1_15,
|
|
36
|
+
} from "./message.js";
|
|
37
|
+
import type { ScrcpyScrollController } from "./scroll.js";
|
|
38
|
+
import { ScrcpyScrollController1_16 } from "./scroll.js";
|
|
39
|
+
|
|
40
|
+
export class ScrcpyOptions1_16 implements ScrcpyOptions<ScrcpyOptionsInit1_16> {
|
|
41
|
+
public static readonly DEFAULTS = {
|
|
42
|
+
logLevel: ScrcpyLogLevel1_16.Debug,
|
|
43
|
+
maxSize: 0,
|
|
44
|
+
bitRate: 8_000_000,
|
|
45
|
+
maxFps: 0,
|
|
46
|
+
lockVideoOrientation: ScrcpyVideoOrientation1_16.Unlocked,
|
|
47
|
+
tunnelForward: false,
|
|
48
|
+
crop: undefined,
|
|
49
|
+
sendFrameMeta: true,
|
|
50
|
+
control: true,
|
|
51
|
+
displayId: 0,
|
|
52
|
+
showTouches: false,
|
|
53
|
+
stayAwake: false,
|
|
54
|
+
codecOptions: new CodecOptions(),
|
|
55
|
+
} as const satisfies Required<ScrcpyOptionsInit1_16>;
|
|
56
|
+
|
|
57
|
+
public static readonly SERIALIZE_ORDER = [
|
|
58
|
+
"logLevel",
|
|
59
|
+
"maxSize",
|
|
60
|
+
"bitRate",
|
|
61
|
+
"maxFps",
|
|
62
|
+
"lockVideoOrientation",
|
|
63
|
+
"tunnelForward",
|
|
64
|
+
"crop",
|
|
65
|
+
"sendFrameMeta",
|
|
66
|
+
"control",
|
|
67
|
+
"displayId",
|
|
68
|
+
"showTouches",
|
|
69
|
+
"stayAwake",
|
|
70
|
+
"codecOptions",
|
|
71
|
+
] as const satisfies readonly (keyof ScrcpyOptionsInit1_16)[];
|
|
72
|
+
|
|
73
|
+
public static serialize<T>(options: T, order: readonly (keyof T)[]) {
|
|
74
|
+
return order.map((key) => toScrcpyOptionValue(options[key], "-"));
|
|
75
|
+
}
|
|
101
76
|
|
|
102
|
-
|
|
103
|
-
|
|
77
|
+
public static async parseCString(
|
|
78
|
+
stream: AsyncExactReadable,
|
|
79
|
+
maxLength: number
|
|
80
|
+
): Promise<string> {
|
|
81
|
+
let result = decodeUtf8(await stream.readExactly(maxLength));
|
|
82
|
+
result = result.substring(0, result.indexOf("\0"));
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
104
85
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
86
|
+
public static async parseUint16BE(
|
|
87
|
+
stream: AsyncExactReadable
|
|
88
|
+
): Promise<number> {
|
|
89
|
+
const buffer = await stream.readExactly(NumberFieldType.Uint16.size);
|
|
90
|
+
return NumberFieldType.Uint16.deserialize(buffer, false);
|
|
91
|
+
}
|
|
109
92
|
|
|
110
|
-
|
|
93
|
+
public static async parseUint32BE(
|
|
94
|
+
stream: AsyncExactReadable
|
|
95
|
+
): Promise<number> {
|
|
96
|
+
const buffer = await stream.readExactly(NumberFieldType.Uint32.size);
|
|
97
|
+
return NumberFieldType.Uint32.deserialize(buffer, false);
|
|
98
|
+
}
|
|
111
99
|
|
|
112
|
-
|
|
113
|
-
"type",
|
|
114
|
-
ScrcpyControlMessageType.BackOrScreenOn as const
|
|
115
|
-
);
|
|
100
|
+
public value: Required<ScrcpyOptionsInit1_16>;
|
|
116
101
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
.uint32("length")
|
|
120
|
-
.string("content", { lengthField: "length" });
|
|
102
|
+
public readonly defaults: Required<ScrcpyOptionsInit1_16> =
|
|
103
|
+
ScrcpyOptions1_16.DEFAULTS;
|
|
121
104
|
|
|
122
|
-
|
|
123
|
-
|
|
105
|
+
public readonly controlMessageTypes: readonly ScrcpyControlMessageType[] =
|
|
106
|
+
SCRCPY_CONTROL_MESSAGE_TYPES_1_16;
|
|
124
107
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
public value: Partial<T>;
|
|
108
|
+
public constructor(init: ScrcpyOptionsInit1_16) {
|
|
109
|
+
this.value = { ...ScrcpyOptions1_16.DEFAULTS, ...init };
|
|
110
|
+
}
|
|
130
111
|
|
|
131
|
-
public
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
}
|
|
112
|
+
public serialize(): string[] {
|
|
113
|
+
return ScrcpyOptions1_16.serialize(
|
|
114
|
+
this.value,
|
|
115
|
+
ScrcpyOptions1_16.SERIALIZE_ORDER
|
|
116
|
+
);
|
|
117
|
+
}
|
|
138
118
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
) {
|
|
143
|
-
value.lockVideoOrientation = ScrcpyVideoOrientation.Unlocked;
|
|
144
|
-
}
|
|
119
|
+
public setListEncoders(): void {
|
|
120
|
+
throw new Error("Not supported");
|
|
121
|
+
}
|
|
145
122
|
|
|
146
|
-
|
|
123
|
+
public setListDisplays(): void {
|
|
124
|
+
// Set to an invalid value
|
|
125
|
+
// Server will print valid values before crashing
|
|
126
|
+
// (server will crash before opening sockets)
|
|
127
|
+
this.value.displayId = -1;
|
|
147
128
|
}
|
|
148
129
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"logLevel",
|
|
152
|
-
"maxSize",
|
|
153
|
-
"bitRate",
|
|
154
|
-
"maxFps",
|
|
155
|
-
"lockVideoOrientation",
|
|
156
|
-
"tunnelForward",
|
|
157
|
-
"crop",
|
|
158
|
-
"sendFrameMeta",
|
|
159
|
-
"control",
|
|
160
|
-
"displayId",
|
|
161
|
-
"showTouches",
|
|
162
|
-
"stayAwake",
|
|
163
|
-
"codecOptions",
|
|
164
|
-
"encoderName",
|
|
165
|
-
];
|
|
130
|
+
public parseEncoder(): ScrcpyEncoder | undefined {
|
|
131
|
+
throw new Error("Not supported");
|
|
166
132
|
}
|
|
167
133
|
|
|
168
|
-
public
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
sendFrameMeta: true,
|
|
178
|
-
control: true,
|
|
179
|
-
displayId: 0,
|
|
180
|
-
showTouches: false,
|
|
181
|
-
stayAwake: false,
|
|
182
|
-
codecOptions: new CodecOptions({}),
|
|
183
|
-
encoderName: "-",
|
|
184
|
-
} as T;
|
|
134
|
+
public parseDisplay(line: string): ScrcpyDisplay | undefined {
|
|
135
|
+
const displayIdRegex = /\s+scrcpy --display (\d+)/;
|
|
136
|
+
const match = line.match(displayIdRegex);
|
|
137
|
+
if (match) {
|
|
138
|
+
return {
|
|
139
|
+
id: Number.parseInt(match[1]!, 10),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
185
143
|
}
|
|
186
144
|
|
|
187
|
-
public
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
145
|
+
public parseVideoStreamMetadata(
|
|
146
|
+
stream: ReadableStream<Uint8Array>
|
|
147
|
+
): ValueOrPromise<ScrcpyVideoStream> {
|
|
148
|
+
return (async () => {
|
|
149
|
+
const buffered = new BufferedReadableStream(stream);
|
|
150
|
+
const metadata: ScrcpyVideoStreamMetadata = {
|
|
151
|
+
codec: ScrcpyVideoCodecId.H264,
|
|
152
|
+
};
|
|
153
|
+
metadata.deviceName = await ScrcpyOptions1_16.parseCString(
|
|
154
|
+
buffered,
|
|
155
|
+
64
|
|
156
|
+
);
|
|
157
|
+
metadata.width = await ScrcpyOptions1_16.parseUint16BE(buffered);
|
|
158
|
+
metadata.height = await ScrcpyOptions1_16.parseUint16BE(buffered);
|
|
159
|
+
return { stream: buffered.release(), metadata };
|
|
160
|
+
})();
|
|
192
161
|
}
|
|
193
162
|
|
|
194
|
-
public
|
|
195
|
-
|
|
163
|
+
public parseAudioStreamMetadata(): never {
|
|
164
|
+
throw new Error("Not supported");
|
|
196
165
|
}
|
|
197
166
|
|
|
198
|
-
public
|
|
167
|
+
public createMediaStreamTransformer(): TransformStream<
|
|
199
168
|
Uint8Array,
|
|
200
|
-
|
|
169
|
+
ScrcpyMediaStreamPacket
|
|
201
170
|
> {
|
|
202
171
|
// Optimized path for video frames only
|
|
203
|
-
if (this.value.sendFrameMeta
|
|
172
|
+
if (!this.value.sendFrameMeta) {
|
|
204
173
|
return new TransformStream({
|
|
205
174
|
transform(chunk, controller) {
|
|
206
175
|
controller.enqueue({
|
|
207
|
-
type: "
|
|
176
|
+
type: "data",
|
|
208
177
|
data: chunk,
|
|
209
178
|
});
|
|
210
179
|
},
|
|
211
180
|
});
|
|
212
181
|
}
|
|
213
182
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
183
|
+
const deserializeStream = new StructDeserializeStream(
|
|
184
|
+
ScrcpyMediaStreamRawPacket
|
|
185
|
+
);
|
|
217
186
|
return {
|
|
218
187
|
writable: deserializeStream.writable,
|
|
219
188
|
readable: deserializeStream.readable.pipeThrough(
|
|
220
189
|
new TransformStream({
|
|
221
190
|
transform(packet, controller) {
|
|
222
|
-
if (packet.pts ===
|
|
223
|
-
const {
|
|
224
|
-
sequenceParameterSet,
|
|
225
|
-
pictureParameterSet,
|
|
226
|
-
} = parseH264Configuration(packet.data);
|
|
227
|
-
|
|
228
|
-
const {
|
|
229
|
-
profile_idc: profileIndex,
|
|
230
|
-
constraint_set: constraintSet,
|
|
231
|
-
level_idc: levelIndex,
|
|
232
|
-
pic_width_in_mbs_minus1,
|
|
233
|
-
pic_height_in_map_units_minus1,
|
|
234
|
-
frame_mbs_only_flag,
|
|
235
|
-
frame_crop_left_offset,
|
|
236
|
-
frame_crop_right_offset,
|
|
237
|
-
frame_crop_top_offset,
|
|
238
|
-
frame_crop_bottom_offset,
|
|
239
|
-
} = parseSequenceParameterSet(
|
|
240
|
-
removeH264Emulation(sequenceParameterSet)
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
const encodedWidth =
|
|
244
|
-
(pic_width_in_mbs_minus1 + 1) * 16;
|
|
245
|
-
const encodedHeight =
|
|
246
|
-
(pic_height_in_map_units_minus1 + 1) *
|
|
247
|
-
(2 - frame_mbs_only_flag) *
|
|
248
|
-
16;
|
|
249
|
-
const cropLeft = frame_crop_left_offset * 2;
|
|
250
|
-
const cropRight = frame_crop_right_offset * 2;
|
|
251
|
-
const cropTop = frame_crop_top_offset * 2;
|
|
252
|
-
const cropBottom = frame_crop_bottom_offset * 2;
|
|
253
|
-
|
|
254
|
-
const croppedWidth =
|
|
255
|
-
encodedWidth - cropLeft - cropRight;
|
|
256
|
-
const croppedHeight =
|
|
257
|
-
encodedHeight - cropTop - cropBottom;
|
|
258
|
-
|
|
259
|
-
header = packet.data;
|
|
191
|
+
if (packet.pts === SCRCPY_MEDIA_PACKET_FLAG_CONFIG) {
|
|
260
192
|
controller.enqueue({
|
|
261
193
|
type: "configuration",
|
|
262
|
-
|
|
263
|
-
sequenceParameterSet,
|
|
264
|
-
data: {
|
|
265
|
-
profileIndex,
|
|
266
|
-
constraintSet,
|
|
267
|
-
levelIndex,
|
|
268
|
-
encodedWidth,
|
|
269
|
-
encodedHeight,
|
|
270
|
-
cropLeft,
|
|
271
|
-
cropRight,
|
|
272
|
-
cropTop,
|
|
273
|
-
cropBottom,
|
|
274
|
-
croppedWidth,
|
|
275
|
-
croppedHeight,
|
|
276
|
-
},
|
|
194
|
+
data: packet.data,
|
|
277
195
|
});
|
|
278
196
|
return;
|
|
279
197
|
}
|
|
280
198
|
|
|
281
|
-
let frameData: Uint8Array;
|
|
282
|
-
if (header) {
|
|
283
|
-
frameData = new Uint8Array(
|
|
284
|
-
header.byteLength + packet.data.byteLength
|
|
285
|
-
);
|
|
286
|
-
frameData.set(header);
|
|
287
|
-
frameData.set(packet.data, header.byteLength);
|
|
288
|
-
header = undefined;
|
|
289
|
-
} else {
|
|
290
|
-
frameData = packet.data;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
199
|
controller.enqueue({
|
|
294
|
-
type: "
|
|
200
|
+
type: "data",
|
|
295
201
|
pts: packet.pts,
|
|
296
|
-
data:
|
|
202
|
+
data: packet.data,
|
|
297
203
|
});
|
|
298
204
|
},
|
|
299
205
|
})
|
|
@@ -301,20 +207,10 @@ export class ScrcpyOptions1_16<
|
|
|
301
207
|
};
|
|
302
208
|
}
|
|
303
209
|
|
|
304
|
-
public
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
/* 2 */ ScrcpyControlMessageType.InjectTouch,
|
|
309
|
-
/* 3 */ ScrcpyControlMessageType.InjectScroll,
|
|
310
|
-
/* 4 */ ScrcpyControlMessageType.BackOrScreenOn,
|
|
311
|
-
/* 5 */ ScrcpyControlMessageType.ExpandNotificationPanel,
|
|
312
|
-
/* 6 */ ScrcpyControlMessageType.CollapseNotificationPanel,
|
|
313
|
-
/* 7 */ ScrcpyControlMessageType.GetClipboard,
|
|
314
|
-
/* 8 */ ScrcpyControlMessageType.SetClipboard,
|
|
315
|
-
/* 9 */ ScrcpyControlMessageType.SetScreenPowerMode,
|
|
316
|
-
/* 10 */ ScrcpyControlMessageType.RotateDevice,
|
|
317
|
-
];
|
|
210
|
+
public serializeInjectTouchControlMessage(
|
|
211
|
+
message: ScrcpyInjectTouchControlMessage
|
|
212
|
+
): Uint8Array {
|
|
213
|
+
return ScrcpyInjectTouchControlMessage1_16.serialize(message);
|
|
318
214
|
}
|
|
319
215
|
|
|
320
216
|
public serializeBackOrScreenOnControlMessage(
|
|
@@ -333,7 +229,7 @@ export class ScrcpyOptions1_16<
|
|
|
333
229
|
return ScrcpySetClipboardControlMessage1_15.serialize(message);
|
|
334
230
|
}
|
|
335
231
|
|
|
336
|
-
public
|
|
232
|
+
public createScrollController(): ScrcpyScrollController {
|
|
337
233
|
return new ScrcpyScrollController1_16();
|
|
338
234
|
}
|
|
339
235
|
}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import Struct from "@yume-chan/struct";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
ScrcpyControlMessageType,
|
|
5
|
-
type ScrcpyInjectScrollControlMessage,
|
|
6
|
-
} from "../../control/index.js";
|
|
3
|
+
import type { ScrcpyInjectScrollControlMessage } from "../../control/index.js";
|
|
7
4
|
|
|
8
5
|
export interface ScrcpyScrollController {
|
|
9
6
|
serializeScrollMessage(
|
|
@@ -12,7 +9,7 @@ export interface ScrcpyScrollController {
|
|
|
12
9
|
}
|
|
13
10
|
|
|
14
11
|
export const ScrcpyInjectScrollControlMessage1_16 = new Struct()
|
|
15
|
-
.uint8("type"
|
|
12
|
+
.uint8("type")
|
|
16
13
|
.uint32("pointerX")
|
|
17
14
|
.uint32("pointerY")
|
|
18
15
|
.uint16("screenWidth")
|