@yume-chan/scrcpy 0.0.15 → 0.0.17

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 +33 -0
  2. package/CHANGELOG.md +18 -1
  3. package/LICENSE +21 -21
  4. package/README.md +327 -89
  5. package/esm/adb/client.d.ts +40 -0
  6. package/esm/adb/client.d.ts.map +1 -0
  7. package/esm/adb/client.js +218 -0
  8. package/esm/adb/client.js.map +1 -0
  9. package/esm/adb/connection.d.ts +38 -0
  10. package/esm/adb/connection.d.ts.map +1 -0
  11. package/esm/{connection.js → adb/connection.js} +20 -24
  12. package/esm/adb/connection.js.map +1 -0
  13. package/esm/adb/index.d.ts +4 -0
  14. package/esm/adb/index.d.ts.map +1 -0
  15. package/esm/adb/index.js +4 -0
  16. package/esm/adb/index.js.map +1 -0
  17. package/esm/adb/options/1_16.d.ts +8 -0
  18. package/esm/adb/options/1_16.d.ts.map +1 -0
  19. package/esm/adb/options/1_16.js +20 -0
  20. package/esm/adb/options/1_16.js.map +1 -0
  21. package/esm/adb/options/1_22.d.ts +8 -0
  22. package/esm/adb/options/1_22.d.ts.map +1 -0
  23. package/esm/adb/options/1_22.js +17 -0
  24. package/esm/adb/options/1_22.js.map +1 -0
  25. package/esm/adb/options/index.d.ts +4 -0
  26. package/esm/adb/options/index.d.ts.map +1 -0
  27. package/esm/adb/options/index.js +4 -0
  28. package/esm/adb/options/index.js.map +1 -0
  29. package/esm/adb/options/types.d.ts +23 -0
  30. package/esm/adb/options/types.d.ts.map +1 -0
  31. package/esm/adb/options/types.js +30 -0
  32. package/esm/adb/options/types.js.map +1 -0
  33. package/esm/codec.js +2 -2
  34. package/esm/codec.js.map +1 -1
  35. package/esm/control/index.d.ts +8 -0
  36. package/esm/control/index.d.ts.map +1 -0
  37. package/esm/control/index.js +8 -0
  38. package/esm/control/index.js.map +1 -0
  39. package/esm/control/inject-keycode.d.ts +53 -0
  40. package/esm/control/inject-keycode.d.ts.map +1 -0
  41. package/esm/control/inject-keycode.js +54 -0
  42. package/esm/control/inject-keycode.js.map +1 -0
  43. package/esm/control/inject-text.d.ts +9 -0
  44. package/esm/control/inject-text.d.ts.map +1 -0
  45. package/esm/control/inject-text.js +7 -0
  46. package/esm/control/inject-text.js.map +1 -0
  47. package/esm/control/inject-touch.d.ts +30 -0
  48. package/esm/control/inject-touch.d.ts.map +1 -0
  49. package/esm/control/inject-touch.js +30 -0
  50. package/esm/control/inject-touch.js.map +1 -0
  51. package/esm/control/rotate-device.d.ts +7 -0
  52. package/esm/control/rotate-device.d.ts.map +1 -0
  53. package/esm/control/rotate-device.js +5 -0
  54. package/esm/control/rotate-device.js.map +1 -0
  55. package/esm/control/serializer.d.ts +23 -0
  56. package/esm/control/serializer.d.ts.map +1 -0
  57. package/esm/control/serializer.js +73 -0
  58. package/esm/control/serializer.js.map +1 -0
  59. package/esm/control/set-screen-power-mode.d.ts +12 -0
  60. package/esm/control/set-screen-power-mode.d.ts.map +1 -0
  61. package/esm/control/set-screen-power-mode.js +12 -0
  62. package/esm/control/set-screen-power-mode.js.map +1 -0
  63. package/esm/control/type.d.ts +15 -0
  64. package/esm/control/type.d.ts.map +1 -0
  65. package/esm/control/type.js +19 -0
  66. package/esm/control/type.js.map +1 -0
  67. package/esm/decoder/index.d.ts +27 -3
  68. package/esm/decoder/index.d.ts.map +1 -1
  69. package/esm/decoder/index.js +1 -3
  70. package/esm/decoder/index.js.map +1 -1
  71. package/esm/decoder/tinyh264/index.d.ts +5 -5
  72. package/esm/decoder/tinyh264/index.d.ts.map +1 -1
  73. package/esm/decoder/tinyh264/index.js +4 -4
  74. package/esm/decoder/tinyh264/index.js.map +1 -1
  75. package/esm/decoder/tinyh264/worker.js.map +1 -1
  76. package/esm/decoder/tinyh264/wrapper.d.ts.map +1 -1
  77. package/esm/decoder/tinyh264/wrapper.js +14 -8
  78. package/esm/decoder/tinyh264/wrapper.js.map +1 -1
  79. package/esm/decoder/types.d.ts +1 -27
  80. package/esm/decoder/types.d.ts.map +1 -1
  81. package/esm/decoder/web-codecs/index.d.ts +4 -4
  82. package/esm/decoder/web-codecs/index.d.ts.map +1 -1
  83. package/esm/decoder/web-codecs/index.js +1 -1
  84. package/esm/decoder/web-codecs/index.js.map +1 -1
  85. package/esm/device-message/clipboard.d.ts +10 -0
  86. package/esm/device-message/clipboard.d.ts.map +1 -0
  87. package/esm/device-message/clipboard.js +7 -0
  88. package/esm/device-message/clipboard.js.map +1 -0
  89. package/esm/device-message/index.d.ts +4 -0
  90. package/esm/device-message/index.d.ts.map +1 -0
  91. package/esm/device-message/index.js +4 -0
  92. package/esm/device-message/index.js.map +1 -0
  93. package/esm/device-message/stream.d.ts +7 -0
  94. package/esm/device-message/stream.d.ts.map +1 -0
  95. package/esm/device-message/stream.js +16 -0
  96. package/esm/device-message/stream.js.map +1 -0
  97. package/esm/device-message/type.d.ts +5 -0
  98. package/esm/device-message/type.d.ts.map +1 -0
  99. package/esm/device-message/type.js +7 -0
  100. package/esm/device-message/type.js.map +1 -0
  101. package/esm/index.d.ts +3 -6
  102. package/esm/index.d.ts.map +1 -1
  103. package/esm/index.js +3 -6
  104. package/esm/index.js.map +1 -1
  105. package/esm/options/1_16/codec-options.d.ts +19 -0
  106. package/esm/options/1_16/codec-options.d.ts.map +1 -0
  107. package/esm/options/1_16/codec-options.js +27 -0
  108. package/esm/options/1_16/codec-options.js.map +1 -0
  109. package/esm/options/1_16/index.d.ts +3 -107
  110. package/esm/options/1_16/index.d.ts.map +1 -1
  111. package/esm/options/1_16/index.js +3 -216
  112. package/esm/options/1_16/index.js.map +1 -1
  113. package/esm/options/1_16/options.d.ts +97 -0
  114. package/esm/options/1_16/options.d.ts.map +1 -0
  115. package/esm/options/1_16/options.js +188 -0
  116. package/esm/options/1_16/options.js.map +1 -0
  117. package/esm/options/1_18.d.ts +8 -8
  118. package/esm/options/1_18.d.ts.map +1 -1
  119. package/esm/options/1_18.js +6 -6
  120. package/esm/options/1_18.js.map +1 -1
  121. package/esm/options/1_21.d.ts +1 -1
  122. package/esm/options/1_21.d.ts.map +1 -1
  123. package/esm/options/1_21.js +1 -1
  124. package/esm/options/1_21.js.map +1 -1
  125. package/esm/options/1_22.d.ts +5 -8
  126. package/esm/options/1_22.d.ts.map +1 -1
  127. package/esm/options/1_22.js +4 -17
  128. package/esm/options/1_22.js.map +1 -1
  129. package/esm/options/1_23.d.ts +4 -4
  130. package/esm/options/1_23.d.ts.map +1 -1
  131. package/esm/options/1_23.js +1 -1
  132. package/esm/options/1_23.js.map +1 -1
  133. package/esm/options/1_24.d.ts +1 -1
  134. package/esm/options/1_24.d.ts.map +1 -1
  135. package/esm/options/1_24.js.map +1 -1
  136. package/esm/options/index.d.ts +1 -1
  137. package/esm/options/index.d.ts.map +1 -1
  138. package/esm/options/index.js +1 -1
  139. package/esm/options/index.js.map +1 -1
  140. package/esm/options/types.d.ts +45 -0
  141. package/esm/options/types.d.ts.map +1 -0
  142. package/esm/options/{common.js → types.js} +1 -1
  143. package/esm/options/types.js.map +1 -0
  144. package/package.json +24 -24
  145. package/scrcpy.LICENSE +203 -203
  146. package/scripts/fetch-server.cjs +28 -28
  147. package/src/adb/client.ts +292 -0
  148. package/src/{connection.ts → adb/connection.ts} +145 -148
  149. package/src/adb/index.ts +3 -0
  150. package/src/adb/options/1_16.ts +23 -0
  151. package/src/adb/options/1_22.ts +20 -0
  152. package/src/adb/options/index.ts +3 -0
  153. package/src/adb/options/types.ts +55 -0
  154. package/src/codec.ts +35 -35
  155. package/src/control/index.ts +7 -0
  156. package/src/control/inject-keycode.ts +59 -0
  157. package/src/control/inject-text.ts +12 -0
  158. package/src/control/inject-touch.ts +34 -0
  159. package/src/control/rotate-device.ts +10 -0
  160. package/src/control/serializer.ts +86 -0
  161. package/src/control/set-screen-power-mode.ts +17 -0
  162. package/src/control/type.ts +17 -0
  163. package/src/device-message/clipboard.ts +11 -0
  164. package/src/device-message/index.ts +3 -0
  165. package/src/device-message/stream.ts +19 -0
  166. package/src/device-message/type.ts +5 -0
  167. package/src/index.ts +5 -8
  168. package/src/options/1_16/codec-options.ts +48 -0
  169. package/src/options/1_16/index.ts +3 -330
  170. package/src/options/1_16/options.ts +294 -0
  171. package/src/options/1_16/sps.ts +300 -300
  172. package/src/options/1_18.ts +63 -61
  173. package/src/options/1_21.ts +44 -34
  174. package/src/options/1_22.ts +67 -78
  175. package/src/options/1_23.ts +7 -5
  176. package/src/options/1_24.ts +3 -2
  177. package/src/options/index.ts +7 -7
  178. package/src/options/{common.ts → types.ts} +85 -66
  179. package/tsconfig.build.json +3 -0
  180. package/tsconfig.build.tsbuildinfo +1 -0
  181. package/tsconfig.test.tsbuildinfo +1 -0
  182. package/esm/client.d.ts +0 -48
  183. package/esm/client.d.ts.map +0 -1
  184. package/esm/client.js +0 -341
  185. package/esm/client.js.map +0 -1
  186. package/esm/connection.d.ts +0 -37
  187. package/esm/connection.d.ts.map +0 -1
  188. package/esm/connection.js.map +0 -1
  189. package/esm/message.d.ts +0 -97
  190. package/esm/message.d.ts.map +0 -1
  191. package/esm/message.js +0 -97
  192. package/esm/message.js.map +0 -1
  193. package/esm/options/common.d.ts +0 -34
  194. package/esm/options/common.d.ts.map +0 -1
  195. package/esm/options/common.js.map +0 -1
  196. package/esm/push-server.d.ts +0 -6
  197. package/esm/push-server.d.ts.map +0 -1
  198. package/esm/push-server.js +0 -16
  199. package/esm/push-server.js.map +0 -1
  200. package/esm/utils.d.ts +0 -2
  201. package/esm/utils.d.ts.map +0 -1
  202. package/esm/utils.js +0 -6
  203. package/esm/utils.js.map +0 -1
  204. package/src/client.ts +0 -435
  205. package/src/decoder/index.ts +0 -3
  206. package/src/decoder/tinyh264/index.ts +0 -112
  207. package/src/decoder/tinyh264/types.d.ts +0 -137
  208. package/src/decoder/tinyh264/worker.ts +0 -2
  209. package/src/decoder/tinyh264/wrapper.ts +0 -89
  210. package/src/decoder/types.ts +0 -35
  211. package/src/decoder/web-codecs/index.ts +0 -99
  212. package/src/message.ts +0 -112
  213. package/src/push-server.ts +0 -24
  214. package/src/utils.ts +0 -5
