@yume-chan/scrcpy 0.0.19 → 0.0.21

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 (278) hide show
  1. package/CHANGELOG.json +30 -0
  2. package/CHANGELOG.md +17 -1
  3. package/README.md +76 -266
  4. package/esm/codec/av1.js +2 -2
  5. package/esm/codec/av1.js.map +1 -1
  6. package/esm/codec/h264.d.ts +1 -21
  7. package/esm/codec/h264.d.ts.map +1 -1
  8. package/esm/codec/h264.js +15 -236
  9. package/esm/codec/h264.js.map +1 -1
  10. package/esm/codec/h265.d.ts +454 -0
  11. package/esm/codec/h265.d.ts.map +1 -1
  12. package/esm/codec/h265.js +1062 -2
  13. package/esm/codec/h265.js.map +1 -1
  14. package/esm/codec/index.d.ts +1 -0
  15. package/esm/codec/index.d.ts.map +1 -1
  16. package/esm/codec/index.js +1 -0
  17. package/esm/codec/index.js.map +1 -1
  18. package/esm/codec/nalu.d.ts +37 -0
  19. package/esm/codec/nalu.d.ts.map +1 -0
  20. package/esm/codec/nalu.js +323 -0
  21. package/esm/codec/nalu.js.map +1 -0
  22. package/esm/control/back-or-screen-on.d.ts +1 -1
  23. package/esm/control/back-or-screen-on.d.ts.map +1 -1
  24. package/esm/control/hover-helper.d.ts +1 -1
  25. package/esm/control/hover-helper.d.ts.map +1 -1
  26. package/esm/control/hover-helper.js +8 -9
  27. package/esm/control/hover-helper.js.map +1 -1
  28. package/esm/control/index.d.ts +2 -0
  29. package/esm/control/index.d.ts.map +1 -1
  30. package/esm/control/index.js +2 -0
  31. package/esm/control/index.js.map +1 -1
  32. package/esm/control/inject-keycode.d.ts +1 -2
  33. package/esm/control/inject-keycode.d.ts.map +1 -1
  34. package/esm/control/inject-keycode.js +4 -5
  35. package/esm/control/inject-keycode.js.map +1 -1
  36. package/esm/control/inject-text.d.ts +1 -2
  37. package/esm/control/inject-text.d.ts.map +1 -1
  38. package/esm/control/inject-text.js +1 -2
  39. package/esm/control/inject-text.js.map +1 -1
  40. package/esm/control/inject-touch.d.ts +15 -20
  41. package/esm/control/inject-touch.d.ts.map +1 -1
  42. package/esm/control/inject-touch.js +16 -43
  43. package/esm/control/inject-touch.js.map +1 -1
  44. package/esm/control/rotate-device.d.ts +2 -4
  45. package/esm/control/rotate-device.d.ts.map +1 -1
  46. package/esm/control/rotate-device.js +2 -3
  47. package/esm/control/rotate-device.js.map +1 -1
  48. package/esm/control/serializer.d.ts +11 -23
  49. package/esm/control/serializer.d.ts.map +1 -1
  50. package/esm/control/serializer.js +23 -52
  51. package/esm/control/serializer.js.map +1 -1
  52. package/esm/control/set-screen-power-mode.d.ts +1 -2
  53. package/esm/control/set-screen-power-mode.d.ts.map +1 -1
  54. package/esm/control/set-screen-power-mode.js +2 -3
  55. package/esm/control/set-screen-power-mode.js.map +1 -1
  56. package/esm/control/type.d.ts +14 -0
  57. package/esm/control/type.d.ts.map +1 -1
  58. package/esm/control/type.js +23 -1
  59. package/esm/control/type.js.map +1 -1
  60. package/esm/control/writer.d.ts +26 -0
  61. package/esm/control/writer.d.ts.map +1 -0
  62. package/esm/control/writer.js +53 -0
  63. package/esm/control/writer.js.map +1 -0
  64. package/esm/device-message/stream.d.ts.map +1 -1
  65. package/esm/device-message/stream.js +23 -8
  66. package/esm/device-message/stream.js.map +1 -1
  67. package/esm/device-message/type.js +1 -1
  68. package/esm/device-message/type.js.map +1 -1
  69. package/esm/index.d.ts +1 -2
  70. package/esm/index.d.ts.map +1 -1
  71. package/esm/index.js +1 -2
  72. package/esm/index.js.map +1 -1
  73. package/esm/options/1_16/codec-options.d.ts +2 -3
  74. package/esm/options/1_16/codec-options.d.ts.map +1 -1
  75. package/esm/options/1_16/codec-options.js.map +1 -1
  76. package/esm/options/1_16/index.d.ts +3 -1
  77. package/esm/options/1_16/index.d.ts.map +1 -1
  78. package/esm/options/1_16/index.js +3 -1
  79. package/esm/options/1_16/index.js.map +1 -1
  80. package/esm/options/1_16/init.js +2 -2
  81. package/esm/options/1_16/init.js.map +1 -1
  82. package/esm/options/1_16/options.d.ts +42 -96
  83. package/esm/options/1_16/options.d.ts.map +1 -1
  84. package/esm/options/1_16/options.js +104 -142
  85. package/esm/options/1_16/options.js.map +1 -1
  86. package/esm/options/1_16/scroll.d.ts +2 -4
  87. package/esm/options/1_16/scroll.d.ts.map +1 -1
  88. package/esm/options/1_16/scroll.js +13 -14
  89. package/esm/options/1_16/scroll.js.map +1 -1
  90. package/esm/options/1_17.d.ts +1 -0
  91. package/esm/options/1_17.d.ts.map +1 -1
  92. package/esm/options/1_17.js +8 -3
  93. package/esm/options/1_17.js.map +1 -1
  94. package/esm/options/1_18.d.ts +49 -11
  95. package/esm/options/1_18.d.ts.map +1 -1
  96. package/esm/options/1_18.js +64 -32
  97. package/esm/options/1_18.js.map +1 -1
  98. package/esm/options/1_21.d.ts +26 -7
  99. package/esm/options/1_21.d.ts.map +1 -1
  100. package/esm/options/1_21.js +34 -20
  101. package/esm/options/1_21.js.map +1 -1
  102. package/esm/options/1_22/index.d.ts +1 -0
  103. package/esm/options/1_22/index.d.ts.map +1 -1
  104. package/esm/options/1_22/index.js +1 -0
  105. package/esm/options/1_22/index.js.map +1 -1
  106. package/esm/options/1_22/options.d.ts +32 -26
  107. package/esm/options/1_22/options.d.ts.map +1 -1
  108. package/esm/options/1_22/options.js +26 -16
  109. package/esm/options/1_22/options.js.map +1 -1
  110. package/esm/options/1_22/scroll.d.ts +1 -1
  111. package/esm/options/1_22/scroll.d.ts.map +1 -1
  112. package/esm/options/1_22/scroll.js +1 -1
  113. package/esm/options/1_22/scroll.js.map +1 -1
  114. package/esm/options/1_23.d.ts +32 -8
  115. package/esm/options/1_23.d.ts.map +1 -1
  116. package/esm/options/1_23.js +23 -14
  117. package/esm/options/1_23.js.map +1 -1
  118. package/esm/options/1_24.d.ts +29 -4
  119. package/esm/options/1_24.d.ts.map +1 -1
  120. package/esm/options/1_24.js +16 -7
  121. package/esm/options/1_24.js.map +1 -1
  122. package/esm/options/1_25/options.d.ts +6 -2
  123. package/esm/options/1_25/options.d.ts.map +1 -1
  124. package/esm/options/1_25/options.js +16 -2
  125. package/esm/options/1_25/options.js.map +1 -1
  126. package/esm/options/1_25/scroll.d.ts.map +1 -1
  127. package/esm/options/1_25/scroll.js +2 -1
  128. package/esm/options/1_25/scroll.js.map +1 -1
  129. package/esm/options/2_0.d.ts +12 -8
  130. package/esm/options/2_0.d.ts.map +1 -1
  131. package/esm/options/2_0.js +82 -15
  132. package/esm/options/2_0.js.map +1 -1
  133. package/esm/options/2_1.d.ts +48 -0
  134. package/esm/options/2_1.d.ts.map +1 -0
  135. package/esm/options/2_1.js +23 -0
  136. package/esm/options/2_1.js.map +1 -0
  137. package/esm/options/codec.d.ts +4 -4
  138. package/esm/options/codec.d.ts.map +1 -1
  139. package/esm/options/codec.js +5 -6
  140. package/esm/options/codec.js.map +1 -1
  141. package/esm/options/index.d.ts +5 -0
  142. package/esm/options/index.d.ts.map +1 -1
  143. package/esm/options/index.js +5 -0
  144. package/esm/options/index.js.map +1 -1
  145. package/esm/options/latest.d.ts +4 -5
  146. package/esm/options/latest.d.ts.map +1 -1
  147. package/esm/options/latest.js +2 -3
  148. package/esm/options/latest.js.map +1 -1
  149. package/esm/options/types.d.ts +74 -33
  150. package/esm/options/types.d.ts.map +1 -1
  151. package/esm/options/types.js +62 -0
  152. package/esm/options/types.js.map +1 -1
  153. package/package.json +9 -19
  154. package/src/codec/av1.ts +33 -0
  155. package/src/codec/h264.ts +317 -0
  156. package/src/codec/h265.ts +1375 -0
  157. package/src/codec/index.ts +4 -0
  158. package/src/codec/nalu.ts +391 -0
  159. package/src/control/back-or-screen-on.ts +1 -1
  160. package/{esm/control/simple.js → src/control/basic.ts} +3 -3
  161. package/src/control/hover-helper.ts +10 -11
  162. package/src/control/index.ts +2 -0
  163. package/src/control/inject-keycode.ts +1 -3
  164. package/src/control/inject-text.ts +1 -3
  165. package/src/control/inject-touch.ts +16 -55
  166. package/src/control/rotate-device.ts +2 -7
  167. package/src/control/serializer.ts +50 -113
  168. package/src/control/set-screen-power-mode.ts +1 -3
  169. package/src/control/type.ts +32 -0
  170. package/src/control/writer.ts +85 -0
  171. package/src/device-message/stream.ts +32 -12
  172. package/src/index.ts +1 -2
  173. package/src/options/1_16/codec-options.ts +6 -7
  174. package/src/options/1_16/float-to-uint16.ts +33 -0
  175. package/src/options/1_16/index.ts +3 -1
  176. package/src/options/1_16/init.ts +80 -0
  177. package/src/options/1_16/message.ts +55 -0
  178. package/src/options/1_16/options.ts +147 -260
  179. package/src/options/1_16/scroll.ts +17 -18
  180. package/src/options/1_17.ts +66 -0
  181. package/src/options/1_18.ts +103 -39
  182. package/src/options/1_21.ts +49 -27
  183. package/src/options/1_22/index.ts +1 -0
  184. package/src/options/1_22/init.ts +19 -0
  185. package/src/options/1_22/options.ts +38 -45
  186. package/src/options/1_22/scroll.ts +3 -3
  187. package/src/options/1_23.ts +34 -22
  188. package/src/options/1_24.ts +23 -11
  189. package/src/options/1_25/options.ts +22 -4
  190. package/src/options/1_25/scroll.ts +4 -3
  191. package/src/options/2_0.ts +342 -0
  192. package/src/options/2_1.ts +35 -0
  193. package/src/options/codec.ts +98 -0
  194. package/src/options/index.ts +5 -0
  195. package/src/options/latest.ts +12 -0
  196. package/src/options/types.ts +164 -43
  197. package/tsconfig.build.json +9 -1
  198. package/tsconfig.build.tsbuildinfo +1 -1
  199. package/bin/scrcpy-server +0 -0
  200. package/bin/version.d.ts +0 -1
  201. package/bin/version.js +0 -1
  202. package/esm/adb/client.d.ts +0 -41
  203. package/esm/adb/client.d.ts.map +0 -1
  204. package/esm/adb/client.js +0 -224
  205. package/esm/adb/client.js.map +0 -1
  206. package/esm/adb/connection.d.ts +0 -49
  207. package/esm/adb/connection.d.ts.map +0 -1
  208. package/esm/adb/connection.js +0 -122
  209. package/esm/adb/connection.js.map +0 -1
  210. package/esm/adb/index.d.ts +0 -4
  211. package/esm/adb/index.d.ts.map +0 -1
  212. package/esm/adb/index.js +0 -4
  213. package/esm/adb/index.js.map +0 -1
  214. package/esm/adb/options/1_16.d.ts +0 -8
  215. package/esm/adb/options/1_16.d.ts.map +0 -1
  216. package/esm/adb/options/1_16.js +0 -20
  217. package/esm/adb/options/1_16.js.map +0 -1
  218. package/esm/adb/options/1_22.d.ts +0 -8
  219. package/esm/adb/options/1_22.d.ts.map +0 -1
  220. package/esm/adb/options/1_22.js +0 -17
  221. package/esm/adb/options/1_22.js.map +0 -1
  222. package/esm/adb/options/1_26.d.ts +0 -9
  223. package/esm/adb/options/1_26.d.ts.map +0 -1
  224. package/esm/adb/options/1_26.js +0 -11
  225. package/esm/adb/options/1_26.js.map +0 -1
  226. package/esm/adb/options/2_0.d.ts +0 -8
  227. package/esm/adb/options/2_0.d.ts.map +0 -1
  228. package/esm/adb/options/2_0.js +0 -13
  229. package/esm/adb/options/2_0.js.map +0 -1
  230. package/esm/adb/options/index.d.ts +0 -4
  231. package/esm/adb/options/index.d.ts.map +0 -1
  232. package/esm/adb/options/index.js +0 -4
  233. package/esm/adb/options/index.js.map +0 -1
  234. package/esm/adb/options/types.d.ts +0 -24
  235. package/esm/adb/options/types.d.ts.map +0 -1
  236. package/esm/adb/options/types.js +0 -37
  237. package/esm/adb/options/types.js.map +0 -1
  238. package/esm/codec.d.ts +0 -34
  239. package/esm/codec.d.ts.map +0 -1
  240. package/esm/codec.js +0 -37
  241. package/esm/codec.js.map +0 -1
  242. package/esm/control/simple.d.ts +0 -5
  243. package/esm/control/simple.d.ts.map +0 -1
  244. package/esm/control/simple.js.map +0 -1
  245. package/esm/decoder.d.ts +0 -2
  246. package/esm/decoder.d.ts.map +0 -1
  247. package/esm/decoder.js +0 -2
  248. package/esm/decoder.js.map +0 -1
  249. package/esm/options/1.17.d.ts +0 -3
  250. package/esm/options/1.17.d.ts.map +0 -1
  251. package/esm/options/1.17.js +0 -2
  252. package/esm/options/1.17.js.map +0 -1
  253. package/esm/options/1_16/h264-configuration.d.ts +0 -49
  254. package/esm/options/1_16/h264-configuration.d.ts.map +0 -1
  255. package/esm/options/1_16/h264-configuration.js +0 -414
  256. package/esm/options/1_16/h264-configuration.js.map +0 -1
  257. package/esm/options/1_16/sps.d.ts +0 -22
  258. package/esm/options/1_16/sps.d.ts.map +0 -1
  259. package/esm/options/1_16/sps.js +0 -263
  260. package/esm/options/1_16/sps.js.map +0 -1
  261. package/esm/options/1_26.d.ts +0 -57
  262. package/esm/options/1_26.d.ts.map +0 -1
  263. package/esm/options/1_26.js +0 -67
  264. package/esm/options/1_26.js.map +0 -1
  265. package/esm/options/2.d.ts +0 -57
  266. package/esm/options/2.d.ts.map +0 -1
  267. package/esm/options/2.js +0 -67
  268. package/esm/options/2.js.map +0 -1
  269. package/scripts/fetch-server.cjs +0 -38
  270. package/src/adb/client.ts +0 -329
  271. package/src/adb/connection.ts +0 -209
  272. package/src/adb/index.ts +0 -3
  273. package/src/adb/options/1_16.ts +0 -32
  274. package/src/adb/options/1_22.ts +0 -26
  275. package/src/adb/options/index.ts +0 -3
  276. package/src/adb/options/types.ts +0 -75
  277. package/src/codec.ts +0 -35
  278. 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,391 @@
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
+ readonly #nalu: Uint8Array;
235
+ readonly #byteLength: number;
236
+ readonly #stopBitIndex: number;
237
+
238
+ #zeroCount = 0;
239
+ #bytePosition = -1;
240
+ #bitPosition = -1;
241
+ #byte = 0;
242
+
243
+ get byteLength() {
244
+ return this.#byteLength;
245
+ }
246
+
247
+ get stopBitIndex() {
248
+ return this.#stopBitIndex;
249
+ }
250
+
251
+ get bytePosition() {
252
+ return this.#bytePosition;
253
+ }
254
+
255
+ get bitPosition() {
256
+ return this.#bitPosition;
257
+ }
258
+
259
+ get ended() {
260
+ return (
261
+ this.#bytePosition === this.#byteLength &&
262
+ this.#bitPosition === this.#stopBitIndex
263
+ );
264
+ }
265
+
266
+ 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("Stop bit not found");
286
+ }
287
+
288
+ #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
+ next() {
305
+ if (this.#bitPosition === -1) {
306
+ this.#bitPosition = 7;
307
+ this.#bytePosition += 1;
308
+ this.#readByte();
309
+ }
310
+
311
+ if (this.ended) {
312
+ throw new Error("Bit index out of bounds");
313
+ }
314
+
315
+ const value = (this.#byte >> this.#bitPosition) & 1;
316
+ this.#bitPosition -= 1;
317
+ return value;
318
+ }
319
+
320
+ read(length: number): number {
321
+ if (length > 32) {
322
+ throw new Error("Read length too large");
323
+ }
324
+
325
+ let result = 0;
326
+ for (let i = 0; i < length; i += 1) {
327
+ result = (result << 1) | this.next();
328
+ }
329
+ return result;
330
+ }
331
+
332
+ skip(length: number) {
333
+ for (let i = 0; i < length; i += 1) {
334
+ this.next();
335
+ }
336
+ }
337
+
338
+ decodeExponentialGolombNumber(): number {
339
+ let length = 0;
340
+ while (this.next() === 0) {
341
+ length += 1;
342
+ }
343
+ if (length === 0) {
344
+ return 0;
345
+ }
346
+ return ((1 << length) | this.read(length)) - 1;
347
+ }
348
+
349
+ #save() {
350
+ return {
351
+ zeroCount: this.#zeroCount,
352
+ bytePosition: this.#bytePosition,
353
+ bitPosition: this.#bitPosition,
354
+ byte: this.#byte,
355
+ };
356
+ }
357
+
358
+ #restore(state: {
359
+ zeroCount: number;
360
+ bytePosition: number;
361
+ bitPosition: number;
362
+ byte: number;
363
+ }) {
364
+ this.#zeroCount = state.zeroCount;
365
+ this.#bytePosition = state.bytePosition;
366
+ this.#bitPosition = state.bitPosition;
367
+ this.#byte = state.byte;
368
+ }
369
+
370
+ peek(length: number) {
371
+ const state = this.#save();
372
+ const result = this.read(length);
373
+ this.#restore(state);
374
+ return result;
375
+ }
376
+
377
+ readBytes(length: number): Uint8Array {
378
+ const result = new Uint8Array(length);
379
+ for (let i = 0; i < length; i += 1) {
380
+ result[i] = this.read(8);
381
+ }
382
+ return result;
383
+ }
384
+
385
+ peekBytes(length: number): Uint8Array {
386
+ const state = this.#save();
387
+ const result = this.readBytes(length);
388
+ this.#restore(state);
389
+ return result;
390
+ }
391
+ }
@@ -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");
@@ -15,34 +15,33 @@ import { ScrcpyControlMessageType } from "./type.js";
15
15
  * so Scrcpy server can remove the previously hovering pointer.
