@yume-chan/scrcpy 0.0.17 → 0.0.18

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 (214) hide show
  1. package/CHANGELOG.json +21 -3
  2. package/CHANGELOG.md +13 -4
  3. package/LICENSE +1 -1
  4. package/README.md +41 -24
  5. package/bin/scrcpy-server +0 -0
  6. package/bin/version.d.ts +1 -1
  7. package/bin/version.js +1 -1
  8. package/esm/adb/client.d.ts +15 -14
  9. package/esm/adb/client.d.ts.map +1 -1
  10. package/esm/adb/client.js +66 -41
  11. package/esm/adb/client.js.map +1 -1
  12. package/esm/adb/connection.d.ts +16 -7
  13. package/esm/adb/connection.d.ts.map +1 -1
  14. package/esm/adb/connection.js +21 -13
  15. package/esm/adb/connection.js.map +1 -1
  16. package/esm/adb/options/1_16.d.ts +4 -4
  17. package/esm/adb/options/1_16.d.ts.map +1 -1
  18. package/esm/adb/options/1_16.js +2 -2
  19. package/esm/adb/options/1_16.js.map +1 -1
  20. package/esm/adb/options/1_22.d.ts +4 -4
  21. package/esm/adb/options/1_22.d.ts.map +1 -1
  22. package/esm/adb/options/1_22.js +2 -2
  23. package/esm/adb/options/1_22.js.map +1 -1
  24. package/esm/adb/options/types.d.ts +10 -9
  25. package/esm/adb/options/types.d.ts.map +1 -1
  26. package/esm/adb/options/types.js +11 -4
  27. package/esm/adb/options/types.js.map +1 -1
  28. package/esm/control/back-or-screen-on.d.ts +3 -0
  29. package/esm/control/back-or-screen-on.d.ts.map +1 -0
  30. package/esm/control/back-or-screen-on.js +2 -0
  31. package/esm/control/back-or-screen-on.js.map +1 -0
  32. package/esm/control/hover-helper.d.ts +18 -0
  33. package/esm/control/hover-helper.d.ts.map +1 -0
  34. package/esm/control/hover-helper.js +44 -0
  35. package/esm/control/hover-helper.js.map +1 -0
  36. package/esm/control/index.d.ts +11 -7
  37. package/esm/control/index.d.ts.map +1 -1
  38. package/esm/control/index.js +11 -7
  39. package/esm/control/index.js.map +1 -1
  40. package/esm/control/inject-keycode.d.ts +12 -4
  41. package/esm/control/inject-keycode.d.ts.map +1 -1
  42. package/esm/control/inject-keycode.js +15 -7
  43. package/esm/control/inject-keycode.js.map +1 -1
  44. package/esm/control/inject-scroll.d.ts +3 -0
  45. package/esm/control/inject-scroll.d.ts.map +1 -0
  46. package/esm/control/inject-scroll.js +2 -0
  47. package/esm/control/inject-scroll.js.map +1 -0
  48. package/esm/control/inject-text.d.ts +2 -2
  49. package/esm/control/inject-text.d.ts.map +1 -1
  50. package/esm/control/inject-touch.d.ts +12 -4
  51. package/esm/control/inject-touch.d.ts.map +1 -1
  52. package/esm/control/inject-touch.js +44 -11
  53. package/esm/control/inject-touch.js.map +1 -1
  54. package/esm/control/rotate-device.d.ts +2 -2
  55. package/esm/control/rotate-device.d.ts.map +1 -1
  56. package/esm/control/serializer.d.ts +22 -11
  57. package/esm/control/serializer.d.ts.map +1 -1
  58. package/esm/control/serializer.js +32 -26
  59. package/esm/control/serializer.js.map +1 -1
  60. package/esm/control/set-clipboard.d.ts +3 -0
  61. package/esm/control/set-clipboard.d.ts.map +1 -0
  62. package/esm/control/set-clipboard.js +2 -0
  63. package/esm/control/set-clipboard.js.map +1 -0
  64. package/esm/control/set-screen-power-mode.d.ts +2 -2
  65. package/esm/control/set-screen-power-mode.d.ts.map +1 -1
  66. package/esm/device-message/ack-clipboard.d.ts +9 -0
  67. package/esm/device-message/ack-clipboard.d.ts.map +1 -0
  68. package/esm/device-message/ack-clipboard.js +6 -0
  69. package/esm/device-message/ack-clipboard.js.map +1 -0
  70. package/esm/device-message/clipboard.d.ts +3 -3
  71. package/esm/device-message/clipboard.d.ts.map +1 -1
  72. package/esm/device-message/clipboard.js +4 -4
  73. package/esm/device-message/clipboard.js.map +1 -1
  74. package/esm/device-message/index.d.ts +4 -3
  75. package/esm/device-message/index.d.ts.map +1 -1
  76. package/esm/device-message/index.js +4 -3
  77. package/esm/device-message/index.js.map +1 -1
  78. package/esm/device-message/stream.d.ts +4 -3
  79. package/esm/device-message/stream.d.ts.map +1 -1
  80. package/esm/device-message/stream.js +8 -4
  81. package/esm/device-message/stream.js.map +1 -1
  82. package/esm/options/1_16/codec-options.d.ts +3 -2
  83. package/esm/options/1_16/codec-options.d.ts.map +1 -1
  84. package/esm/options/1_16/codec-options.js +6 -7
  85. package/esm/options/1_16/codec-options.js.map +1 -1
  86. package/esm/options/1_16/h264-configuration.d.ts +49 -0
  87. package/esm/options/1_16/h264-configuration.d.ts.map +1 -0
  88. package/esm/options/1_16/h264-configuration.js +414 -0
  89. package/esm/options/1_16/h264-configuration.js.map +1 -0
  90. package/esm/options/1_16/index.d.ts +4 -3
  91. package/esm/options/1_16/index.d.ts.map +1 -1
  92. package/esm/options/1_16/index.js +4 -3
  93. package/esm/options/1_16/index.js.map +1 -1
  94. package/esm/options/1_16/options.d.ts +17 -20
  95. package/esm/options/1_16/options.d.ts.map +1 -1
  96. package/esm/options/1_16/options.js +51 -49
  97. package/esm/options/1_16/options.js.map +1 -1
  98. package/esm/options/1_16/scroll.d.ts +27 -0
  99. package/esm/options/1_16/scroll.d.ts.map +1 -0
  100. package/esm/options/1_16/scroll.js +56 -0
  101. package/esm/options/1_16/scroll.js.map +1 -0
  102. package/esm/options/1_16/sps.d.ts +1 -1
  103. package/esm/options/1_16/sps.d.ts.map +1 -1
  104. package/esm/options/1_16/sps.js +25 -17
  105. package/esm/options/1_16/sps.js.map +1 -1
  106. package/esm/options/1_18.d.ts +6 -6
  107. package/esm/options/1_18.d.ts.map +1 -1
  108. package/esm/options/1_18.js +5 -5
  109. package/esm/options/1_18.js.map +1 -1
  110. package/esm/options/1_21.d.ts +12 -1
  111. package/esm/options/1_21.d.ts.map +1 -1
  112. package/esm/options/1_21.js +14 -3
  113. package/esm/options/1_21.js.map +1 -1
  114. package/esm/options/1_22/index.d.ts +3 -0
  115. package/esm/options/1_22/index.d.ts.map +1 -0
  116. package/esm/options/1_22/index.js +3 -0
  117. package/esm/options/1_22/index.js.map +1 -0
  118. package/esm/options/{1_22.d.ts → 1_22/options.d.ts} +4 -15
  119. package/esm/options/1_22/options.d.ts.map +1 -0
  120. package/esm/options/{1_22.js → 1_22/options.js} +5 -9
  121. package/esm/options/1_22/options.js.map +1 -0
  122. package/esm/options/1_22/scroll.d.ts +17 -0
  123. package/esm/options/1_22/scroll.d.ts.map +1 -0
  124. package/esm/options/1_22/scroll.js +15 -0
  125. package/esm/options/1_22/scroll.js.map +1 -0
  126. package/esm/options/1_23.d.ts +3 -3
  127. package/esm/options/1_23.d.ts.map +1 -1
  128. package/esm/options/1_23.js +7 -6
  129. package/esm/options/1_23.js.map +1 -1
  130. package/esm/options/1_25/index.d.ts +3 -0
  131. package/esm/options/1_25/index.d.ts.map +1 -0
  132. package/esm/options/1_25/index.js +3 -0
  133. package/esm/options/1_25/index.js.map +1 -0
  134. package/esm/options/1_25/options.d.ts +6 -0
  135. package/esm/options/1_25/options.d.ts.map +1 -0
  136. package/esm/options/1_25/options.js +8 -0
  137. package/esm/options/1_25/options.js.map +1 -0
  138. package/esm/options/1_25/scroll.d.ts +19 -0
  139. package/esm/options/1_25/scroll.d.ts.map +1 -0
  140. package/esm/options/1_25/scroll.js +33 -0
  141. package/esm/options/1_25/scroll.js.map +1 -0
  142. package/esm/options/index.d.ts +5 -4
  143. package/esm/options/index.d.ts.map +1 -1
  144. package/esm/options/index.js +5 -4
  145. package/esm/options/index.js.map +1 -1
  146. package/esm/options/types.d.ts +14 -12
  147. package/esm/options/types.d.ts.map +1 -1
  148. package/esm/options/types.js +6 -4
  149. package/esm/options/types.js.map +1 -1
  150. package/package.json +19 -12
  151. package/scripts/fetch-server.cjs +19 -9
  152. package/src/adb/client.ts +142 -89
  153. package/src/adb/connection.ts +77 -30
  154. package/src/adb/options/1_16.ts +13 -6
  155. package/src/adb/options/1_22.ts +12 -6
  156. package/src/adb/options/types.ts +34 -14
  157. package/src/control/back-or-screen-on.ts +4 -0
  158. package/src/control/hover-helper.ts +56 -0
  159. package/src/control/index.ts +11 -7
  160. package/src/control/inject-keycode.ts +23 -10
  161. package/src/control/inject-scroll.ts +4 -0
  162. package/src/control/inject-touch.ts +58 -14
  163. package/src/control/serializer.ts +106 -41
  164. package/src/control/set-clipboard.ts +4 -0
  165. package/src/device-message/ack-clipboard.ts +10 -0
  166. package/src/device-message/clipboard.ts +8 -8
  167. package/src/device-message/index.ts +4 -3
  168. package/src/device-message/stream.ts +17 -7
  169. package/src/options/1_16/codec-options.ts +17 -10
  170. package/src/options/1_16/h264-configuration.ts +485 -0
  171. package/src/options/1_16/index.ts +4 -3
  172. package/src/options/1_16/options.ts +175 -130
  173. package/src/options/1_16/scroll.ts +76 -0
  174. package/src/options/1_18.ts +22 -12
  175. package/src/options/1_21.ts +31 -13
  176. package/src/options/1_22/index.ts +2 -0
  177. package/src/options/{1_22.ts → 1_22/options.ts} +8 -17
  178. package/src/options/1_22/scroll.ts +26 -0
  179. package/src/options/1_23.ts +32 -20
  180. package/src/options/1_25/index.ts +2 -0
  181. package/src/options/1_25/options.ts +12 -0
  182. package/src/options/1_25/scroll.ts +52 -0
  183. package/src/options/index.ts +5 -4
  184. package/src/options/types.ts +34 -17
  185. package/tsconfig.build.json +1 -1
  186. package/tsconfig.build.tsbuildinfo +1 -1
  187. package/esm/decoder/index.d.ts +0 -28
  188. package/esm/decoder/index.d.ts.map +0 -1
  189. package/esm/decoder/index.js +0 -2
  190. package/esm/decoder/index.js.map +0 -1
  191. package/esm/decoder/tinyh264/index.d.ts +0 -20
  192. package/esm/decoder/tinyh264/index.d.ts.map +0 -1
  193. package/esm/decoder/tinyh264/index.js +0 -86
  194. package/esm/decoder/tinyh264/index.js.map +0 -1
  195. package/esm/decoder/tinyh264/worker.d.ts +0 -2
  196. package/esm/decoder/tinyh264/worker.d.ts.map +0 -1
  197. package/esm/decoder/tinyh264/worker.js +0 -3
  198. package/esm/decoder/tinyh264/worker.js.map +0 -1
  199. package/esm/decoder/tinyh264/wrapper.d.ts +0 -21
  200. package/esm/decoder/tinyh264/wrapper.d.ts.map +0 -1
  201. package/esm/decoder/tinyh264/wrapper.js +0 -74
  202. package/esm/decoder/tinyh264/wrapper.js.map +0 -1
  203. package/esm/decoder/types.d.ts +0 -2
  204. package/esm/decoder/types.d.ts.map +0 -1
  205. package/esm/decoder/types.js +0 -2
  206. package/esm/decoder/types.js.map +0 -1
  207. package/esm/decoder/web-codecs/index.d.ts +0 -22
  208. package/esm/decoder/web-codecs/index.d.ts.map +0 -1
  209. package/esm/decoder/web-codecs/index.js +0 -81
  210. package/esm/decoder/web-codecs/index.js.map +0 -1
  211. package/esm/options/1_22.d.ts.map +0 -1
  212. package/esm/options/1_22.js.map +0 -1
  213. package/src/options/1_16/sps.ts +0 -300
  214. package/tsconfig.test.tsbuildinfo +0 -1
