@yume-chan/scrcpy 0.0.19 → 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 (252) hide show
  1. package/CHANGELOG.json +15 -0
  2. package/CHANGELOG.md +9 -1
  3. package/README.md +105 -181
  4. package/esm/codec/h264.d.ts +1 -21
  5. package/esm/codec/h264.d.ts.map +1 -1
  6. package/esm/codec/h264.js +13 -234
  7. package/esm/codec/h264.js.map +1 -1
  8. package/esm/codec/h265.d.ts +454 -0
  9. package/esm/codec/h265.d.ts.map +1 -1
  10. package/esm/codec/h265.js +1060 -0
  11. package/esm/codec/h265.js.map +1 -1
  12. package/esm/codec/index.d.ts +1 -0
  13. package/esm/codec/index.d.ts.map +1 -1
  14. package/esm/codec/index.js +1 -0
  15. package/esm/codec/index.js.map +1 -1
  16. package/esm/codec/nalu.d.ts +44 -0
  17. package/esm/codec/nalu.d.ts.map +1 -0
  18. package/esm/codec/nalu.js +310 -0
  19. package/esm/codec/nalu.js.map +1 -0
  20. package/esm/control/back-or-screen-on.d.ts +1 -1
  21. package/esm/control/back-or-screen-on.d.ts.map +1 -1
  22. package/esm/control/index.d.ts +2 -0
  23. package/esm/control/index.d.ts.map +1 -1
  24. package/esm/control/index.js +2 -0
  25. package/esm/control/index.js.map +1 -1
  26. package/esm/control/inject-keycode.d.ts +1 -2
  27. package/esm/control/inject-keycode.d.ts.map +1 -1
  28. package/esm/control/inject-keycode.js +1 -2
  29. package/esm/control/inject-keycode.js.map +1 -1
  30. package/esm/control/inject-text.d.ts +1 -2
  31. package/esm/control/inject-text.d.ts.map +1 -1
  32. package/esm/control/inject-text.js +1 -2
  33. package/esm/control/inject-text.js.map +1 -1
  34. package/esm/control/inject-touch.d.ts +15 -20
  35. package/esm/control/inject-touch.d.ts.map +1 -1
  36. package/esm/control/inject-touch.js +14 -41
  37. package/esm/control/inject-touch.js.map +1 -1
  38. package/esm/control/rotate-device.d.ts +2 -4
  39. package/esm/control/rotate-device.d.ts.map +1 -1
  40. package/esm/control/rotate-device.js +2 -3
  41. package/esm/control/rotate-device.js.map +1 -1
  42. package/esm/control/serializer.d.ts +13 -23
  43. package/esm/control/serializer.d.ts.map +1 -1
  44. package/esm/control/serializer.js +23 -52
  45. package/esm/control/serializer.js.map +1 -1
  46. package/esm/control/set-screen-power-mode.d.ts +1 -2
  47. package/esm/control/set-screen-power-mode.d.ts.map +1 -1
  48. package/esm/control/set-screen-power-mode.js +1 -2
  49. package/esm/control/set-screen-power-mode.js.map +1 -1
  50. package/esm/control/type.d.ts +14 -0
  51. package/esm/control/type.d.ts.map +1 -1
  52. package/esm/control/type.js +22 -0
  53. package/esm/control/type.js.map +1 -1
  54. package/esm/control/writer.d.ts +28 -0
  55. package/esm/control/writer.d.ts.map +1 -0
  56. package/esm/control/writer.js +53 -0
  57. package/esm/control/writer.js.map +1 -0
  58. package/esm/device-message/stream.d.ts.map +1 -1
  59. package/esm/device-message/stream.js +23 -8
  60. package/esm/device-message/stream.js.map +1 -1
  61. package/esm/index.d.ts +1 -2
  62. package/esm/index.d.ts.map +1 -1
  63. package/esm/index.js +1 -2
  64. package/esm/index.js.map +1 -1
  65. package/esm/options/1_16/codec-options.d.ts +2 -3
  66. package/esm/options/1_16/codec-options.d.ts.map +1 -1
  67. package/esm/options/1_16/codec-options.js.map +1 -1
  68. package/esm/options/1_16/index.d.ts +3 -1
  69. package/esm/options/1_16/index.d.ts.map +1 -1
  70. package/esm/options/1_16/index.js +3 -1
  71. package/esm/options/1_16/index.js.map +1 -1
  72. package/esm/options/1_16/options.d.ts +42 -96
  73. package/esm/options/1_16/options.d.ts.map +1 -1
  74. package/esm/options/1_16/options.js +106 -143
  75. package/esm/options/1_16/options.js.map +1 -1
  76. package/esm/options/1_16/scroll.d.ts +1 -2
  77. package/esm/options/1_16/scroll.d.ts.map +1 -1
  78. package/esm/options/1_16/scroll.js +1 -2
  79. package/esm/options/1_16/scroll.js.map +1 -1
  80. package/esm/options/1_17.d.ts +1 -0
  81. package/esm/options/1_17.d.ts.map +1 -1
  82. package/esm/options/1_17.js +7 -1
  83. package/esm/options/1_17.js.map +1 -1
  84. package/esm/options/1_18.d.ts +49 -11
  85. package/esm/options/1_18.d.ts.map +1 -1
  86. package/esm/options/1_18.js +65 -32
  87. package/esm/options/1_18.js.map +1 -1
  88. package/esm/options/1_21.d.ts +26 -7
  89. package/esm/options/1_21.d.ts.map +1 -1
  90. package/esm/options/1_21.js +35 -20
  91. package/esm/options/1_21.js.map +1 -1
  92. package/esm/options/1_22/index.d.ts +1 -0
  93. package/esm/options/1_22/index.d.ts.map +1 -1
  94. package/esm/options/1_22/index.js +1 -0
  95. package/esm/options/1_22/index.js.map +1 -1
  96. package/esm/options/1_22/options.d.ts +32 -26
  97. package/esm/options/1_22/options.d.ts.map +1 -1
  98. package/esm/options/1_22/options.js +27 -16
  99. package/esm/options/1_22/options.js.map +1 -1
  100. package/esm/options/1_22/scroll.d.ts +1 -1
  101. package/esm/options/1_22/scroll.js +1 -1
  102. package/esm/options/1_23.d.ts +32 -8
  103. package/esm/options/1_23.d.ts.map +1 -1
  104. package/esm/options/1_23.js +24 -14
  105. package/esm/options/1_23.js.map +1 -1
  106. package/esm/options/1_24.d.ts +29 -4
  107. package/esm/options/1_24.d.ts.map +1 -1
  108. package/esm/options/1_24.js +17 -7
  109. package/esm/options/1_24.js.map +1 -1
  110. package/esm/options/1_25/options.d.ts +6 -2
  111. package/esm/options/1_25/options.d.ts.map +1 -1
  112. package/esm/options/1_25/options.js +16 -2
  113. package/esm/options/1_25/options.js.map +1 -1
  114. package/esm/options/1_25/scroll.d.ts.map +1 -1
  115. package/esm/options/1_25/scroll.js +2 -1
  116. package/esm/options/1_25/scroll.js.map +1 -1
  117. package/esm/options/2_0.d.ts +12 -8
  118. package/esm/options/2_0.d.ts.map +1 -1
  119. package/esm/options/2_0.js +80 -11
  120. package/esm/options/2_0.js.map +1 -1
  121. package/esm/options/codec.d.ts +4 -4
  122. package/esm/options/codec.d.ts.map +1 -1
  123. package/esm/options/codec.js +3 -3
  124. package/esm/options/codec.js.map +1 -1
  125. package/esm/options/index.d.ts +4 -0
  126. package/esm/options/index.d.ts.map +1 -1
  127. package/esm/options/index.js +4 -0
  128. package/esm/options/index.js.map +1 -1
  129. package/esm/options/types.d.ts +73 -33
  130. package/esm/options/types.d.ts.map +1 -1
  131. package/esm/options/types.js +52 -0
  132. package/esm/options/types.js.map +1 -1
  133. package/package.json +7 -14
  134. package/src/codec/av1.ts +33 -0
  135. package/src/codec/h264.ts +317 -0
  136. package/src/codec/h265.ts +1375 -0
  137. package/src/codec/index.ts +4 -0
  138. package/src/codec/nalu.ts +373 -0
  139. package/src/control/back-or-screen-on.ts +1 -1
  140. package/{esm/control/simple.js → src/control/basic.ts} +3 -3
  141. package/src/control/index.ts +2 -0
  142. package/src/control/inject-keycode.ts +1 -3
  143. package/src/control/inject-text.ts +1 -3
  144. package/src/control/inject-touch.ts +16 -55
  145. package/src/control/rotate-device.ts +2 -7
  146. package/src/control/serializer.ts +42 -101
  147. package/src/control/set-screen-power-mode.ts +1 -3
  148. package/src/control/type.ts +32 -0
  149. package/src/control/writer.ts +87 -0
  150. package/src/device-message/stream.ts +32 -12
  151. package/src/index.ts +1 -2
  152. package/src/options/1_16/codec-options.ts +2 -3
  153. package/src/options/1_16/float-to-uint16.ts +33 -0
  154. package/src/options/1_16/index.ts +3 -1
  155. package/src/options/1_16/init.ts +80 -0
  156. package/src/options/1_16/message.ts +55 -0
  157. package/src/options/1_16/options.ts +146 -255
  158. package/src/options/1_16/scroll.ts +1 -2
  159. package/src/options/1_17.ts +66 -0
  160. package/src/options/1_18.ts +101 -37
  161. package/src/options/1_21.ts +47 -25
  162. package/src/options/1_22/index.ts +1 -0
  163. package/src/options/1_22/init.ts +19 -0
  164. package/src/options/1_22/options.ts +38 -45
  165. package/src/options/1_22/scroll.ts +1 -1
  166. package/src/options/1_23.ts +33 -21
  167. package/src/options/1_24.ts +23 -11
  168. package/src/options/1_25/options.ts +22 -4
  169. package/src/options/1_25/scroll.ts +2 -1
  170. package/src/options/2_0.ts +342 -0
  171. package/src/options/codec.ts +98 -0
  172. package/src/options/index.ts +4 -0
  173. package/src/options/latest.ts +14 -0
  174. package/src/options/types.ts +152 -42
  175. package/tsconfig.build.json +9 -1
  176. package/tsconfig.build.tsbuildinfo +1 -1
  177. package/esm/adb/client.d.ts +0 -41
  178. package/esm/adb/client.d.ts.map +0 -1
  179. package/esm/adb/client.js +0 -224
  180. package/esm/adb/client.js.map +0 -1
  181. package/esm/adb/connection.d.ts +0 -49
  182. package/esm/adb/connection.d.ts.map +0 -1
  183. package/esm/adb/connection.js +0 -122
  184. package/esm/adb/connection.js.map +0 -1
  185. package/esm/adb/index.d.ts +0 -4
  186. package/esm/adb/index.d.ts.map +0 -1
  187. package/esm/adb/index.js +0 -4
  188. package/esm/adb/index.js.map +0 -1
  189. package/esm/adb/options/1_16.d.ts +0 -8
  190. package/esm/adb/options/1_16.d.ts.map +0 -1
  191. package/esm/adb/options/1_16.js +0 -20
  192. package/esm/adb/options/1_16.js.map +0 -1
  193. package/esm/adb/options/1_22.d.ts +0 -8
  194. package/esm/adb/options/1_22.d.ts.map +0 -1
  195. package/esm/adb/options/1_22.js +0 -17
  196. package/esm/adb/options/1_22.js.map +0 -1
  197. package/esm/adb/options/1_26.d.ts +0 -9
  198. package/esm/adb/options/1_26.d.ts.map +0 -1
  199. package/esm/adb/options/1_26.js +0 -11
  200. package/esm/adb/options/1_26.js.map +0 -1
  201. package/esm/adb/options/2_0.d.ts +0 -8
  202. package/esm/adb/options/2_0.d.ts.map +0 -1
  203. package/esm/adb/options/2_0.js +0 -13
  204. package/esm/adb/options/2_0.js.map +0 -1
  205. package/esm/adb/options/index.d.ts +0 -4
  206. package/esm/adb/options/index.d.ts.map +0 -1
  207. package/esm/adb/options/index.js +0 -4
  208. package/esm/adb/options/index.js.map +0 -1
  209. package/esm/adb/options/types.d.ts +0 -24
  210. package/esm/adb/options/types.d.ts.map +0 -1
  211. package/esm/adb/options/types.js +0 -37
  212. package/esm/adb/options/types.js.map +0 -1
  213. package/esm/codec.d.ts +0 -34
  214. package/esm/codec.d.ts.map +0 -1
  215. package/esm/codec.js +0 -37
  216. package/esm/codec.js.map +0 -1
  217. package/esm/control/simple.d.ts +0 -5
  218. package/esm/control/simple.d.ts.map +0 -1
  219. package/esm/control/simple.js.map +0 -1
  220. package/esm/decoder.d.ts +0 -2
  221. package/esm/decoder.d.ts.map +0 -1
  222. package/esm/decoder.js +0 -2
  223. package/esm/decoder.js.map +0 -1
  224. package/esm/options/1.17.d.ts +0 -3
  225. package/esm/options/1.17.d.ts.map +0 -1
  226. package/esm/options/1.17.js +0 -2
  227. package/esm/options/1.17.js.map +0 -1
  228. package/esm/options/1_16/h264-configuration.d.ts +0 -49
  229. package/esm/options/1_16/h264-configuration.d.ts.map +0 -1
  230. package/esm/options/1_16/h264-configuration.js +0 -414
  231. package/esm/options/1_16/h264-configuration.js.map +0 -1
  232. package/esm/options/1_16/sps.d.ts +0 -22
  233. package/esm/options/1_16/sps.d.ts.map +0 -1
  234. package/esm/options/1_16/sps.js +0 -263
  235. package/esm/options/1_16/sps.js.map +0 -1
  236. package/esm/options/1_26.d.ts +0 -57
  237. package/esm/options/1_26.d.ts.map +0 -1
  238. package/esm/options/1_26.js +0 -67
  239. package/esm/options/1_26.js.map +0 -1
  240. package/esm/options/2.d.ts +0 -57
  241. package/esm/options/2.d.ts.map +0 -1
  242. package/esm/options/2.js +0 -67
  243. package/esm/options/2.js.map +0 -1
  244. package/src/adb/client.ts +0 -329
  245. package/src/adb/connection.ts +0 -209
  246. package/src/adb/index.ts +0 -3
  247. package/src/adb/options/1_16.ts +0 -32
  248. package/src/adb/options/1_22.ts +0 -26
  249. package/src/adb/options/index.ts +0 -3
  250. package/src/adb/options/types.ts +0 -75
  251. package/src/codec.ts +0 -35
  252. package/src/options/1_16/h264-configuration.ts +0 -485