package/CHANGELOG.json CHANGED
@@ -1,6 +1,39 @@
1
1
  {
2
2
  "name": "@yume-chan/scrcpy",
3
3
  "entries": [
4
+ {
5
+ "version": "0.0.17",
6
+ "tag": "@yume-chan/scrcpy_v0.0.17",
7
+ "date": "Tue, 18 Oct 2022 09:32:30 GMT",
8
+ "comments": {
9
+ "none": [
10
+ {
11
+ "comment": "Add standalone types for serializing/deserializing Scrcpy packets"
12
+ },
13
+ {
14
+ "comment": "Separate decoders to own packages so they don't need optional peer dependencies."
15
+ }
16
+ ]
17
+ }
18
+ },
19
+ {
20
+ "version": "0.0.16",
21
+ "tag": "@yume-chan/scrcpy_v0.0.16",
22
+ "date": "Sat, 28 May 2022 03:56:37 GMT",
23
+ "comments": {
24
+ "none": [
25
+ {
26
+ "comment": "Upgrade TypeScript to 4.7.2 to enable Node.js ESM"
27
+ },
28
+ {
29
+ "comment": "Add support for more `CodecOptions` keys"
30
+ },
31
+ {
32
+ "comment": "Add support for `CodecOptions` value types other than `int`"
33
+ }
34
+ ]
35
+ }
36
+ },
4
37
  {
5
38
  "version": "0.0.15",
6
39
  "tag": "@yume-chan/scrcpy_v0.0.15",
package/CHANGELOG.md CHANGED
@@ -1,6 +1,23 @@
1
1
  # Change Log - @yume-chan/scrcpy
2
2
 
3
- This log was last generated on Mon, 02 May 2022 04:18:01 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 18 Oct 2022 09:32:30 GMT and should not be manually modified.
4
+
5
+ ## 0.0.17
6
+ Tue, 18 Oct 2022 09:32:30 GMT
7
+
8
+ ### Updates
9
+
10
+ - Add standalone types for serializing/deserializing Scrcpy packets
11
+ - Separate decoders to own packages so they don't need optional peer dependencies.
12
+
13
+ ## 0.0.16
14
+ Sat, 28 May 2022 03:56:37 GMT
15
+
16
+ ### Updates
17
+
18
+ - Upgrade TypeScript to 4.7.2 to enable Node.js ESM
19
+ - Add support for more `CodecOptions` keys
20
+ - Add support for `CodecOptions` value types other than `int`
4
21
 
5
22
  ## 0.0.15
6
23
  Mon, 02 May 2022 04:18:01 GMT
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2020-2022 Simon Chan
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2022 Simon Chan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,89 +1,327 @@
1
- # @yume-chan/scrcpy
2
-
3
- TypeScript implementation of [Scrcpy](https://github.com/Genymobile/scrcpy) client.
4
-
5
- It uses the official Scrcpy server releases.
6
-
7
- **WARNING:** The public API is UNSTABLE. If you have any questions, please open an issue.
8
-
9
- ## Download Server Binary
10
-
11
- This package has a script `fetch-scrcpy-server` to help you download the official server binary.
12
-
13
- The server binary is subject to [Apache License 2.0](https://github.com/Genymobile/scrcpy/blob/master/LICENSE).
14
-
15
- Usage:
16
-
17
- ```
18
- $ npx fetch-scrcpy-server <version>
19
- ```
20
-
21
- For example:
22
-
23
- ```
24
- $ npx fetch-scrcpy-server 1.21
25
- ```
26
-
27
- You can also add it to the `postinstall` script of your `package.json` so it will run automatically when you do `npm install`:
28
-
29
- ```json
30
- "scripts": {
31
- "postinstall": "fetch-scrcpy-server 1.21",
32
- },
33
- ```
34
-
35
- It will download the binary to `bin/scrcpy` and write the version string to `bin/version.js`. You can import the version string with
36
-
37
- ```js
38
- import SCRCPY_SERVER_VERSION from '@yume-chan/scrcpy/bin/version';
39
- ```
40
-
41
- And import the server binary with [file-loader](https://v4.webpack.js.org/loaders/file-loader/) (Webpack 4) or [Asset Modules](https://webpack.js.org/guides/asset-modules/) (Webpack 5).
42
-
43
- ## Option versions
44
-
45
- Scrcpy server has no backward compatibility on options input format. Currently the following versions are supported:
46
-
47
- | versions | type |
48
- | --------- | ------------------- |
49
- | 1.16~1.17 | `ScrcpyOptions1_16` |
50
- | 1.18~1.20 | `ScrcpyOptions1_18` |
51
- | 1.21 | `ScrcpyOptions1_21` |
52
- | 1.22 | `ScrcpyOptions1_22` |
53
- | 1.23 | `ScrcpyOptions1_23` |
54
-
55
- You must use the correct type according to the server version.
56
-
57
- ## Video stream
58
-
59
- The data from `onVideoData` event is a raw H.264 stream. You can process it as you want, or use the following built-in decoders to render it in browsers:
60
-
61
- * WebCodecs decoder: Uses the [WebCodecs API](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API). The video stream will be decoded into `VideoFrame`s and drawn on a 2D canvas.
62
- * TinyH264 decoder: TinyH264 compiles the old Android H.264 software decoder (now deprecated and removed) into WebAssembly, and wrap it in Web Worker to prevent blocking the main thread. The video stream will be decoded into YUV frames, then converted to RGB using a WebGL shader.
63
-
64
- | Name | Chrome | Firefox | Safari | Performance | Supported H.264 profile/level |
65
- | ----------------- | ------ | ------- | ------ | ------------------------------- | ----------------------------- |
66
- | WebCodecs decoder | 94 | No | No | High with Hardware acceleration | High level 5 |
67
- | TinyH264 decoder | 57 | 52 | 11 | Poor | Baseline level 4 |
68
-
69
- TinyH264 decoder needs some extra setup:
70
-
71
- 1. `tinyh264`, `yuv-buffer` and `yuv-canvas` packages are peer dependencies. You must install them separately.
72
- 2. The bundler you use must support the `new Worker(new URL('./worker.js', import.meta.url))` syntax. It's known to work with Webpack 5.
73
-
74
- Example usage:
75
-
76
- ```ts
77
- const client = new ScrcpyClient(adb);
78
- const decoder = new WebCodecsDecoder(); // Or `new TinyH264Decoder()`
79
- client.onSizeChanged(size => decoder.setSize(size));
80
- client.onVideoData(data => decoder.feed(data));
81
- client.start(serverPath, serverVersion, new ScrcpyOptionsX_XX({
82
- ...options,
83
- codecOptions: new CodecOptions({
84
- profile: decoder.maxProfile,
85
- level: decoder.maxLevel,
86
- }),
87
- }));
88
- document.body.appendChild(decoder.element);
89
- ```
1
+ # @yume-chan/scrcpy
2
+
3
+ TypeScript implementation of [Scrcpy](https://github.com/Genymobile/scrcpy) client.
4
+
5
+ It's compatible with the official Scrcpy server binaries.
6
+
7
+ **WARNING:** The public API is UNSTABLE. If you have any questions, please open an issue.
8
+
9
+ - [Transport agnostic](#transport-agnostic)
10
+ - [Prepare server binary](#prepare-server-binary)
11
+ - [`fetch-scrcpy-server`](#fetch-scrcpy-server)
12
+ - [Use the server binary](#use-the-server-binary)
13
+ - [Node.js CommonJS](#nodejs-commonjs)
14
+ - [Node.js ES module](#nodejs-es-module)
15
+ - [Webpack 4](#webpack-4)
16
+ - [Webpack 5](#webpack-5)
17
+ - [Read the server version](#read-the-server-version)
18
+ - [Option versions](#option-versions)
19
+ - [Use with `@yume-chan/adb`](#use-with-yume-chanadb)
20
+ - [Push server binary](#push-server-binary)
21
+ - [Start server on device](#start-server-on-device)
22
+ - [Using other transportation](#using-other-transportation)
23
+ - [Parsing video packets](#parsing-video-packets)
24
+ - [Sending control messages](#sending-control-messages)
25
+ - [Reading device messages](#reading-device-messages)
26
+ - [Consume the streams](#consume-the-streams)
27
+ - [Video stream](#video-stream)
28
+ - [Decode video stream](#decode-video-stream)
29
+
30
+ ## Transport agnostic
31
+
32
+ It was initially designed to be used with `@yume-chan/adb`, but now it can also to used with any other transportation.
33
+
34
+ ## Prepare server binary
35
+
36
+ Scrcpy needs a server binary running on the device in order to work. This package doesn't ship with one.
37
+
38
+ You can download the server binary from official releases (https://github.com/Genymobile/scrcpy/releases), or use the built-in `fetch-scrcpy-server` script to automate the process.
39
+
40
+ The server binary is subject to [Apache License 2.0](https://github.com/Genymobile/scrcpy/blob/master/LICENSE).
41
+
42
+ ### `fetch-scrcpy-server`
43
+
44
+ To use the script, first add `gh-release-fetch@3` to `devDependencies` of your `package.json`. It's an optional peer dependency fpr minimized download size.
45
+
46
+ Then you can invoke it in a terminal:
47
+
48
+ ```
49
+ $ npx fetch-scrcpy-server <version>
50
+ ```
51
+
52
+ For example:
53
+
54
+ ```
55
+ $ npx fetch-scrcpy-server 1.24
56
+ ```
57
+
58
+ You can also add it to the `postinstall` script in your `package.json`. After that, running `npm install` will automatically invoke the script.
59
+
60
+ ```json
61
+ "scripts": {
62
+ "postinstall": "fetch-scrcpy-server 1.24",
63
+ },
64
+ ```
65
+
66
+ The server binary will be named `bin/scrcpy-server` in this package's installation directory (usually in `node_modules`).
67
+
68
+ ### Use the server binary
69
+
70
+ The server binary file needs to be embedded into your application, the exact method depends on the runtime.
71
+
72
+ To name a few:
73
+
74
+ #### Node.js CommonJS
75
+
76
+ ```ts
77
+ const fs = require('fs');
78
+ const path: string = require.resolve('@yume-chan/scrcpy/bin/scrcpy-server'); // Or your own server binary path
79
+ const buffer: Buffer = fs.readFileSync(path);
80
+ ```
81
+
82
+ #### Node.js ES module
83
+
84
+ ```ts
85
+ import fs from 'node:fs/promises';
86
+ import { createRequire } from 'node:module';
87
+
88
+ const path: string = createRequire(import.meta.url).resolve('@yume-chan/scrcpy/bin/scrcpy-server'); // Or your own server binary path
89
+ const buffer: Buffer = await fs.readFile(path);
90
+ ```
91
+
92
+ Currently, ES Module doesn't have a `resolve` function like `require.resolve` in CommonJS, so `createRequire` is used to create a CommonJS resolver.
93
+
94
+ `import.meta.resolve` (https://github.com/whatwg/html/pull/5572) is a proposal that fills this gap. Node.js already has experimental support for it behind a flag. See https://nodejs.org/api/esm.html#importmetaresolvespecifier-parent for more information.
95
+
96
+ ```ts
97
+ const path: string = import.meta.resolve('@yume-chan/scrcpy/bin/scrcpy-server');
98
+ ```
99
+
100
+ #### Webpack 4
101
+
102
+ Requires installing and configuring file-loader (https://v4.webpack.js.org/loaders/file-loader/)
103
+
104
+ ```ts
105
+ import SCRCPY_SERVER_URL from '@yume-chan/scrcpy/bin/scrcpy-server'; // Or your own server binary path
106
+ const buffer: ArrayBuffer = await fetch(SCRCPY_SERVER_URL).then(res => res.arrayBuffer());
107
+ ```
108
+
109
+ #### Webpack 5
110
+
111
+ Requires configuring Asset Modules (https://webpack.js.org/guides/asset-modules/)
112
+
113
+ ```ts
114
+ const SCRCPY_SERVER_URL = new URL('@yume-chan/scrcpy/bin/scrcpy-server', import.meta.url); // Or your own server binary path
115
+ const buffer: ArrayBuffer = await fetch(SCRCPY_SERVER_URL).then(res => res.arrayBuffer());
116
+ ```
117
+
118
+ ### Read the server version
119
+
120
+ The correct version number is required to launch the server, so `fetch-scrcpy-server` also writes the version number to `bin/version.js`.
121
+
122
+ ```js
123
+ import SCRCPY_SERVER_VERSION from '@yume-chan/scrcpy/bin/version.js';
124
+
125
+ console.log(SCRCPY_SERVER_VERSION); // "1.24"
126
+ ```
127
+
128
+ ## Option versions
129
+
130
+ Scrcpy server options changes over time, and some of them are not backwards compatible. This package provides option types for each version (or range). Using wrong option version usually results in errors.
131
+
132
+ The latest one may continue to work for future server versions, but there is no guarantee.
133
+
134
+ | Version | Type |
135
+ | --------- | ------------------- |
136
+ | 1.16~1.17 | `ScrcpyOptions1_16` |
137
+ | 1.18~1.20 | `ScrcpyOptions1_18` |
138
+ | 1.21 | `ScrcpyOptions1_21` |
139
+ | 1.22 | `ScrcpyOptions1_22` |
140
+ | 1.23 | `ScrcpyOptions1_23` |
141
+ | 1.24 | `ScrcpyOptions1_24` |
142
+
143
+ When using `AdbScrcpyClient`, there is another `AdbScrcpyOptions` contains `@yume-chan/adb` related logics:
144
+
145
+ | Version | Type |
146
+ | --------- | ---------------------- |
147
+ | 1.16~1.21 | `AdbScrcpyOptions1_16` |
148
+ | 1.22~1.24 | `AdbScrcpyOptions1_22` |
149
+
150
+ ## Use with `@yume-chan/adb`
151
+
152
+ The the server binary needs to be copied to the device and run on it.
153
+
154
+ ### Push server binary
155
+
156
+ The `Adb#sync()#write()` method can be used to push files to the device. Read more at `@yume-chan/adb`'s documentation (https://github.com/yume-chan/ya-webadb/tree/main/libraries/adb#readme).
157
+
158
+ This package also provides the `AdbScrcpyClient.pushServer()` static method as a shortcut, plus it will automatically close the `AdbSync` object on completion.
159
+
160
+ Example using `write()`:
161
+
162
+ ```ts
163
+ import { AdbScrcpyClient } from '@yume-chan/scrcpy';
164
+
165
+ const stream: WritableStream<Uint8Array> = AdbScrcpyClient.pushServer(adb);
166
+ const writer = stream.getWriter();
167
+ await writer.write(new Uint8Array(buffer));
168
+ await writer.close();
169
+ ```
170
+
171
+ Example using `pipeTo()`:
172
+
173
+ ```ts
174
+ import { WrapReadableStream } from '@yume-chan/adb';
175
+ import { AdbScrcpyClient } from '@yume-chan/scrcpy';
176
+
177
+ await fetch(SCRCPY_SERVER_URL)
178
+ // `WrapReadableStream` is required because native `ReadableStream` (from `fetch`)
179
+ // doesn't support `pipeTo()` non-native `WritableStream`s
180
+ // (`@yume-chan/adb` is using `web-streams-polyfill`)
181
+ .then(response => new WrapReadableStream(response.body))
182
+ .then(stream => stream.pipeTo(AdbScrcpyClient.pushServer(adb)));
183
+ ```
184
+
185
+ ### Start server on device
186
+
187
+ To start the server, use the `AdbScrcpyClient.start()` method. It automatically sets up port forwarding, launches the server, and connects to it.
188
+
189
+ ```js
190
+ import { AdbScrcpyClient, AdbScrcpyOptions1_22, DEFAULT_SERVER_PATH, ScrcpyOptions1_24 } from '@yume-chan/scrcpy';
191
+ import SCRCPY_SERVER_VERSION from '@yume-chan/scrcpy/bin/version.js';
192
+
193
+ const client: AdbScrcpyClient = await AdbScrcpyClient.start(
194
+ adb,
195
+ DEFAULT_SERVER_PATH,
196
+ SCRCPY_SERVER_VERSION, // Or provide your own version number
197
+ new AdbScrcpyOptions1_22(ScrcpyOptions1_24({
198
+ // options
199
+ }))
200
+ );
201
+
202
+ const stdout: ReadableStream<string> = client.stdout;
203
+ const videoPacketStream: ReadableStream<ScrcpyVideoStreamPacket> = client.videoStream;
204
+ const controlMessageSerializer: ScrcpyControlMessageSerializer | undefined = client.controlMessageSerializer;
205
+ const deviceMessageStream: ReadableStream<ScrcpyDeviceMessage> | undefined = client.deviceMessageStream;
206
+
207
+ // to stop the server
208
+ client.close();
209
+ ```
210
+
211
+ ## Using other transportation
212
+
213
+ If you push, start and connect to the server yourself, you can still use this package to serialize/deserialize packets.
214
+
215
+ ### Parsing video packets
216
+
217
+ Requires a `ReadableStream<Uint8Array>` that reads from the video socket, preserving packet boundaries.
218
+
219
+ ```ts
220
+ import { ScrcpyOptions1_24, ScrcpyVideoStreamPacket } from '@yume-chan/scrcpy';
221
+
222
+ const videoStream: ReadableStream<Uint8Array>; // get the stream yourself
223
+
224
+ const options = new ScrcpyOptions1_24({
225
+ // use the same version and options
226
+ });
227
+
228
+ const videoPacketStream: ReadableStream<ScrcpyVideoStreamPacket> = videoStream.pipeThrough(options.createVideoStreamTransformer());
229
+ // Read from `videoPacketStream`
230
+ ```
231
+
232
+ ### Sending control messages
233
+
234
+ Requires a `WritableStream<Uint8Array>` that writes to the control socket.
235
+
236
+ Control socket is optional if control is not enabled. Video socket and control socket can run completely separately.
237
+
238
+ ```ts
239
+ import { ScrcpyControlMessageSerializer, ScrcpyOptions1_24 } from '@yume-chan/scrcpy';
240
+
241
+ const controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined // get the stream yourself
242
+
243
+ const options = new ScrcpyOptions1_24({
244
+ // use the same version and options
245
+ });
246
+
247
+ const controlMessageSerializer = new ScrcpyControlMessageSerializer(controlStream.writable, options);
248
+ // Call methods on `controlMessageSerializer`
249
+ controlMessageSerializer.injectText("Hello World!");
250
+ ```
251
+
252
+ ### Reading device messages
253
+
254
+ Requires a `ReadableStream<Uint8Array>` that reads from the control socket.
255
+
256
+ ```ts
257
+ import { ScrcpyDeviceMessageDeserializeStream, ScrcpyOptions1_24 } from '@yume-chan/scrcpy';
258
+
259
+ const controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined // get the stream yourself
260
+
261
+ const deviceMessageStream: ReadableStream<ScrcpyDeviceMessage> = controlStream.readable.pipeThrough(new ScrcpyDeviceMessageDeserializeStream());
262
+ ```
263
+
264
+ ## Consume the streams
265
+
266
+ Any `ReadableStream` (`stdout` when using `AdbScrcpyClient`, `videoPacketStream` and `deviceMessageStream` when control is enabled) must be continuously read (even if you don't care about the data), otherwise the whole connection will stall.
267
+
268
+ ```ts
269
+ // when using `AdbScrcpyClient`
270
+ stdout
271
+ .pipeTo(
272
+ new WritableStream<string>({
273
+ write: (line) => {
274
+ // Handle the stdout line
275
+ },
276
+ }),
277
+ )
278
+ .catch(() => {})
279
+ .then(() => {
280
+ // Handle server exit
281
+ });
282
+
283
+ videoPacketStream
284
+ .pipeTo(new WritableStream<ScrcpyVideoStreamPacket>({
285
+ write: (packet) => {
286
+ // Handle the video packet
287
+ },
288
+ }))
289
+ .catch(() => {});
290
+
291
+ deviceMessageStream
292
+ .pipeTo(new WritableStream<ScrcpyDeviceMessage>({
293
+ write: (message) => {
294
+ // Handle the device message
295
+ },
296
+ }))
297
+ .catch(() => {});
298
+ ```
299
+
300
+ ## Video stream
301
+
302
+ The data from `videoPacketStream` has two types: `configuration` and `frame`. Some fields may not be populated depending on the server version and options.
303
+
304
+ ```ts
305
+ export interface ScrcpyVideoStreamConfigurationPacket {
306
+ type: 'configuration';
307
+ data: H264Configuration;
308
+ }
309
+
310
+ export interface ScrcpyVideoStreamFramePacket {
311
+ type: 'frame';
312
+ keyframe?: boolean | undefined;
313
+ pts?: bigint | undefined;
314
+ data: Uint8Array;
315
+ }
316
+ ```
317
+
318
+ When `sendFrameMeta: false` is set, `videoPacketStream` only contains `frame` packets, and only the `data` field in it is available. It's commonly used when feeding into decoders like FFmpeg that can parse the H.264 stream itself, or saving to disk directly.
319
+
320
+ Otherwise, both `configuration` and `frame` packets are available.
321
+
322
+ * `configuration` packets contain the parsed SPS data, and can be used to initialize a video decoder.
323
+ * `pts` (and `keyframe` field from server version 1.23) fields in `frame` packets are available to help decode the video.
324
+
325
+ ## Decode video stream
326
+
327
+ `@yume-chan/scrcpy-decoder-tinyh264` and `@yume-chan/scrcpy-decoder-webcodecs` can be used to decode and render the video stream in Browser environments. Refer to their README files for compatibility and usage information.
@@ -0,0 +1,40 @@
1
+ import { Adb, AdbSubprocessProtocol } from '@yume-chan/adb';
2
+ import { ReadableStream, WrapWritableStream, type ReadableWritablePair } from '@yume-chan/stream-extra';
3
+ import { ScrcpyControlMessageSerializer } from '../control/index.js';
4
+ import { type ScrcpyVideoStreamPacket } from '../options/index.js';
5
+ import type { AdbScrcpyOptions } from './options/index.js';
6
+ export declare class AdbScrcpyClient {
7
+ static pushServer(adb: Adb, path?: string): WrapWritableStream<Uint8Array>;
8
+ static start(adb: Adb, path: string, version: string, options: AdbScrcpyOptions<any>): Promise<AdbScrcpyClient>;
9
+ /**
10
+ * This method will modify the given `options`,
11
+ * so don't reuse it elsewhere.
12
+ */
13
+ static getEncoders(adb: Adb, path: string, version: string, options: AdbScrcpyOptions<any>): Promise<string[]>;
14
+ /**
15
+ * This method will modify the given `options`,
16
+ * so don't reuse it elsewhere.
17
+ */
18
+ static getDisplays(adb: Adb, path: string, version: string, options: AdbScrcpyOptions<any>): Promise<number[]>;
19
+ private process;
20
+ private _stdout;
21
+ get stdout(): ReadableStream<string>;
22
+ get exit(): Promise<number>;
23
+ private _screenWidth;
24
+ get screenWidth(): number | undefined;
25
+ private _screenHeight;
26
+ get screenHeight(): number | undefined;
27
+ private _videoStream;
28
+ get videoStream(): ReadableStream<ScrcpyVideoStreamPacket>;
29
+ private _controlMessageSerializer;
30
+ get controlMessageSerializer(): ScrcpyControlMessageSerializer | undefined;
31
+ private _deviceMessageStream;
32
+ get deviceMessageStream(): ReadableStream<{
33
+ type: import("../device-message/type.js").ScrcpyDeviceMessageType.Clipboard;
34
+ length: number;
35
+ content: string;
36
+ }> | undefined;
37
+ constructor(options: AdbScrcpyOptions<any>, process: AdbSubprocessProtocol, stdout: ReadableStream<string>, videoStream: ReadableStream<Uint8Array>, controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined);
38
+ close(): Promise<void>;
39
+ }
40
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/adb/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAA6B,qBAAqB,EAAW,MAAM,gBAAgB,CAAC;AAChG,OAAO,EAAoD,cAAc,EAAqB,kBAAkB,EAA0F,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAErQ,OAAO,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,EAAuB,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA0D3D,qBAAa,eAAe;WACV,UAAU,CACpB,GAAG,EAAE,GAAG,EACR,IAAI,SAAsB;WAcV,KAAK,CACrB,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC;IA4ElC;;;OAGG;WACiB,WAAW,CAC3B,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC;IAgCpB;;;OAGG;WACiB,WAAW,CAC3B,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,GAC/B,OAAO,CAAC,MAAM,EAAE,CAAC;IA8BpB,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,OAAO,CAAyB;IACxC,IAAW,MAAM,2BAA2B;IAE5C,IAAW,IAAI,oBAAgC;IAE/C,OAAO,CAAC,YAAY,CAAqB;IACzC,IAAW,WAAW,uBAAgC;IAEtD,OAAO,CAAC,aAAa,CAAqB;IAC1C,IAAW,YAAY,uBAAiC;IAExD,OAAO,CAAC,YAAY,CAA0C;IAC9D,IAAW,WAAW,4CAAgC;IAEtD,OAAO,CAAC,yBAAyB,CAA6C;IAC9E,IAAW,wBAAwB,+CAA6C;IAEhF,OAAO,CAAC,oBAAoB,CAAkD;IAC9E,IAAW,mBAAmB;;;;mBAAwC;gBAGlE,OAAO,EAAE,gBAAgB,CAAC,GAAG,CAAC,EAC9B,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,EAC9B,WAAW,EAAE,cAAc,CAAC,UAAU,CAAC,EACvC,aAAa,EAAE,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,SAAS;IAoB9D,KAAK;CAGrB"}