package/src/adb/client.ts CHANGED
@@ -1,12 +1,35 @@
1
- import { Adb, AdbSubprocessNoneProtocol, AdbSubprocessProtocol, AdbSync } from '@yume-chan/adb';
2
- import { AbortController, DecodeUtf8Stream, InspectStream, ReadableStream, SplitStringStream, WrapWritableStream, WritableStream, type ReadableStreamDefaultController, type ReadableStreamDefaultReader, type ReadableWritablePair } from '@yume-chan/stream-extra';
3
-
4
- import { ScrcpyControlMessageSerializer } from '../control/index.js';
5
- import { ScrcpyDeviceMessageDeserializeStream, type ScrcpyDeviceMessage } from '../device-message/index.js';
6
- import { DEFAULT_SERVER_PATH, type ScrcpyVideoStreamPacket } from '../options/index.js';
7
- import type { AdbScrcpyOptions } from './options/index.js';
8
-
9
- class ArrayToStream<T> extends ReadableStream<T>{
1
+ import {
2
+ AdbSubprocessNoneProtocol,
3
+ type Adb,
4
+ type AdbSubprocessProtocol,
5
+ type AdbSync,
6
+ } from "@yume-chan/adb";
7
+ import {
8
+ AbortController,
9
+ DecodeUtf8Stream,
10
+ InspectStream,
11
+ ReadableStream,
12
+ SplitStringStream,
13
+ WrapWritableStream,
14
+ WritableStream,
15
+ type ReadableStreamDefaultController,
16
+ type ReadableStreamDefaultReader,
17
+ type ReadableWritablePair,
18
+ } from "@yume-chan/stream-extra";
19
+
20
+ import { ScrcpyControlMessageSerializer } from "../control/index.js";
21
+ import {
22
+ ScrcpyDeviceMessageDeserializeStream,
23
+ type ScrcpyDeviceMessage,
24
+ } from "../device-message/index.js";
25
+ import {
26
+ DEFAULT_SERVER_PATH,
27
+ type ScrcpyVideoStreamPacket,
28
+ } from "../options/index.js";
29
+
30
+ import { type AdbScrcpyOptions } from "./options/index.js";
31
+
32
+ class ArrayToStream<T> extends ReadableStream<T> {
10
33
  private array!: T[];
11
34
  private index = 0;
12
35
 
@@ -28,7 +51,7 @@ class ArrayToStream<T> extends ReadableStream<T>{
28
51
  }
29
52
  }
30
53
 
31
- class ConcatStream<T> extends ReadableStream<T>{
54
+ class ConcatStream<T> extends ReadableStream<T> {
32
55
  private streams!: ReadableStream<T>[];
33
56
  private index = 0;
34
57
  private reader!: ReadableStreamDefaultReader<T>;
@@ -48,7 +71,7 @@ class ConcatStream<T> extends ReadableStream<T>{
48
71
  return;
49
72
  }
50
73
  this.advance(controller);
51
- }
74
+ },
52
75
  });