@@ -0,0 +1,4 @@
1
+ export * from "./av1.js";
2
+ export * from "./h264.js";
3
+ export * from "./h265.js";
4
+ export * from "./nalu.js";
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Split NAL units from an H.264/H.265 Annex B stream.
3
+ *
4
+ * The input is not modified.
5
+ * The returned NAL units are views of the input (no memory allocation nor copy),
6
+ * and still contains emulation prevention bytes.
7
+ *
8
+ * This methods returns a generator, so it can be stopped immediately
9
+ * after the interested NAL unit is found.
10
+ */
11
+ export function* annexBSplitNalu(buffer: Uint8Array): Generator<Uint8Array> {
12
+ // -1 means we haven't found the first start code
13
+ let start = -1;
14
+ // How many `0x00`s in a row we have counted
15
+ let zeroCount = 0;
16
+ let inEmulation = false;
17
+
18
+ for (let i = 0; i < buffer.length; i += 1) {
19
+ const byte = buffer[i]!;
20
+
21
+ if (inEmulation) {
22
+ if (byte > 0x03) {
23
+ // `0x00000304` or larger are invalid
24
+ throw new Error("Invalid data");
25
+ }
26
+
27
+ inEmulation = false;
28
+ continue;
29
+ }
30
+
31
+ if (byte === 0x00) {
32
+ zeroCount += 1;
33
+ continue;
34
+ }
35
+
36
+ const prevZeroCount = zeroCount;
37
+ zeroCount = 0;
38
+
39
+ if (start === -1) {
40
+ // 0x000001 is the start code
41
+ // But it can be preceded by any number of zeros
42
+ // So 2 is the minimal
43
+ if (prevZeroCount >= 2 && byte === 0x01) {
44
+ // Found start of first NAL unit
45
+ start = i + 1;
46
+ continue;
47
+ }
48
+
49
+ // Not begin with start code
50
+ throw new Error("Invalid data");
51
+ }
52
+
53
+ if (prevZeroCount < 2) {
54
+ // zero or one `0x00`s are acceptable
55
+ continue;
56
+ }
57
+
58
+ if (byte === 0x01) {
59
+ // Found another NAL unit
60
+ yield buffer.subarray(start, i - prevZeroCount);
61
+
62
+ start = i + 1;
63
+ continue;
64
+ }
65
+
66
+ if (prevZeroCount > 2) {
67
+ // Too much `0x00`s
68
+ throw new Error("Invalid data");
69
+ }
70
+
71
+ switch (byte) {
72
+ case 0x02:
73
+ // Didn't find why, but 7.4.1 NAL unit semantics forbids `0x000002` appearing in NAL units
74
+ throw new Error("Invalid data");
75
+ case 0x03:
76
+ // `0x000003` is the "emulation_prevention_three_byte"
77
+ // `0x00000300`, `0x00000301`, `0x00000302` and `0x00000303` represent
78
+ // `0x000000`, `0x000001`, `0x000002` and `0x000003` respectively
79
+ inEmulation = true;
80
+ break;
81
+ default:
82
+ // `0x000004` or larger are as-is
83
+ break;
84
+ }
85
+ }
86
+
87
+ if (inEmulation) {
88
+ throw new Error("Invalid data");
89
+ }
90
+
91
+ yield buffer.subarray(start, buffer.length);
92
+ }
93
+
94
+ /**
95
+ * Remove emulation prevention bytes from a H.264/H.265 NAL Unit.
96
+ *
97
+ * The input is not modified.
98
+ * If the input doesn't contain any emulation prevention bytes,
99
+ * the input is returned as-is.
100
+ * Otherwise, a new `Uint8Array` is created and returned.
101
+ */
102
+ export function naluRemoveEmulation(buffer: Uint8Array) {
103
+ // output will be created when first emulation prevention byte is found
104
+ let output: Uint8Array | undefined;
105
+ let outputOffset = 0;
106
+
107
+ let zeroCount = 0;
108
+ let inEmulation = false;
109
+
110
+ let i = 0;
111
+ scan: for (; i < buffer.length; i += 1) {
112
+ const byte = buffer[i]!;
113
+
114
+ if (byte === 0x00) {
115
+ zeroCount += 1;
116
+ continue;
117
+ }
118
+
119
+ // Current byte is not zero
120
+ const prevZeroCount = zeroCount;
121
+ zeroCount = 0;
122
+
123
+ if (prevZeroCount < 2) {
124
+ // zero or one `0x00`s are acceptable
125
+ continue;
126
+ }
127
+
128
+ if (byte === 0x01) {
129
+ // Unexpected start code
130
+ throw new Error("Invalid data");
131
+ }
132
+
133
+ if (prevZeroCount > 2) {
134
+ // Too much `0x00`s
135
+ throw new Error("Invalid data");
136
+ }
137
+
138
+ switch (byte) {
139
+ case 0x02:
140
+ // Didn't find why, but 7.4.1 NAL unit semantics forbids `0x000002` appearing in NAL units
141
+ throw new Error("Invalid data");
142
+ case 0x03:
143
+ // `0x000003` is the "emulation_prevention_three_byte"
144
+ // `0x00000300`, `0x00000301`, `0x00000302` and `0x00000303` represent
145
+ // `0x000000`, `0x000001`, `0x000002` and `0x000003` respectively
146
+ inEmulation = true;
147
+
148
+ // Create output and copy the data before the emulation prevention byte
149
+ // Output size is unknown, so we use the input size as an upper bound
150
+ output = new Uint8Array(buffer.length - 1);
151
+ output.set(buffer.subarray(0, i));
152
+ outputOffset = i;
153
+ i += 1;
154
+ break scan;
155
+ default:
156
+ // `0x000004` or larger are as-is
157
+ break;
158
+ }
159
+ }
160
+
161
+ if (!output) {
162
+ return buffer;
163
+ }
164
+
165
+ // Continue at the byte after the emulation prevention byte
166
+ for (; i < buffer.length; i += 1) {
167
+ const byte = buffer[i]!;
168
+
169
+ output[outputOffset] = byte;
170
+ outputOffset += 1;
171
+
172
+ if (inEmulation) {
173
+ if (byte > 0x03) {
174
+ // `0x00000304` or larger are invalid
175
+ throw new Error("Invalid data");
176
+ }
177
+
178
+ // `00000300000300` results in `0000000000` (both `0x03` are removed)
179
+ // which means the `0x00` after `0x03` also counts
180
+ if (byte === 0x00) {
181
+ zeroCount += 1;
182
+ }
183
+
184
+ inEmulation = false;
185
+ continue;
186
+ }
187
+
188
+ if (byte === 0x00) {
189
+ zeroCount += 1;
190
+ continue;
191
+ }
192
+
193
+ const prevZeroCount = zeroCount;
194
+ zeroCount = 0;
195
+
196
+ if (prevZeroCount < 2) {
197
+ // zero or one `0x00`s are acceptable
198
+ continue;
199
+ }
200
+
201
+ if (byte === 0x01) {
202
+ // Unexpected start code
203
+ throw new Error("Invalid data");
204
+ }
205
+
206
+ if (prevZeroCount > 2) {
207
+ // Too much `0x00`s
208
+ throw new Error("Invalid data");
209
+ }
210
+
211
+ switch (byte) {
212
+ case 0x02:
213
+ // Didn't find why, but 7.4.1 NAL unit semantics forbids `0x000002` appearing in NAL units
214
+ throw new Error("Invalid data");
215
+ case 0x03:
216
+ // `0x000003` is the "emulation_prevention_three_byte"
217
+ // `0x00000300`, `0x00000301`, `0x00000302` and `0x00000303` represent
218
+ // `0x000000`, `0x000001`, `0x000002` and `0x000003` respectively
219
+ inEmulation = true;
220
+
221
+ // Remove the emulation prevention byte
222
+ outputOffset -= 1;
223
+ break;
224
+ default:
225
+ // `0x000004` or larger are as-is
226
+ break;
227
+ }
228
+ }
229
+
230
+ return output.subarray(0, outputOffset);
231
+ }
232
+
233
+ export class NaluSodbBitReader {
234
+ private readonly _nalu: Uint8Array;
235
+ private readonly _byteLength: number;
236
+ private readonly _stopBitIndex: number;
237
+
238
+ private _zeroCount = 0;
239
+ private _bytePosition = -1;
240
+ private _bitPosition = -1;
241
+ private _byte = 0;
242
+
243
+ public get byteLength() {
244
+ return this._byteLength;
245
+ }
246
+
247
+ public get stopBitIndex() {
248
+ return this._stopBitIndex;
249
+ }
250
+
251
+ public get bytePosition() {
252
+ return this._bytePosition;
253
+ }
254
+
255
+ public get bitPosition() {
256
+ return this._bitPosition;
257
+ }
258
+
259
+ public get ended() {
260
+ return (
261
+ this._bytePosition === this._byteLength &&
262
+ this._bitPosition === this._stopBitIndex
263
+ );
264
+ }
265
+
266
+ public constructor(nalu: Uint8Array) {
267
+ this._nalu = nalu;
268
+
269
+ for (let i = nalu.length - 1; i >= 0; i -= 1) {
270
+ if (this._nalu[i] === 0) {
271
+ continue;
272
+ }
273
+
274
+ const byte = nalu[i]!;
275
+ for (let j = 0; j < 8; j += 1) {
276
+ if (((byte >> j) & 1) === 1) {
277
+ this._byteLength = i;
278
+ this._stopBitIndex = j;
279
+ this.readByte();
280
+ return;
281
+ }
282
+ }
283
+ }
284
+
285
+ throw new Error("End bit not found");
286
+ }
287
+
288
+ private readByte() {
289
+ this._byte = this._nalu[this._bytePosition]!;
290
+ if (this._zeroCount === 2 && this._byte === 3) {
291
+ this._zeroCount = 0;
292
+ this._bytePosition += 1;
293
+ this.readByte();
294
+ return;
295
+ }
296
+
297
+ if (this._byte === 0) {
298
+ this._zeroCount += 1;
299
+ } else {
300
+ this._zeroCount = 0;
301
+ }
302
+ }
303
+
304
+ public next() {
305
+ if (this._bitPosition === -1) {
306
+ this._bitPosition = 7;
307
+ this._bytePosition += 1;
308
+ this.readByte();
309
+ }
310
+
311
+ if (
312
+ this._bytePosition === this._byteLength &&
313
+ this._bitPosition === this._stopBitIndex
314
+ ) {
315
+ throw new Error("Bit index out of bounds");
316
+ }
317
+
318
+ const value = (this._byte >> this._bitPosition) & 1;
319
+ this._bitPosition -= 1;
320
+ return value;
321
+ }
322
+
323
+ public read(length: number): number {
324
+ if (length > 32) {
325
+ throw new Error("Read length too large");
326
+ }
327
+
328
+ let result = 0;
329
+ for (let i = 0; i < length; i += 1) {
330
+ result = (result << 1) | this.next();
331
+ }
332
+ return result;
333
+ }
334
+
335
+ public skip(length: number) {
336
+ for (let i = 0; i < length; i += 1) {
337
+ this.next();
338
+ }
339
+ }
340
+
341
+ public decodeExponentialGolombNumber(): number {
342
+ let length = 0;
343
+ while (this.next() === 0) {
344
+ length += 1;
345
+ }
346
+ if (length === 0) {
347
+ return 0;
348
+ }
349
+ return ((1 << length) | this.read(length)) - 1;
350
+ }
351
+
352
+ public peek(length: number) {
353
+ const { _zeroCount, _bytePosition, _bitPosition, _byte } = this;
354
+ const result = this.read(length);
355
+ Object.assign(this, { _zeroCount, _bytePosition, _bitPosition, _byte });
356
+ return result;
357
+ }
358
+
359
+ public readBytes(length: number): Uint8Array {
360
+ const result = new Uint8Array(length);
361
+ for (let i = 0; i < length; i += 1) {
362
+ result[i] = this.read(8);
363
+ }
364
+ return result;
365
+ }
366
+
367
+ public peekBytes(length: number): Uint8Array {
368
+ const { _zeroCount, _bytePosition, _bitPosition, _byte } = this;
369
+ const result = this.readBytes(length);
370
+ Object.assign(this, { _zeroCount, _bytePosition, _bitPosition, _byte });
371
+ return result;
372
+ }
373
+ }
@@ -1,4 +1,4 @@
1
- import type { ScrcpyBackOrScreenOnControlMessage1_18 } from "../index.js";
1
+ import type { ScrcpyBackOrScreenOnControlMessage1_18 } from "../options/index.js";
2
2
 
