@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,342 @@
|
|
|
1
|
+
import type { ReadableStream } from "@yume-chan/stream-extra";
|
|
2
|
+
import {
|
|
3
|
+
BufferedReadableStream,
|
|
4
|
+
PushReadableStream,
|
|
5
|
+
} from "@yume-chan/stream-extra";
|
|
6
|
+
import type { ValueOrPromise } from "@yume-chan/struct";
|
|
7
|
+
import Struct, { NumberFieldType, placeholder } from "@yume-chan/struct";
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
AndroidMotionEventAction,
|
|
11
|
+
ScrcpyInjectTouchControlMessage,
|
|
12
|
+
} from "../control/index.js";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
CodecOptions,
|
|
16
|
+
ScrcpyFloatToUint16FieldDefinition,
|
|
17
|
+
ScrcpyOptions1_16,
|
|
18
|
+
} from "./1_16/index.js";
|
|
19
|
+
import { ScrcpyOptions1_21 } from "./1_21.js";
|
|
20
|
+
import type { ScrcpyOptionsInit1_24 } from "./1_24.js";
|
|
21
|
+
import { ScrcpyOptions1_24 } from "./1_24.js";
|
|
22
|
+
import { ScrcpyOptions1_25 } from "./1_25/index.js";
|
|
23
|
+
import type { ScrcpyAudioStreamMetadata, ScrcpyVideoStream } from "./codec.js";
|
|
24
|
+
import { ScrcpyAudioCodec, ScrcpyVideoCodecId } from "./codec.js";
|
|
25
|
+
import type {
|
|
26
|
+
ScrcpyDisplay,
|
|
27
|
+
ScrcpyEncoder,
|
|
28
|
+
ScrcpyOptionValue,
|
|
29
|
+
} from "./types.js";
|
|
30
|
+
import { ScrcpyOptionsBase } from "./types.js";
|
|
31
|
+
|
|
32
|
+
export const ScrcpyInjectTouchControlMessage2_0 = new Struct()
|
|
33
|
+
.uint8("type")
|
|
34
|
+
.uint8("action", placeholder<AndroidMotionEventAction>())
|
|
35
|
+
.uint64("pointerId")
|
|
36
|
+
.uint32("pointerX")
|
|
37
|
+
.uint32("pointerY")
|
|
38
|
+
.uint16("screenWidth")
|
|
39
|
+
.uint16("screenHeight")
|
|
40
|
+
.field("pressure", ScrcpyFloatToUint16FieldDefinition)
|
|
41
|
+
.uint32("actionButton")
|
|
42
|
+
.uint32("buttons");
|
|
43
|
+
|
|
44
|
+
export type ScrcpyInjectTouchControlMessage2_0 =
|
|
45
|
+
(typeof ScrcpyInjectTouchControlMessage2_0)["TInit"];
|
|
46
|
+
|
|
47
|
+
export class ScrcpyInstanceId implements ScrcpyOptionValue {
|
|
48
|
+
public static readonly NONE = new ScrcpyInstanceId(-1);
|
|
49
|
+
|
|
50
|
+
public static random(): ScrcpyInstanceId {
|
|
51
|
+
// A random 31-bit unsigned integer
|
|
52
|
+
return new ScrcpyInstanceId((Math.random() * 0x80000000) | 0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public value: number;
|
|
56
|
+
|
|
57
|
+
public constructor(value: number) {
|
|
58
|
+
this.value = value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public toOptionValue(): string | undefined {
|
|
62
|
+
if (this.value < 0) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
return this.value.toString(16);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ScrcpyOptionsInit2_0
|
|
70
|
+
extends Omit<
|
|
71
|
+
ScrcpyOptionsInit1_24,
|
|
72
|
+
"bitRate" | "codecOptions" | "encoderName"
|
|
73
|
+
> {
|
|
74
|
+
scid?: ScrcpyInstanceId;
|
|
75
|
+
|
|
76
|
+
videoCodec?: "h264" | "h265" | "av1";
|
|
77
|
+
videoBitRate?: number;
|
|
78
|
+
videoCodecOptions?: CodecOptions;
|
|
79
|
+
videoEncoder?: string;
|
|
80
|
+
|
|
81
|
+
audio?: boolean;
|
|
82
|
+
audioCodec?: "opus" | "aac" | "raw";
|
|
83
|
+
audioBitRate?: number;
|
|
84
|
+
audioCodecOptions?: CodecOptions;
|
|
85
|
+
audioEncoder?: string;
|
|
86
|
+
|
|
87
|
+
listEncoders?: boolean;
|
|
88
|
+
listDisplays?: boolean;
|
|
89
|
+
sendCodecMeta?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function omit<T extends object, K extends keyof T>(
|
|
93
|
+
obj: T,
|
|
94
|
+
keys: K[]
|
|
95
|
+
): Omit<T, K> {
|
|
96
|
+
const result: Record<PropertyKey, unknown> = {};
|
|
97
|
+
for (const key in obj) {
|
|
98
|
+
if (!keys.includes(key as keyof T as K)) {
|
|
99
|
+
result[key] = obj[key];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return result as Omit<T, K>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export class ScrcpyOptions2_0 extends ScrcpyOptionsBase<
|
|
106
|
+
ScrcpyOptionsInit2_0,
|
|
107
|
+
ScrcpyOptions1_25
|
|
108
|
+
> {
|
|
109
|
+
public static readonly DEFAULTS = {
|
|
110
|
+
...omit(ScrcpyOptions1_24.DEFAULTS, [
|
|
111
|
+
"bitRate",
|
|
112
|
+
"codecOptions",
|
|
113
|
+
"encoderName",
|
|
114
|
+
]),
|
|
115
|
+
scid: ScrcpyInstanceId.NONE,
|
|
116
|
+
|
|
117
|
+
videoCodec: "h264",
|
|
118
|
+
videoBitRate: 8000000,
|
|
119
|
+
videoCodecOptions: new CodecOptions(),
|
|
120
|
+
videoEncoder: "",
|
|
121
|
+
|
|
122
|
+
audio: true,
|
|
123
|
+
audioCodec: "opus",
|
|
124
|
+
audioBitRate: 128000,
|
|
125
|
+
audioCodecOptions: new CodecOptions(),
|
|
126
|
+
audioEncoder: "",
|
|
127
|
+
|
|
128
|
+
listEncoders: false,
|
|
129
|
+
listDisplays: false,
|
|
130
|
+
sendCodecMeta: true,
|
|
131
|
+
} as const satisfies Required<ScrcpyOptionsInit2_0>;
|
|
132
|
+
|
|
133
|
+
public override get defaults(): Required<ScrcpyOptionsInit2_0> {
|
|
134
|
+
return ScrcpyOptions2_0.DEFAULTS;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public constructor(init: ScrcpyOptionsInit2_0) {
|
|
138
|
+
super(new ScrcpyOptions1_25(init), {
|
|
139
|
+
...ScrcpyOptions2_0.DEFAULTS,
|
|
140
|
+
...init,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public override serialize(): string[] {
|
|
145
|
+
return ScrcpyOptions1_21.serialize(this.value, this.defaults);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public override setListEncoders(): void {
|
|
149
|
+
this.value.listEncoders = true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
public override setListDisplays(): void {
|
|
153
|
+
this.value.listDisplays = true;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public override parseEncoder(line: string): ScrcpyEncoder | undefined {
|
|
157
|
+
let match = line.match(
|
|
158
|
+
/\s+--video-codec=(.*)\s+--video-encoder='(.*)'/
|
|
159
|
+
);
|
|
160
|
+
if (match) {
|
|
161
|
+
return {
|
|
162
|
+
type: "video",
|
|
163
|
+
codec: match[1]!,
|
|
164
|
+
name: match[2]!,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
match = line.match(/\s+--audio-codec=(.*)\s+--audio-encoder='(.*)'/);
|
|
169
|
+
if (match) {
|
|
170
|
+
return {
|
|
171
|
+
type: "audio",
|
|
172
|
+
codec: match[1]!,
|
|
173
|
+
name: match[2]!,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public override parseDisplay(line: string): ScrcpyDisplay | undefined {
|
|
181
|
+
const match = line.match(/\s+--display=(\d+)\s+\((.*?)\)/);
|
|
182
|
+
if (match) {
|
|
183
|
+
const display: ScrcpyDisplay = {
|
|
184
|
+
id: Number.parseInt(match[1]!, 10),
|
|
185
|
+
};
|
|
186
|
+
if (match[2] !== "size unknown") {
|
|
187
|
+
display.resolution = match[2]!;
|
|
188
|
+
}
|
|
189
|
+
return display;
|
|
190
|
+
}
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public override parseVideoStreamMetadata(
|
|
195
|
+
stream: ReadableStream<Uint8Array>
|
|
196
|
+
): ValueOrPromise<ScrcpyVideoStream> {
|
|
197
|
+
const { sendDeviceMeta, sendCodecMeta } = this.value;
|
|
198
|
+
if (!sendDeviceMeta && !sendCodecMeta) {
|
|
199
|
+
let codec: ScrcpyVideoCodecId;
|
|
200
|
+
switch (this.value.videoCodec) {
|
|
201
|
+
case "h264":
|
|
202
|
+
codec = ScrcpyVideoCodecId.H264;
|
|
203
|
+
break;
|
|
204
|
+
case "h265":
|
|
205
|
+
codec = ScrcpyVideoCodecId.H265;
|
|
206
|
+
break;
|
|
207
|
+
case "av1":
|
|
208
|
+
codec = ScrcpyVideoCodecId.AV1;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
return { stream, metadata: { codec } };
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return (async () => {
|
|
215
|
+
const buffered = new BufferedReadableStream(stream);
|
|
216
|
+
|
|
217
|
+
// `sendDeviceMeta` now only contains device name,
|
|
218
|
+
// can't use `super.parseVideoStreamMetadata` here
|
|
219
|
+
let deviceName: string | undefined;
|
|
220
|
+
if (sendDeviceMeta) {
|
|
221
|
+
deviceName = await ScrcpyOptions1_16.parseCString(buffered, 64);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let codec: ScrcpyVideoCodecId;
|
|
225
|
+
let width: number | undefined;
|
|
226
|
+
let height: number | undefined;
|
|
227
|
+
if (sendCodecMeta) {
|
|
228
|
+
codec = await ScrcpyOptions1_16.parseUint32BE(buffered);
|
|
229
|
+
width = await ScrcpyOptions1_16.parseUint32BE(buffered);
|
|
230
|
+
height = await ScrcpyOptions1_16.parseUint32BE(buffered);
|
|
231
|
+
} else {
|
|
232
|
+
switch (this.value.videoCodec) {
|
|
233
|
+
case "h264":
|
|
234
|
+
codec = ScrcpyVideoCodecId.H264;
|
|
235
|
+
break;
|
|
236
|
+
case "h265":
|
|
237
|
+
codec = ScrcpyVideoCodecId.H265;
|
|
238
|
+
break;
|
|
239
|
+
case "av1":
|
|
240
|
+
codec = ScrcpyVideoCodecId.AV1;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
stream: buffered.release(),
|
|
247
|
+
metadata: { deviceName, codec, width, height },
|
|
248
|
+
};
|
|
249
|
+
})();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
public override parseAudioStreamMetadata(
|
|
253
|
+
stream: ReadableStream<Uint8Array>
|
|
254
|
+
): ValueOrPromise<ScrcpyAudioStreamMetadata> {
|
|
255
|
+
return (async (): Promise<ScrcpyAudioStreamMetadata> => {
|
|
256
|
+
const buffered = new BufferedReadableStream(stream);
|
|
257
|
+
const buffer = await buffered.readExactly(
|
|
258
|
+
NumberFieldType.Uint32.size
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
const codecMetadataValue = NumberFieldType.Uint32.deserialize(
|
|
262
|
+
buffer,
|
|
263
|
+
false
|
|
264
|
+
);
|
|
265
|
+
// Server will send `0x00_00_00_00` and `0x00_00_00_01` even if `sendCodecMeta` is false
|
|
266
|
+
switch (codecMetadataValue) {
|
|
267
|
+
case 0x00_00_00_00:
|
|
268
|
+
return {
|
|
269
|
+
type: "disabled",
|
|
270
|
+
};
|
|
271
|
+
case 0x00_00_00_01:
|
|
272
|
+
return {
|
|
273
|
+
type: "errored",
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (this.value.sendCodecMeta) {
|
|
278
|
+
let codec: ScrcpyAudioCodec;
|
|
279
|
+
switch (codecMetadataValue) {
|
|
280
|
+
case ScrcpyAudioCodec.OPUS.metadataValue:
|
|
281
|
+
codec = ScrcpyAudioCodec.OPUS;
|
|
282
|
+
break;
|
|
283
|
+
case ScrcpyAudioCodec.AAC.metadataValue:
|
|
284
|
+
codec = ScrcpyAudioCodec.AAC;
|
|
285
|
+
break;
|
|
286
|
+
case ScrcpyAudioCodec.RAW.metadataValue:
|
|
287
|
+
codec = ScrcpyAudioCodec.RAW;
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
throw new Error(
|
|
291
|
+
`Unknown audio codec metadata value: ${codecMetadataValue}`
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
type: "success",
|
|
296
|
+
codec,
|
|
297
|
+
stream: buffered.release(),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Infer codec from `audioCodec` option
|
|
302
|
+
let codec: ScrcpyAudioCodec;
|
|
303
|
+
switch (this.value.audioCodec) {
|
|
304
|
+
case "opus":
|
|
305
|
+
codec = ScrcpyAudioCodec.OPUS;
|
|
306
|
+
break;
|
|
307
|
+
case "aac":
|
|
308
|
+
codec = ScrcpyAudioCodec.AAC;
|
|
309
|
+
break;
|
|
310
|
+
case "raw":
|
|
311
|
+
codec = ScrcpyAudioCodec.RAW;
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
type: "success",
|
|
316
|
+
codec,
|
|
317
|
+
stream: new PushReadableStream<Uint8Array>(
|
|
318
|
+
async (controller) => {
|
|
319
|
+
// Put the first 4 bytes back
|
|
320
|
+
await controller.enqueue(buffer);
|
|
321
|
+
|
|
322
|
+
const stream = buffered.release();
|
|
323
|
+
const reader = stream.getReader();
|
|
324
|
+
while (true) {
|
|
325
|
+
const { done, value } = await reader.read();
|
|
326
|
+
if (done) {
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
await controller.enqueue(value);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
),
|
|
333
|
+
};
|
|
334
|
+
})();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
public override serializeInjectTouchControlMessage(
|
|
338
|
+
message: ScrcpyInjectTouchControlMessage
|
|
339
|
+
): Uint8Array {
|
|
340
|
+
return ScrcpyInjectTouchControlMessage2_0.serialize(message);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { ReadableStream } from "@yume-chan/stream-extra";
|
|
2
|
+
|
|
3
|
+
import type { ScrcpyOptionValue } from "./types.js";
|
|
4
|
+
|
|
5
|
+
export enum ScrcpyVideoCodecId {
|
|
6
|
+
H264 = 0x68_32_36_34,
|
|
7
|
+
H265 = 0x68_32_36_35,
|
|
8
|
+
AV1 = 0x00_61_76_31,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ScrcpyVideoStreamMetadata {
|
|
12
|
+
deviceName?: string | undefined;
|
|
13
|
+
width?: number | undefined;
|
|
14
|
+
height?: number | undefined;
|
|
15
|
+
codec: ScrcpyVideoCodecId;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ScrcpyVideoStream {
|
|
19
|
+
readonly stream: ReadableStream<Uint8Array>;
|
|
20
|
+
readonly metadata: ScrcpyVideoStreamMetadata;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class ScrcpyAudioCodec implements ScrcpyOptionValue {
|
|
24
|
+
public static readonly OPUS = new ScrcpyAudioCodec(
|
|
25
|
+
"opus",
|
|
26
|
+
0x6f_70_75_73,
|
|
27
|
+
"audio/opus",
|
|
28
|
+
"opus"
|
|
29
|
+
);
|
|
30
|
+
public static readonly AAC = new ScrcpyAudioCodec(
|
|
31
|
+
"aac",
|
|
32
|
+
0x00_61_61_63,
|
|
33
|
+
"audio/aac",
|
|
34
|
+
"mp4a.66"
|
|
35
|
+
);
|
|
36
|
+
public static readonly RAW = new ScrcpyAudioCodec(
|
|
37
|
+
"raw",
|
|
38
|
+
0x00_72_61_77,
|
|
39
|
+
"audio/raw",
|
|
40
|
+
"1"
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
public readonly optionValue: string;
|
|
44
|
+
public readonly metadataValue: number;
|
|
45
|
+
public readonly mimeType: string;
|
|
46
|
+
public readonly webCodecId: string;
|
|
47
|
+
|
|
48
|
+
public constructor(
|
|
49
|
+
optionValue: string,
|
|
50
|
+
metadataValue: number,
|
|
51
|
+
mimeType: string,
|
|
52
|
+
webCodecId: string
|
|
53
|
+
) {
|
|
54
|
+
this.optionValue = optionValue;
|
|
55
|
+
this.metadataValue = metadataValue;
|
|
56
|
+
this.mimeType = mimeType;
|
|
57
|
+
this.webCodecId = webCodecId;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public toOptionValue(): string {
|
|
61
|
+
return this.optionValue;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface ScrcpyAudioStreamDisabledMetadata {
|
|
66
|
+
readonly type: "disabled";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface ScrcpyAudioStreamErroredMetadata {
|
|
70
|
+
readonly type: "errored";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ScrcpyAudioStreamSuccessMetadata {
|
|
74
|
+
readonly type: "success";
|
|
75
|
+
readonly codec: ScrcpyAudioCodec;
|
|
76
|
+
readonly stream: ReadableStream<Uint8Array>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type ScrcpyAudioStreamMetadata =
|
|
80
|
+
| ScrcpyAudioStreamDisabledMetadata
|
|
81
|
+
| ScrcpyAudioStreamErroredMetadata
|
|
82
|
+
| ScrcpyAudioStreamSuccessMetadata;
|
|
83
|
+
|
|
84
|
+
export interface ScrcpyMediaStreamConfigurationPacket {
|
|
85
|
+
type: "configuration";
|
|
86
|
+
data: Uint8Array;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface ScrcpyMediaStreamDataPacket {
|
|
90
|
+
type: "data";
|
|
91
|
+
keyframe?: boolean;
|
|
92
|
+
pts?: bigint;
|
|
93
|
+
data: Uint8Array;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export type ScrcpyMediaStreamPacket =
|
|
97
|
+
| ScrcpyMediaStreamConfigurationPacket
|
|
98
|
+
| ScrcpyMediaStreamDataPacket;
|
package/src/options/index.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./1_16/index.js";
|
|
2
|
+
export * from "./1_17.js";
|
|
3
|
+
export * from "./1_18.js";
|
|
4
|
+
export * from "./1_21.js";
|
|
4
5
|
export * from "./1_22/index.js";
|
|
5
6
|
export * from "./1_23.js";
|
|
6
7
|
export * from "./1_24.js";
|
|
7
8
|
export * from "./1_25/index.js";
|
|
9
|
+
export * from "./2_0.js";
|
|
10
|
+
export * from "./codec.js";
|
|
11
|
+
export * from "./latest.js";
|
|
8
12
|
export * from "./types.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ScrcpyLogLevel1_18, ScrcpyVideoOrientation1_18 } from "./1_18.js";
|
|
2
|
+
import type { ScrcpyOptionsInit2_0 } from "./2_0.js";
|
|
3
|
+
import { ScrcpyOptions2_0 } from "./2_0.js";
|
|
4
|
+
|
|
5
|
+
export const ScrcpyLogLevel = ScrcpyLogLevel1_18;
|
|
6
|
+
export type ScrcpyLogLevel = ScrcpyLogLevel1_18;
|
|
7
|
+
|
|
8
|
+
export const ScrcpyVideoOrientation = ScrcpyVideoOrientation1_18;
|
|
9
|
+
export type ScrcpyVideoOrientation = ScrcpyVideoOrientation1_18;
|
|
10
|
+
|
|
11
|
+
export type ScrcpyOptionsInitLatest = ScrcpyOptionsInit2_0;
|
|
12
|
+
export class ScrcpyOptionsLatest extends ScrcpyOptions2_0 {}
|
|
13
|
+
|
|
14
|
+
export const ScrcpyLatestVersion = "2.0";
|