@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.
Files changed (288) hide show
  1. package/CHANGELOG.json +33 -0
  2. package/CHANGELOG.md +18 -1
  3. package/README.md +157 -183
  4. package/bin/scrcpy-server +0 -0
  5. package/bin/version.d.ts +1 -1
  6. package/bin/version.js +1 -1
  7. package/esm/codec/av1.d.ts +33 -0
  8. package/esm/codec/av1.d.ts.map +1 -0
  9. package/esm/codec/av1.js +35 -0
  10. package/esm/codec/av1.js.map +1 -0
  11. package/esm/codec/h264.d.ts +78 -0
  12. package/esm/codec/h264.d.ts.map +1 -0
  13. package/esm/codec/h264.js +256 -0
  14. package/esm/codec/h264.js.map +1 -0
  15. package/esm/codec/h265.d.ts +490 -0
  16. package/esm/codec/h265.d.ts.map +1 -0
  17. package/esm/codec/h265.js +1098 -0
  18. package/esm/codec/h265.js.map +1 -0
  19. package/esm/codec/index.d.ts +5 -0
  20. package/esm/codec/index.d.ts.map +1 -0
  21. package/esm/codec/index.js +5 -0
  22. package/esm/codec/index.js.map +1 -0
  23. package/esm/codec/nalu.d.ts +44 -0
  24. package/esm/codec/nalu.d.ts.map +1 -0
  25. package/esm/codec/nalu.js +310 -0
  26. package/esm/codec/nalu.js.map +1 -0
  27. package/esm/control/back-or-screen-on.d.ts +2 -2
  28. package/esm/control/back-or-screen-on.d.ts.map +1 -1
  29. package/esm/control/back-or-screen-on.js +1 -1
  30. package/esm/control/basic.d.ts +5 -0
  31. package/esm/control/basic.d.ts.map +1 -0
  32. package/esm/control/basic.js +3 -0
  33. package/esm/control/basic.js.map +1 -0
  34. package/esm/control/hover-helper.d.ts +17 -17
  35. package/esm/control/hover-helper.d.ts.map +1 -1
  36. package/esm/control/hover-helper.js +43 -43
  37. package/esm/control/hover-helper.js.map +1 -1
  38. package/esm/control/index.d.ts +13 -11
  39. package/esm/control/index.d.ts.map +1 -1
  40. package/esm/control/index.js +13 -11
  41. package/esm/control/index.js.map +1 -1
  42. package/esm/control/inject-keycode.d.ts +193 -60
  43. package/esm/control/inject-keycode.d.ts.map +1 -1
  44. package/esm/control/inject-keycode.js +198 -61
  45. package/esm/control/inject-keycode.js.map +1 -1
  46. package/esm/control/inject-scroll.d.ts +2 -2
  47. package/esm/control/inject-scroll.d.ts.map +1 -1
  48. package/esm/control/inject-scroll.js +1 -1
  49. package/esm/control/inject-text.d.ts +7 -8
  50. package/esm/control/inject-text.d.ts.map +1 -1
  51. package/esm/control/inject-text.js +5 -6
  52. package/esm/control/inject-text.js.map +1 -1
  53. package/esm/control/inject-touch.d.ts +32 -37
  54. package/esm/control/inject-touch.d.ts.map +1 -1
  55. package/esm/control/inject-touch.js +35 -62
  56. package/esm/control/inject-touch.js.map +1 -1
  57. package/esm/control/rotate-device.d.ts +4 -6
  58. package/esm/control/rotate-device.d.ts.map +1 -1
  59. package/esm/control/rotate-device.js +2 -4
  60. package/esm/control/rotate-device.js.map +1 -1
  61. package/esm/control/serializer.d.ts +25 -33
  62. package/esm/control/serializer.d.ts.map +1 -1
  63. package/esm/control/serializer.js +53 -78
  64. package/esm/control/serializer.js.map +1 -1
  65. package/esm/control/set-clipboard.d.ts +2 -2
  66. package/esm/control/set-clipboard.d.ts.map +1 -1
  67. package/esm/control/set-clipboard.js +1 -1
  68. package/esm/control/set-screen-power-mode.d.ts +10 -11
  69. package/esm/control/set-screen-power-mode.d.ts.map +1 -1
  70. package/esm/control/set-screen-power-mode.js +10 -11
  71. package/esm/control/set-screen-power-mode.js.map +1 -1
  72. package/esm/control/type.d.ts +28 -14
  73. package/esm/control/type.d.ts.map +1 -1
  74. package/esm/control/type.js +40 -18
  75. package/esm/control/type.js.map +1 -1
  76. package/esm/control/writer.d.ts +28 -0
  77. package/esm/control/writer.d.ts.map +1 -0
  78. package/esm/control/writer.js +53 -0
  79. package/esm/control/writer.js.map +1 -0
  80. package/esm/device-message/ack-clipboard.d.ts +8 -8
  81. package/esm/device-message/ack-clipboard.d.ts.map +1 -1
  82. package/esm/device-message/ack-clipboard.js +5 -5
  83. package/esm/device-message/clipboard.d.ts +9 -9
  84. package/esm/device-message/clipboard.d.ts.map +1 -1
  85. package/esm/device-message/clipboard.js +6 -6
  86. package/esm/device-message/index.d.ts +4 -4
  87. package/esm/device-message/index.js +4 -4
  88. package/esm/device-message/stream.d.ts +7 -7
  89. package/esm/device-message/stream.d.ts.map +1 -1
  90. package/esm/device-message/stream.js +34 -19
  91. package/esm/device-message/stream.js.map +1 -1
  92. package/esm/device-message/type.d.ts +4 -4
  93. package/esm/device-message/type.js +6 -6
  94. package/esm/index.d.ts +4 -5
  95. package/esm/index.d.ts.map +1 -1
  96. package/esm/index.js +4 -5
  97. package/esm/index.js.map +1 -1
  98. package/esm/options/1_16/codec-options.d.ts +19 -19
  99. package/esm/options/1_16/codec-options.d.ts.map +1 -1
  100. package/esm/options/1_16/codec-options.js +25 -25
  101. package/esm/options/1_16/codec-options.js.map +1 -1
  102. package/esm/options/1_16/float-to-uint16.d.ts +5 -0
  103. package/esm/options/1_16/float-to-uint16.d.ts.map +1 -0
  104. package/esm/options/1_16/float-to-uint16.js +27 -0
  105. package/esm/options/1_16/float-to-uint16.js.map +1 -0
  106. package/esm/options/1_16/index.d.ts +6 -4
  107. package/esm/options/1_16/index.d.ts.map +1 -1
  108. package/esm/options/1_16/index.js +6 -4
  109. package/esm/options/1_16/index.js.map +1 -1
  110. package/esm/options/1_16/init.d.ts +66 -0
  111. package/esm/options/1_16/init.d.ts.map +1 -0
  112. package/esm/options/1_16/init.js +16 -0
  113. package/esm/options/1_16/init.js.map +1 -0
  114. package/esm/options/1_16/message.d.ts +32 -0
  115. package/esm/options/1_16/message.d.ts.map +1 -0
  116. package/esm/options/1_16/message.js +37 -0
  117. package/esm/options/1_16/message.js.map +1 -0
  118. package/esm/options/1_16/options.d.ts +48 -93
  119. package/esm/options/1_16/options.d.ts.map +1 -1
  120. package/esm/options/1_16/options.js +152 -189
  121. package/esm/options/1_16/options.js.map +1 -1
  122. package/esm/options/1_16/scroll.d.ts +26 -26
  123. package/esm/options/1_16/scroll.d.ts.map +1 -1
  124. package/esm/options/1_16/scroll.js +54 -55
  125. package/esm/options/1_16/scroll.js.map +1 -1
  126. package/esm/options/1_17.d.ts +33 -0
  127. package/esm/options/1_17.d.ts.map +1 -0
  128. package/esm/options/1_17.js +42 -0
  129. package/esm/options/1_17.js.map +1 -0
  130. package/esm/options/1_18.d.ts +59 -19
  131. package/esm/options/1_18.d.ts.map +1 -1
  132. package/esm/options/1_18.js +78 -45
  133. package/esm/options/1_18.js.map +1 -1
  134. package/esm/options/1_21.d.ts +41 -20
  135. package/esm/options/1_21.d.ts.map +1 -1
  136. package/esm/options/1_21.js +51 -36
  137. package/esm/options/1_21.js.map +1 -1
  138. package/esm/options/1_22/index.d.ts +3 -2
  139. package/esm/options/1_22/index.d.ts.map +1 -1
  140. package/esm/options/1_22/index.js +3 -2
  141. package/esm/options/1_22/index.js.map +1 -1
  142. package/esm/options/1_22/init.d.ts +17 -0
  143. package/esm/options/1_22/init.d.ts.map +1 -0
  144. package/esm/options/1_22/init.js +2 -0
  145. package/esm/options/1_22/init.js.map +1 -0
  146. package/esm/options/1_22/options.d.ts +35 -28
  147. package/esm/options/1_22/options.d.ts.map +1 -1
  148. package/esm/options/1_22/options.js +36 -25
  149. package/esm/options/1_22/options.js.map +1 -1
  150. package/esm/options/1_22/scroll.d.ts +16 -16
  151. package/esm/options/1_22/scroll.d.ts.map +1 -1
  152. package/esm/options/1_22/scroll.js +14 -14
  153. package/esm/options/1_23.d.ts +36 -11
  154. package/esm/options/1_23.d.ts.map +1 -1
  155. package/esm/options/1_23.js +44 -34
  156. package/esm/options/1_23.js.map +1 -1
  157. package/esm/options/1_24.d.ts +34 -8
  158. package/esm/options/1_24.d.ts.map +1 -1
  159. package/esm/options/1_24.js +22 -12
  160. package/esm/options/1_24.js.map +1 -1
  161. package/esm/options/1_25/index.d.ts +2 -2
  162. package/esm/options/1_25/index.js +2 -2
  163. package/esm/options/1_25/options.d.ts +10 -5
  164. package/esm/options/1_25/options.d.ts.map +1 -1
  165. package/esm/options/1_25/options.js +21 -7
  166. package/esm/options/1_25/options.js.map +1 -1
  167. package/esm/options/1_25/scroll.d.ts +19 -18
  168. package/esm/options/1_25/scroll.d.ts.map +1 -1
  169. package/esm/options/1_25/scroll.js +33 -32
  170. package/esm/options/1_25/scroll.js.map +1 -1
  171. package/esm/options/2_0.d.ts +91 -0
  172. package/esm/options/2_0.d.ts.map +1 -0
  173. package/esm/options/2_0.js +244 -0
  174. package/esm/options/2_0.js.map +1 -0
  175. package/esm/options/codec.d.ts +52 -0
  176. package/esm/options/codec.d.ts.map +1 -0
  177. package/esm/options/codec.js +26 -0
  178. package/esm/options/codec.js.map +1 -0
  179. package/esm/options/index.d.ts +12 -8
  180. package/esm/options/index.d.ts.map +1 -1
  181. package/esm/options/index.js +12 -8
  182. package/esm/options/index.js.map +1 -1
  183. package/esm/options/latest.d.ts +12 -0
  184. package/esm/options/latest.d.ts.map +1 -0
  185. package/esm/options/latest.js +8 -0
  186. package/esm/options/latest.js.map +1 -0
  187. package/esm/options/types.d.ts +86 -46
  188. package/esm/options/types.d.ts.map +1 -1
  189. package/esm/options/types.js +69 -17
  190. package/esm/options/types.js.map +1 -1
  191. package/package.json +10 -16
  192. package/src/codec/av1.ts +33 -0
  193. package/src/codec/h264.ts +317 -0
  194. package/src/codec/h265.ts +1375 -0
  195. package/src/codec/index.ts +4 -0
  196. package/src/codec/nalu.ts +373 -0
  197. package/src/control/back-or-screen-on.ts +1 -1
  198. package/src/control/basic.ts +3 -0
  199. package/src/control/hover-helper.ts +2 -4
  200. package/src/control/index.ts +2 -0
  201. package/src/control/inject-keycode.ts +194 -51
  202. package/src/control/inject-scroll.ts +1 -1
  203. package/src/control/inject-text.ts +6 -9
  204. package/src/control/inject-touch.ts +16 -55
  205. package/src/control/rotate-device.ts +3 -7
  206. package/src/control/serializer.ts +49 -105
  207. package/src/control/set-clipboard.ts +1 -1
  208. package/src/control/set-screen-power-mode.ts +6 -9
  209. package/src/control/type.ts +32 -0
  210. package/src/control/writer.ts +87 -0
  211. package/src/device-message/ack-clipboard.ts +1 -1
  212. package/src/device-message/clipboard.ts +1 -1
  213. package/src/device-message/stream.ts +32 -12
  214. package/src/index.ts +4 -5
  215. package/src/options/1_16/codec-options.ts +5 -8
  216. package/src/options/1_16/float-to-uint16.ts +33 -0
  217. package/src/options/1_16/index.ts +3 -1
  218. package/src/options/1_16/init.ts +80 -0
  219. package/src/options/1_16/message.ts +55 -0
  220. package/src/options/1_16/options.ts +152 -256
  221. package/src/options/1_16/scroll.ts +2 -5
  222. package/src/options/1_17.ts +66 -0
  223. package/src/options/1_18.ts +106 -42
  224. package/src/options/1_21.ts +51 -30
  225. package/src/options/1_22/index.ts +1 -0
  226. package/src/options/1_22/init.ts +19 -0
  227. package/src/options/1_22/options.ts +40 -46
  228. package/src/options/1_22/scroll.ts +2 -2
  229. package/src/options/1_23.ts +33 -23
  230. package/src/options/1_24.ts +25 -11
  231. package/src/options/1_25/options.ts +25 -6
  232. package/src/options/1_25/scroll.ts +5 -7
  233. package/src/options/2_0.ts +342 -0
  234. package/src/options/codec.ts +98 -0
  235. package/src/options/index.ts +7 -3
  236. package/src/options/latest.ts +14 -0
  237. package/src/options/types.ts +158 -48
  238. package/tsconfig.build.json +9 -1
  239. package/tsconfig.build.tsbuildinfo +1 -1
  240. package/esm/adb/client.d.ts +0 -41
  241. package/esm/adb/client.d.ts.map +0 -1
  242. package/esm/adb/client.js +0 -243
  243. package/esm/adb/client.js.map +0 -1
  244. package/esm/adb/connection.d.ts +0 -47
  245. package/esm/adb/connection.d.ts.map +0 -1
  246. package/esm/adb/connection.js +0 -110
  247. package/esm/adb/connection.js.map +0 -1
  248. package/esm/adb/index.d.ts +0 -4
  249. package/esm/adb/index.d.ts.map +0 -1
  250. package/esm/adb/index.js +0 -4
  251. package/esm/adb/index.js.map +0 -1
  252. package/esm/adb/options/1_16.d.ts +0 -8
  253. package/esm/adb/options/1_16.d.ts.map +0 -1
  254. package/esm/adb/options/1_16.js +0 -20
  255. package/esm/adb/options/1_16.js.map +0 -1
  256. package/esm/adb/options/1_22.d.ts +0 -8
  257. package/esm/adb/options/1_22.d.ts.map +0 -1
  258. package/esm/adb/options/1_22.js +0 -17
  259. package/esm/adb/options/1_22.js.map +0 -1
  260. package/esm/adb/options/index.d.ts +0 -4
  261. package/esm/adb/options/index.d.ts.map +0 -1
  262. package/esm/adb/options/index.js +0 -4
  263. package/esm/adb/options/index.js.map +0 -1
  264. package/esm/adb/options/types.d.ts +0 -24
  265. package/esm/adb/options/types.d.ts.map +0 -1
  266. package/esm/adb/options/types.js +0 -37
  267. package/esm/adb/options/types.js.map +0 -1
  268. package/esm/codec.d.ts +0 -34
  269. package/esm/codec.d.ts.map +0 -1
  270. package/esm/codec.js +0 -37
  271. package/esm/codec.js.map +0 -1
  272. package/esm/options/1_16/h264-configuration.d.ts +0 -49
  273. package/esm/options/1_16/h264-configuration.d.ts.map +0 -1
  274. package/esm/options/1_16/h264-configuration.js +0 -414
  275. package/esm/options/1_16/h264-configuration.js.map +0 -1
  276. package/esm/options/1_16/sps.d.ts +0 -22
  277. package/esm/options/1_16/sps.d.ts.map +0 -1
  278. package/esm/options/1_16/sps.js +0 -263
  279. package/esm/options/1_16/sps.js.map +0 -1
  280. package/src/adb/client.ts +0 -345
  281. package/src/adb/connection.ts +0 -192
  282. package/src/adb/index.ts +0 -3
  283. package/src/adb/options/1_16.ts +0 -30
  284. package/src/adb/options/1_22.ts +0 -26
  285. package/src/adb/options/index.ts +0 -3
  286. package/src/adb/options/types.ts +0 -75
  287. package/src/codec.ts +0 -35
  288. 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;
@@ -1,8 +1,12 @@
1
- export * from './1_16/index.js';
2
- export * from './1_18.js';
3
- export * from './1_21.js';
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";