3
3
  export type ScrcpyBackOrScreenOnControlMessage =
4
4
  ScrcpyBackOrScreenOnControlMessage1_18;
@@ -1,3 +1,3 @@
1
- import { Struct } from "@yume-chan/struct";
2
- export const BasicControlMessage = new Struct().uint8("type");
3
- //# sourceMappingURL=simple.js.map
1
+ import { Struct } from "@yume-chan/struct";
2
+
3
+ export const BasicControlMessage = new Struct().uint8("type");
@@ -1,4 +1,5 @@
1
1
  export * from "./back-or-screen-on.js";
2
+ export * from "./basic.js";
2
3
  export * from "./hover-helper.js";
3
4
  export * from "./inject-keycode.js";
4
5
  export * from "./inject-scroll.js";
@@ -9,3 +10,4 @@ export * from "./serializer.js";
9
10
  export * from "./set-clipboard.js";
10
11
  export * from "./set-screen-power-mode.js";
11
12
  export * from "./type.js";
13
+ export * from "./writer.js";
@@ -1,7 +1,5 @@
1
1
  import Struct, { placeholder } from "@yume-chan/struct";
2
2
 
3
- import { ScrcpyControlMessageType } from "./type.js";
4
-
5
3
  export enum AndroidKeyEventAction {
6
4
  Down = 0,
7
5
  Up = 1,
@@ -207,7 +205,7 @@ export enum AndroidKeyCode {
207
205
  }
208
206
 
209
207
  export const ScrcpyInjectKeyCodeControlMessage = new Struct()
210
- .uint8("type", ScrcpyControlMessageType.InjectKeyCode as const)
208
+ .uint8("type")
211
209
  .uint8("action", placeholder<AndroidKeyEventAction>())
212
210
  .uint32("keyCode")
213
211
  .uint32("repeat")
@@ -1,9 +1,7 @@
1
1
  import Struct from "@yume-chan/struct";
2
2
 
3
- import { ScrcpyControlMessageType } from "./type.js";
4
-
5
3
  export const ScrcpyInjectTextControlMessage = new Struct()
6
- .uint8("type", ScrcpyControlMessageType.InjectText as const)
4
+ .uint8("type")
7
5
  .uint32("length")
8
6
  .string("text", { lengthField: "length" });
9
7
 
@@ -1,10 +1,4 @@
1
- import Struct, {
2
- NumberFieldDefinition,
3
- NumberFieldType,
4
- placeholder,
5
- } from "@yume-chan/struct";
6
-
7
- import { ScrcpyControlMessageType } from "./type.js";
1
+ import type { ScrcpyInjectTouchControlMessage2_0 } from "../options/index.js";
8
2
 
9
3
  // https://developer.android.com/reference/android/view/MotionEvent#constants_1
10
4
  export enum AndroidMotionEventAction {
@@ -23,56 +17,23 @@ export enum AndroidMotionEventAction {
23
17
  ButtonRelease,
24
18
  }
25
19
 
26
- // eslint-disable-next-line @typescript-eslint/no-namespace
27
- export namespace ScrcpyPointerId {
28
- export const Mouse = BigInt(-1);
29
- export const Finger = BigInt(-2);
30
- export const VirtualMouse = BigInt(-3);
31
- export const VirtualFinger = BigInt(-4);
20
+ export enum AndroidMotionEventButton {
21
+ Primary = 0x01,
22
+ Secondary = 0x02,
23
+ Tertiary = 0x04,
24
+ Back = 0x08,
25
+ Forward = 0x10,
26
+ StylusPrimary = 0x20,
27
+ StylusSecondary = 0x40,
32
28
  }
33
29
 
34
- export function clamp(value: number, min: number, max: number): number {
35
- if (value < min) {
36
- return min;
37
- }
38
-
39
- if (value > max) {
40
- return max;
41
- }
42
-
43
- return value;
30
+ // eslint-disable-next-line @typescript-eslint/no-namespace
31
+ export namespace ScrcpyPointerId {
32
+ export const Mouse = -1n;
33
+ export const Finger = -2n;
34
+ export const VirtualMouse = -3n;
35
+ export const VirtualFinger = -4n;
44
36
  }
45
37
 
46
- export const ScrcpyFloatToUint16NumberType: NumberFieldType = {
47
- size: 2,
48
- signed: false,
49
- deserialize(array, littleEndian) {
50
- const value = NumberFieldType.Uint16.deserialize(array, littleEndian);
51
- // https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/server/src/main/java/com/genymobile/scrcpy/Binary.java#L22
52
- return value === 0xffff ? 1 : value / 0x10000;
53
- },
54
- serialize(dataView, offset, value, littleEndian) {
55
- // https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/app/src/util/binary.h#L51
56
- value = clamp(value, -1, 1);
57
- value = value === 1 ? 0xffff : value * 0x10000;
58
- NumberFieldType.Uint16.serialize(dataView, offset, value, littleEndian);
59
- },
60
- };
61
-
62
- const ScrcpyFloatToUint16FieldDefinition = new NumberFieldDefinition(
63
- ScrcpyFloatToUint16NumberType
64
- );
65
-
66
- export const ScrcpyInjectTouchControlMessage = new Struct()
67
- .uint8("type", ScrcpyControlMessageType.InjectTouch as const)
68
- .uint8("action", placeholder<AndroidMotionEventAction>())
69
- .uint64("pointerId")
70
- .uint32("pointerX")
71
- .uint32("pointerY")
72
- .uint16("screenWidth")
73
- .uint16("screenHeight")
74
- .field("pressure", ScrcpyFloatToUint16FieldDefinition)
75
- .uint32("buttons");
76
-
77
38
  export type ScrcpyInjectTouchControlMessage =
78
- (typeof ScrcpyInjectTouchControlMessage)["TInit"];
39
+ ScrcpyInjectTouchControlMessage2_0;
@@ -1,11 +1,6 @@
1
- import Struct from "@yume-chan/struct";
1
+ import { BasicControlMessage } from "./basic.js";
2
2
 
3
- import { ScrcpyControlMessageType } from "./type.js";
4
-
5
- export const ScrcpyRotateDeviceControlMessage = new Struct().uint8(
6
- "type",
7
- ScrcpyControlMessageType.RotateDevice as const
8
- );
3
+ export const ScrcpyRotateDeviceControlMessage = BasicControlMessage;
9
4
 
10
5
  export type ScrcpyRotateDeviceControlMessage =
11
6
  (typeof ScrcpyRotateDeviceControlMessage)["TInit"];