16
16
  */
17
17
  export class ScrcpyHoverHelper {
18
- // AFAIK, only mouse and pen can have hover state
19
- // and you can't have two mouses or pens.
20
- // So remember the last hovering pointer is enough.
21
- private lastHoverMessage: ScrcpyInjectTouchControlMessage | undefined;
18
+ // There can be only one hovering pointer (either mouse or pen,
19
+ // touch can have multiple pointers but no hovering state).
20
+ #lastHoverMessage: ScrcpyInjectTouchControlMessage | undefined;
22
21
 
23
- public process(
24
- message: Omit<ScrcpyInjectTouchControlMessage, "type">
22
+ process(
23
+ message: Omit<ScrcpyInjectTouchControlMessage, "type">,
25
24
  ): ScrcpyInjectTouchControlMessage[] {
26
25
  const result: ScrcpyInjectTouchControlMessage[] = [];
27
26
 
28
27
  // A different pointer appeared,
29
28
  // Cancel previously hovering pointer so Scrcpy server can free up the pointer ID.
30
29
  if (
31
- this.lastHoverMessage &&
32
- this.lastHoverMessage.pointerId !== message.pointerId
30
+ this.#lastHoverMessage &&
31
+ this.#lastHoverMessage.pointerId !== message.pointerId
33
32
  ) {
34
33
  // TODO: Inject MotionEvent.ACTION_HOVER_EXIT
35
34
  // From testing, it seems no App cares about this event.
36
35
  result.push({
37
- ...this.lastHoverMessage,
36
+ ...this.#lastHoverMessage,
38
37
  action: AndroidMotionEventAction.Up,
39
38
  });
40
- this.lastHoverMessage = undefined;
39
+ this.#lastHoverMessage = undefined;
41
40
  }
42
41
 
43
42
  if (message.action === AndroidMotionEventAction.HoverMove) {
44
43
  // TODO: Inject MotionEvent.ACTION_HOVER_ENTER
45
- this.lastHoverMessage = message as ScrcpyInjectTouchControlMessage;
44
+ this.#lastHoverMessage = message as ScrcpyInjectTouchControlMessage;
46
45
  }
47
46
 
48
47
  (message as ScrcpyInjectTouchControlMessage).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"];