53
76
  }
54
77
 
@@ -62,11 +85,17 @@ class ConcatStream<T> extends ReadableStream<T>{
62
85
  }
63
86
  }
64
87
 
88
+ export class ScrcpyExitedError extends Error {
89
+ public output: string[];
90
+
91
+ public constructor(output: string[]) {
92
+ super("scrcpy server exited prematurely");
93
+ this.output = output;
94
+ }
95
+ }
96
+
65
97
  export class AdbScrcpyClient {
66
- public static pushServer(
67
- adb: Adb,
68
- path = DEFAULT_SERVER_PATH,
69
- ) {
98
+ public static pushServer(adb: Adb, path = DEFAULT_SERVER_PATH) {
70
99
  let sync!: AdbSync;
71
100
  return new WrapWritableStream<Uint8Array>({
72
101
  async start() {
@@ -83,7 +112,7 @@ export class AdbScrcpyClient {
83
112
  adb: Adb,
84
113
  path: string,
85
114
  version: string,
86
- options: AdbScrcpyOptions<any>
115
+ options: AdbScrcpyOptions<object>
87
116
  ) {
88
117
  const connection = options.createConnection(adb);
89
118
  let process: AdbSubprocessProtocol | undefined;
@@ -95,9 +124,9 @@ export class AdbScrcpyClient {
95
124
  [
96
125
  // cspell: disable-next-line
97
126
  `CLASSPATH=${path}`,
98
- 'app_process',
99
- /* unused */ '/',
100
- 'com.genymobile.scrcpy.Server',
127
+ "app_process",
128
+ /* unused */ "/",
129
+ "com.genymobile.scrcpy.Server",
101
130
  version,
102
131
  ...options.formatServerArguments(),
103
132
  ],
@@ -110,31 +139,34 @@ export class AdbScrcpyClient {
110
139
 
111
140
  const stdout = process.stdout
112
141
  .pipeThrough(new DecodeUtf8Stream())
113
- .pipeThrough(new SplitStringStream('\n'));
142
+ .pipeThrough(new SplitStringStream("\n"));
114
143
 
115
144
  // Read stdout, otherwise `process.exit` won't resolve.
116
145
  const output: string[] = [];
117
146
  const abortController = new AbortController();
118
147
  const pipe = stdout
119
- .pipeTo(new WritableStream({
120
- write(chunk) {
121
- output.push(chunk);
148
+ .pipeTo(
149
+ new WritableStream({
150
+ write(chunk) {
151
+ output.push(chunk);
152
+ },
153
+ }),
154
+ {
155
+ signal: abortController.signal,
156
+ preventCancel: true,
122
157
  }
123
- }), {
124
- signal: abortController.signal,
125
- preventCancel: true,
126
- })
127
- .catch(() => { });
158
+ )
159
+ .catch((e) => {
160
+ void e;
161
+ });
128
162
 
129
163
  const result = await Promise.race([
130
164
  process.exit,
131
165
  connection.getStreams(),
132
166
  ]);
133
167
 
134
- if (typeof result === 'number') {
135
- const error = new Error('scrcpy server exited prematurely');
136
- (error as any).output = output;
137
- throw error;
168
+ if (typeof result === "number") {
169
+ throw new ScrcpyExitedError(output);
138
170
  }
139
171
 
140
172
  abortController.abort();
@@ -144,10 +176,7 @@ export class AdbScrcpyClient {
144
176
  return new AdbScrcpyClient(
145
177
  options,
146
178
  process,
147
- new ConcatStream(
148
- new ArrayToStream(output),
149
- stdout,
150
- ),
179
+ new ConcatStream(new ArrayToStream(output), stdout),
151
180
  videoStream,
152
181
  controlStream
153
182
  );
@@ -167,35 +196,34 @@ export class AdbScrcpyClient {
167
196
  adb: Adb,
168
197
  path: string,
169
198
  version: string,
170
- options: AdbScrcpyOptions<any>
199
+ options: AdbScrcpyOptions<object>
171
200
  ): Promise<string[]> {
172
- // Provide an invalid encoder name
173
- // So the server will return all available encoders
174
- options.value.encoderName = '_';
175
- // Disable control for faster connection in 1.22+
176
- options.value.control = false;
177
- options.value.sendDeviceMeta = false;
178
- options.value.sendDummyByte = false;
201
+ Object.assign(options.value, {
202
+ // Provide an invalid encoder name
203
+ // So the server will return all available encoders
204
+ encoderName: "_",
205
+ // Disable control for faster connection in 1.22+
206
+ control: false,
207
+ sendDeviceMeta: false,
208
+ sendDummyByte: false,
209
+ });
179
210
 
180
211
  // Scrcpy server will open connections, before initializing encoder
181
212
  // Thus although an invalid encoder name is given, the start process will success
182
- const client = await AdbScrcpyClient.start(
183
- adb,
184
- path,
185
- version,
186
- options
187
- );
213
+ const client = await AdbScrcpyClient.start(adb, path, version, options);
188
214
 
189
215
  const encoderNameRegex = options.getOutputEncoderNameRegex();
190
216
  const encoders: string[] = [];
191
- await client.stdout.pipeTo(new WritableStream({
192
- write(line) {
193
- const match = line.match(encoderNameRegex);
194
- if (match) {
195
- encoders.push(match[1]!);
196
- }
197
- },
198
- }));
217
+ await client.stdout.pipeTo(
218
+ new WritableStream({
219
+ write(line) {
220
+ const match = line.match(encoderNameRegex);
221
+ if (match) {
222
+ encoders.push(match[1]!);
223
+ }
224
+ },
225
+ })
226
+ );
199
227
 
200
228
  return encoders;
201
229
  }
@@ -208,25 +236,25 @@ export class AdbScrcpyClient {
208
236
  adb: Adb,
209
237
  path: string,
210
238
  version: string,
211
- options: AdbScrcpyOptions<any>
239
+ options: AdbScrcpyOptions<object>
212
240
  ): Promise<number[]> {
213
- // Similar to `getEncoders`, pass an invalid option and parse the output
214
- options.value.displayId = -1;
215
-
216
- options.value.control = false;
217
- options.value.sendDeviceMeta = false;
218
- options.value.sendDummyByte = false;
241
+ Object.assign(options.value, {
242
+ // Similar to `getEncoders`, pass an invalid option and parse the output
243
+ displayId: -1,
244
+ // Disable control for faster connection in 1.22+
245
+ control: false,
246
+ sendDeviceMeta: false,
247
+ sendDummyByte: false,
248
+ });
219
249
 
220
250
  try {
221
251
  // Server will exit before opening connections when an invalid display id was given.
222
252
  await AdbScrcpyClient.start(adb, path, version, options);
223
253
  } catch (e) {
224
- if (e instanceof Error) {
225
- const output = (e as any).output as string[];
226
-
254
+ if (e instanceof ScrcpyExitedError) {
227
255
  const displayIdRegex = /\s+scrcpy --display (\d+)/;
228
256
  const displays: number[] = [];
229
- for (const line of output) {
257
+ for (const line of e.output) {
230
258
  const match = line.match(displayIdRegex);
231
259
  if (match) {
232
260
  displays.push(Number.parseInt(match[1]!, 10));
@@ -236,53 +264,78 @@ export class AdbScrcpyClient {
236
264
  }
237
265
  }
238
266
 
239
- throw new Error('failed to get displays');
267
+ throw new Error("failed to get displays");
240
268
  }
241
269
 
242
270
  private process: AdbSubprocessProtocol;
243
271
 
244
272
  private _stdout: ReadableStream<string>;
245
- public get stdout() { return this._stdout; }
273
+ public get stdout() {
274
+ return this._stdout;
275
+ }
246
276
 
247
- public get exit() { return this.process.exit; }
277
+ public get exit() {
278
+ return this.process.exit;
279
+ }
248
280
 
249
281
  private _screenWidth: number | undefined;
250
- public get screenWidth() { return this._screenWidth; }
282
+ public get screenWidth() {
283
+ return this._screenWidth;
284
+ }
251
285
 
252
286
  private _screenHeight: number | undefined;
253
- public get screenHeight() { return this._screenHeight; }
287
+ public get screenHeight() {
288
+ return this._screenHeight;
289
+ }
254
290
 
255
291
  private _videoStream: ReadableStream<ScrcpyVideoStreamPacket>;
256
- public get videoStream() { return this._videoStream; }
292
+ public get videoStream() {
293
+ return this._videoStream;
294
+ }
257
295
 
258
- private _controlMessageSerializer: ScrcpyControlMessageSerializer | undefined;
259
- public get controlMessageSerializer() { return this._controlMessageSerializer; }
296
+ private _controlMessageSerializer:
297
+ | ScrcpyControlMessageSerializer
298
+ | undefined;
299
+ public get controlMessageSerializer() {
300
+ return this._controlMessageSerializer;
301
+ }
260
302
 
261
- private _deviceMessageStream: ReadableStream<ScrcpyDeviceMessage> | undefined;
262
- public get deviceMessageStream() { return this._deviceMessageStream; }
303
+ private _deviceMessageStream:
304
+ | ReadableStream<ScrcpyDeviceMessage>
305
+ | undefined;
306
+ public get deviceMessageStream() {
307
+ return this._deviceMessageStream;
308
+ }
263
309
 
264
310
  public constructor(
265
- options: AdbScrcpyOptions<any>,
311
+ options: AdbScrcpyOptions<object>,
266
312
  process: AdbSubprocessProtocol,
267
313
  stdout: ReadableStream<string>,
268
314
  videoStream: ReadableStream<Uint8Array>,
269
- controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined,
315
+ controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined
270
316
  ) {
271
317
  this.process = process;
272
318
  this._stdout = stdout;
273
319
 
274
320
  this._videoStream = videoStream
275
321
  .pipeThrough(options.createVideoStreamTransformer())
276
- .pipeThrough(new InspectStream(packet => {
277
- if (packet.type === 'configuration') {
278
- this._screenWidth = packet.data.croppedWidth;
279
- this._screenHeight = packet.data.croppedHeight;
280
- }
281
- }));
322
+ .pipeThrough(
323
+ new InspectStream((packet) => {
324
+ if (packet.type === "configuration") {
325
+ this._screenWidth = packet.data.croppedWidth;
326
+ this._screenHeight = packet.data.croppedHeight;
327
+ }
328
+ })
329
+ );
282
330
 
283
331
  if (controlStream) {
284
- this._controlMessageSerializer = new ScrcpyControlMessageSerializer(controlStream.writable, options);
285
- this._deviceMessageStream = controlStream.readable.pipeThrough(new ScrcpyDeviceMessageDeserializeStream());
332
+ this._controlMessageSerializer = new ScrcpyControlMessageSerializer(
333
+ controlStream.writable,
334
+ options
335
+ );
336
+ this._deviceMessageStream = controlStream.readable.pipeThrough(
337
+ new ScrcpyDeviceMessageDeserializeStream()
338
+ );
286
339
  }
287
340
  }
288
341
 
@@ -1,8 +1,13 @@
1
- import type { Adb } from '@yume-chan/adb';
2
- import { delay } from '@yume-chan/async';
3
- import type { Disposable } from '@yume-chan/event';
4
- import { TransformStream, type ReadableStream, type ReadableStreamDefaultReader, type ReadableWritablePair } from '@yume-chan/stream-extra';
5
- import type { ValueOrPromise } from '@yume-chan/struct';
1
+ import { type Adb } from "@yume-chan/adb";
2
+ import { delay } from "@yume-chan/async";
3
+ import { type Disposable } from "@yume-chan/event";
4
+ import {
5
+ TransformStream,
6
+ type ReadableStream,
7
+ type ReadableStreamDefaultReader,
8
+ type ReadableWritablePair,
9
+ } from "@yume-chan/stream-extra";
10
+ import { type ValueOrPromise } from "@yume-chan/struct";
6
11
 
7
12
  export interface AdbScrcpyConnectionOptions {
8
13
  control: boolean;
@@ -28,20 +33,33 @@ export abstract class AdbScrcpyConnection implements Disposable {
28
33
  this.options = options;
29
34
  }
30
35
 
31
- public initialize(): ValueOrPromise<void> { }
32
-
33
- public abstract getStreams(): ValueOrPromise<[videoSteam: ReadableStream<Uint8Array>, controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined]>;
36
+ public initialize(): ValueOrPromise<void> {
37
+ // do nothing
38
+ }
34
39
 
35
- public dispose(): void { }
40
+ public abstract getStreams(): ValueOrPromise<
41
+ [
42
+ videoSteam: ReadableStream<Uint8Array>,
43
+ controlStream:
44
+ | ReadableWritablePair<Uint8Array, Uint8Array>
45
+ | undefined
46
+ ]
47
+ >;
48
+
49
+ public dispose(): void {
50
+ // do nothing
51
+ }
36
52
  }
37
53
 
38
54
  export class AdbScrcpyForwardConnection extends AdbScrcpyConnection {
39
55
  private connect(): Promise<ReadableWritablePair<Uint8Array, Uint8Array>> {
40
- return this.adb.createSocket('localabstract:scrcpy');
56
+ return this.adb.createSocket("localabstract:scrcpy");
41
57
  }
42
58
 
43
- private async connectAndRetry(): Promise<ReadableWritablePair<Uint8Array, Uint8Array>> {
44
- for (let i = 0; i < 100; i++) {
59
+ private async connectAndRetry(): Promise<
60
+ ReadableWritablePair<Uint8Array, Uint8Array>
61
+ > {
62
+ for (let i = 0; i < 100; i += 1) {
45
63
  try {
46
64
  return await this.connect();
47
65
  } catch (e) {
@@ -58,17 +76,26 @@ export class AdbScrcpyForwardConnection extends AdbScrcpyConnection {
58
76
  const { done, value } = await reader.read();
59
77
  // server will write a `0` to signal connection success
60
78
  if (done || value.byteLength !== 1 || value[0] !== 0) {
61
- throw new Error('Unexpected response from server');
79
+ throw new Error("Unexpected response from server");
62
80
  }
63
81
  reader.releaseLock();
64
82
  }
65
83
  return videoStream;
66
84
  }
67
85
 
68
- public async getStreams(): Promise<[videoSteam: ReadableStream<Uint8Array>, controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined]> {
86
+ public async getStreams(): Promise<
87
+ [
88
+ videoSteam: ReadableStream<Uint8Array>,
89
+ controlStream:
90
+ | ReadableWritablePair<Uint8Array, Uint8Array>
91
+ | undefined
92
+ ]
93
+ > {
69
94
  const videoStream = await this.connectVideoStream();
70
95
 
71
- let controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined;
96
+ let controlStream:
97
+ | ReadableWritablePair<Uint8Array, Uint8Array>
98
+ | undefined;
72
99
  if (this.options.control) {
73
100
  controlStream = await this.connectAndRetry();
74
101
  }
@@ -79,7 +106,7 @@ export class AdbScrcpyForwardConnection extends AdbScrcpyConnection {
79
106
  const { done, value } = await reader.read();
80
107
  // 64 bytes device name + 2 bytes video width + 2 bytes video height
81
108
  if (done || value.byteLength !== 64 + 2 + 2) {
82
- throw new Error('Unexpected response from server');
109
+ throw new Error("Unexpected response from server");
83
110
  }
84
111
  reader.releaseLock();
85
112
  }
@@ -89,35 +116,53 @@ export class AdbScrcpyForwardConnection extends AdbScrcpyConnection {
89
116
  }
90
117
 
91
118
  export class AdbScrcpyReverseConnection extends AdbScrcpyConnection {
92
- private streams!: ReadableStreamDefaultReader<ReadableWritablePair<Uint8Array, Uint8Array>>;
119
+ private streams!: ReadableStreamDefaultReader<
120
+ ReadableWritablePair<Uint8Array, Uint8Array>
121
+ >;
93
122
 
94
123
  private address!: string;
95
124
 
96
125
  public override async initialize(): Promise<void> {
97
126
  // try to unbind first, ignore errors
98
- await this.adb.reverse.remove('localabstract:scrcpy').catch(() => { });
99
-
100
- const queue = new TransformStream<ReadableWritablePair<Uint8Array, Uint8Array>>();
127
+ await this.adb.reverse.remove("localabstract:scrcpy").catch((e) => {
128
+ void e;
129
+ });
130
+
131
+ const queue = new TransformStream<
132
+ ReadableWritablePair<Uint8Array, Uint8Array>,
133
+ ReadableWritablePair<Uint8Array, Uint8Array>
134
+ >();
101
135
  this.streams = queue.readable.getReader();
102
136
  const writer = queue.writable.getWriter();
103
137
  this.address = await this.adb.reverse.add(
104
- 'localabstract:scrcpy',
105
- 'tcp:27183',
106
- socket => {
107
- writer.write(socket);
138
+ "localabstract:scrcpy",
139
+ "tcp:27183",
140
+ (socket) => {
141
+ void writer.write(socket);
108
142
  return true;
109
- },
143
+ }
110
144
  );
111
145
  }
112
146
 
113
- private async accept(): Promise<ReadableWritablePair<Uint8Array, Uint8Array>> {
147
+ private async accept(): Promise<
148
+ ReadableWritablePair<Uint8Array, Uint8Array>
149
+ > {
114
150
  return (await this.streams.read()).value!;
115
151
  }
116
152
 
117
- public async getStreams(): Promise<[videoSteam: ReadableStream<Uint8Array>, controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined]> {
153
+ public async getStreams(): Promise<
154
+ [
155
+ videoSteam: ReadableStream<Uint8Array>,
156
+ controlStream:
157
+ | ReadableWritablePair<Uint8Array, Uint8Array>
158
+ | undefined
159
+ ]
160
+ > {
118
161
  const { readable: videoStream } = await this.accept();
119
162
 
120
- let controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined;
163
+ let controlStream:
164
+ | ReadableWritablePair<Uint8Array, Uint8Array>
165
+ | undefined;
121
166
  if (this.options.control) {
122
167
  controlStream = await this.accept();
123
168
  }
@@ -128,7 +173,7 @@ export class AdbScrcpyReverseConnection extends AdbScrcpyConnection {
128
173
  const { done, value } = await reader.read();
129
174
  // 64 bytes device name + 2 bytes video width + 2 bytes video height
130
175
  if (done || value.byteLength !== 64 + 2 + 2) {
131
- throw new Error('Unexpected response from server');
176
+ throw new Error("Unexpected response from server");
132
177
  }
133
178
  reader.releaseLock();
134
179
  }
@@ -140,6 +185,8 @@ export class AdbScrcpyReverseConnection extends AdbScrcpyConnection {
140
185
  // Don't await this!
141
186
  // `reverse.remove`'s response will never arrive
142
187
  // before we read all pending data from `videoStream`
143
- this.adb.reverse.remove(this.address);
188
+ this.adb.reverse.remove(this.address).catch((e) => {
189
+ void e;
190
+ });
144
191
  }
145
192
  }
@@ -1,11 +1,18 @@
1
- import type { Adb } from '@yume-chan/adb';
1
+ import { type Adb } from "@yume-chan/adb";
2
2
 
3
- import type { ScrcpyOptionsInit1_16 } from '../../options/index.js';
4
- import { AdbScrcpyConnection, AdbScrcpyConnectionOptions, AdbScrcpyForwardConnection, AdbScrcpyReverseConnection } from '../connection.js';
5
- import { AdbScrcpyOptionsBase } from './types.js';
3
+ import { type ScrcpyOptionsInit1_16 } from "../../options/index.js";
4
+ import {
5
+ AdbScrcpyForwardConnection,
6
+ AdbScrcpyReverseConnection,
7
+ type AdbScrcpyConnection,
8
+ type AdbScrcpyConnectionOptions,
9
+ } from "../connection.js";
6
10
 
7
- export class AdbScrcpyOptions1_16<T extends ScrcpyOptionsInit1_16 = ScrcpyOptionsInit1_16>
8
- extends AdbScrcpyOptionsBase<T> {
11
+ import { AdbScrcpyOptionsBase } from "./types.js";
12
+
13
+ export class AdbScrcpyOptions1_16<
14
+ T extends ScrcpyOptionsInit1_16 = ScrcpyOptionsInit1_16
15
+ > extends AdbScrcpyOptionsBase<T> {
9
16
  public override createConnection(adb: Adb): AdbScrcpyConnection {
10
17
  const options: AdbScrcpyConnectionOptions = {
11
18
  // Old versions always have control stream no matter what the option is
@@ -1,11 +1,17 @@
1
- import type { Adb } from '@yume-chan/adb';
1
+ import { type Adb } from "@yume-chan/adb";
2
2
 
3
- import type { ScrcpyOptionsInit1_22 } from '../../options/index.js';
4
- import { AdbScrcpyConnection, AdbScrcpyForwardConnection, AdbScrcpyReverseConnection } from '../connection.js';
5
- import { AdbScrcpyOptions1_16 } from './1_16.js';
3
+ import { type ScrcpyOptionsInit1_22 } from "../../options/index.js";
4
+ import {
5
+ type AdbScrcpyConnection,
6
+ AdbScrcpyForwardConnection,
7
+ AdbScrcpyReverseConnection,
8
+ } from "../connection.js";
6
9
 
7
- export class AdbScrcpyOptions1_22<T extends ScrcpyOptionsInit1_22 = ScrcpyOptionsInit1_22>
8
- extends AdbScrcpyOptions1_16<T> {
10
+ import { AdbScrcpyOptions1_16 } from "./1_16.js";
11
+
12
+ export class AdbScrcpyOptions1_22<
13
+ T extends ScrcpyOptionsInit1_22 = ScrcpyOptionsInit1_22
14
+ > extends AdbScrcpyOptions1_16<T> {
9
15
  public override createConnection(adb: Adb): AdbScrcpyConnection {
10
16
  const options = {
11
17
  ...this.getDefaultValue(),
@@ -1,19 +1,32 @@
1
- import type { Adb } from '@yume-chan/adb';
2
- import type { TransformStream } from '@yume-chan/stream-extra';
1
+ import { type Adb } from "@yume-chan/adb";
2
+ import { type TransformStream } from "@yume-chan/stream-extra";
3
3
 
4
- import type { ScrcpyControlMessageType } from '../../control/index.js';
5
- import type { ScrcpyBackOrScreenOnControlMessage1_18, ScrcpyInjectScrollControlMessage1_22, ScrcpyOptions, ScrcpyVideoStreamPacket } from '../../options/index.js';
6
- import type { AdbScrcpyConnection } from '../connection.js';
4
+ import {
5
+ type ScrcpyBackOrScreenOnControlMessage,
6
+ type ScrcpyControlMessageType,
7
+ type ScrcpySetClipboardControlMessage,
8
+ } from "../../control/index.js";
9
+ import {
10
+ type ScrcpyOptions,
11
+ type ScrcpyVideoStreamPacket,
12
+ } from "../../options/index.js";
13
+ import { type AdbScrcpyConnection } from "../connection.js";
7
14
 
8
- export interface AdbScrcpyOptions<T> extends ScrcpyOptions<T> {
15
+ export interface AdbScrcpyOptions<T extends object> extends ScrcpyOptions<T> {
9
16
  createConnection(adb: Adb): AdbScrcpyConnection;
10
17
  }
11
18
 
12
- export abstract class AdbScrcpyOptionsBase<T> implements ScrcpyOptions<T> {
19
+ export abstract class AdbScrcpyOptionsBase<T extends object>
20
+ implements ScrcpyOptions<T>
21
+ {
13
22
  private raw: ScrcpyOptions<T>;
14
23
 
15
- public get value(): Partial<T> { return this.raw.value; }
16
- public set value(value: Partial<T>) { this.raw.value = value; }
24
+ public get value(): Partial<T> {
25
+ return this.raw.value;
26
+ }
27
+ public set value(value: Partial<T>) {
28
+ this.raw.value = value;
29
+ }
17
30
 
18
31
  public constructor(raw: ScrcpyOptions<T>) {
19
32
  this.raw = raw;
@@ -31,7 +44,10 @@ export abstract class AdbScrcpyOptionsBase<T> implements ScrcpyOptions<T> {
31
44
  return this.raw.getOutputEncoderNameRegex();
32
45
  }
33
46
 
34
- public createVideoStreamTransformer(): TransformStream<Uint8Array, ScrcpyVideoStreamPacket> {
47
+ public createVideoStreamTransformer(): TransformStream<
48
+ Uint8Array,
49
+ ScrcpyVideoStreamPacket
50
+ > {
35
51
  return this.raw.createVideoStreamTransformer();
36
52
  }
37
53
 
@@ -40,15 +56,19 @@ export abstract class AdbScrcpyOptionsBase<T> implements ScrcpyOptions<T> {
40
56
  }
41
57
 
42
58
  public serializeBackOrScreenOnControlMessage(
43
- message: ScrcpyBackOrScreenOnControlMessage1_18,
59
+ message: ScrcpyBackOrScreenOnControlMessage
44
60
  ): Uint8Array | undefined {
45
61
  return this.raw.serializeBackOrScreenOnControlMessage(message);
46
62
  }
47
63
 
48
- public serializeInjectScrollControlMessage(
49
- message: ScrcpyInjectScrollControlMessage1_22,
64
+ public serializeSetClipboardControlMessage(
65
+ message: ScrcpySetClipboardControlMessage
50
66
  ): Uint8Array {
51
- return this.raw.serializeInjectScrollControlMessage(message);
67
+ return this.raw.serializeSetClipboardControlMessage(message);
68
+ }
69
+
70
+ public getScrollController() {
71
+ return this.raw.getScrollController();
52
72
  }
53
73
 
54
74
  public abstract createConnection(adb: Adb): AdbScrcpyConnection;