@yume-chan/scrcpy 0.0.16 → 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.
- package/CHANGELOG.json +15 -0
- package/CHANGELOG.md +9 -1
- package/README.md +275 -38
- package/esm/adb/client.d.ts +40 -0
- package/esm/adb/client.d.ts.map +1 -0
- package/esm/adb/client.js +218 -0
- package/esm/adb/client.js.map +1 -0
- package/esm/adb/connection.d.ts +38 -0
- package/esm/adb/connection.d.ts.map +1 -0
- package/esm/{connection.js → adb/connection.js} +20 -24
- package/esm/adb/connection.js.map +1 -0
- package/esm/adb/index.d.ts +4 -0
- package/esm/adb/index.d.ts.map +1 -0
- package/esm/adb/index.js +4 -0
- package/esm/adb/index.js.map +1 -0
- package/esm/adb/options/1_16.d.ts +8 -0
- package/esm/adb/options/1_16.d.ts.map +1 -0
- package/esm/adb/options/1_16.js +20 -0
- package/esm/adb/options/1_16.js.map +1 -0
- package/esm/adb/options/1_22.d.ts +8 -0
- package/esm/adb/options/1_22.d.ts.map +1 -0
- package/esm/adb/options/1_22.js +17 -0
- package/esm/adb/options/1_22.js.map +1 -0
- package/esm/adb/options/index.d.ts +4 -0
- package/esm/adb/options/index.d.ts.map +1 -0
- package/esm/adb/options/index.js +4 -0
- package/esm/adb/options/index.js.map +1 -0
- package/esm/adb/options/types.d.ts +23 -0
- package/esm/adb/options/types.d.ts.map +1 -0
- package/esm/adb/options/types.js +30 -0
- package/esm/adb/options/types.js.map +1 -0
- package/esm/codec.js +2 -2
- package/esm/codec.js.map +1 -1
- package/esm/control/index.d.ts +8 -0
- package/esm/control/index.d.ts.map +1 -0
- package/esm/control/index.js +8 -0
- package/esm/control/index.js.map +1 -0
- package/esm/control/inject-keycode.d.ts +53 -0
- package/esm/control/inject-keycode.d.ts.map +1 -0
- package/esm/control/inject-keycode.js +54 -0
- package/esm/control/inject-keycode.js.map +1 -0
- package/esm/control/inject-text.d.ts +9 -0
- package/esm/control/inject-text.d.ts.map +1 -0
- package/esm/control/inject-text.js +7 -0
- package/esm/control/inject-text.js.map +1 -0
- package/esm/control/inject-touch.d.ts +30 -0
- package/esm/control/inject-touch.d.ts.map +1 -0
- package/esm/control/inject-touch.js +30 -0
- package/esm/control/inject-touch.js.map +1 -0
- package/esm/control/rotate-device.d.ts +7 -0
- package/esm/control/rotate-device.d.ts.map +1 -0
- package/esm/control/rotate-device.js +5 -0
- package/esm/control/rotate-device.js.map +1 -0
- package/esm/control/serializer.d.ts +23 -0
- package/esm/control/serializer.d.ts.map +1 -0
- package/esm/control/serializer.js +73 -0
- package/esm/control/serializer.js.map +1 -0
- package/esm/control/set-screen-power-mode.d.ts +12 -0
- package/esm/control/set-screen-power-mode.d.ts.map +1 -0
- package/esm/control/set-screen-power-mode.js +12 -0
- package/esm/control/set-screen-power-mode.js.map +1 -0
- package/esm/control/type.d.ts +15 -0
- package/esm/control/type.d.ts.map +1 -0
- package/esm/control/type.js +19 -0
- package/esm/control/type.js.map +1 -0
- package/esm/decoder/index.d.ts +27 -3
- package/esm/decoder/index.d.ts.map +1 -1
- package/esm/decoder/index.js +1 -3
- package/esm/decoder/index.js.map +1 -1
- package/esm/decoder/tinyh264/index.d.ts +5 -5
- package/esm/decoder/tinyh264/index.d.ts.map +1 -1
- package/esm/decoder/tinyh264/index.js +4 -4
- package/esm/decoder/tinyh264/index.js.map +1 -1
- package/esm/decoder/tinyh264/worker.js.map +1 -1
- package/esm/decoder/tinyh264/wrapper.d.ts.map +1 -1
- package/esm/decoder/tinyh264/wrapper.js +14 -8
- package/esm/decoder/tinyh264/wrapper.js.map +1 -1
- package/esm/decoder/types.d.ts +1 -27
- package/esm/decoder/types.d.ts.map +1 -1
- package/esm/decoder/web-codecs/index.d.ts +4 -4
- package/esm/decoder/web-codecs/index.d.ts.map +1 -1
- package/esm/decoder/web-codecs/index.js +1 -1
- package/esm/decoder/web-codecs/index.js.map +1 -1
- package/esm/device-message/clipboard.d.ts +10 -0
- package/esm/device-message/clipboard.d.ts.map +1 -0
- package/esm/device-message/clipboard.js +7 -0
- package/esm/device-message/clipboard.js.map +1 -0
- package/esm/device-message/index.d.ts +4 -0
- package/esm/device-message/index.d.ts.map +1 -0
- package/esm/device-message/index.js +4 -0
- package/esm/device-message/index.js.map +1 -0
- package/esm/device-message/stream.d.ts +7 -0
- package/esm/device-message/stream.d.ts.map +1 -0
- package/esm/device-message/stream.js +16 -0
- package/esm/device-message/stream.js.map +1 -0
- package/esm/device-message/type.d.ts +5 -0
- package/esm/device-message/type.d.ts.map +1 -0
- package/esm/device-message/type.js +7 -0
- package/esm/device-message/type.js.map +1 -0
- package/esm/index.d.ts +3 -6
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -6
- package/esm/index.js.map +1 -1
- package/esm/options/1_16/codec-options.d.ts +19 -0
- package/esm/options/1_16/codec-options.d.ts.map +1 -0
- package/esm/options/1_16/codec-options.js +27 -0
- package/esm/options/1_16/codec-options.js.map +1 -0
- package/esm/options/1_16/index.d.ts +3 -110
- package/esm/options/1_16/index.d.ts.map +1 -1
- package/esm/options/1_16/index.js +3 -226
- package/esm/options/1_16/index.js.map +1 -1
- package/esm/options/1_16/options.d.ts +97 -0
- package/esm/options/1_16/options.d.ts.map +1 -0
- package/esm/options/1_16/options.js +188 -0
- package/esm/options/1_16/options.js.map +1 -0
- package/esm/options/1_18.d.ts +8 -8
- package/esm/options/1_18.d.ts.map +1 -1
- package/esm/options/1_18.js +6 -6
- package/esm/options/1_18.js.map +1 -1
- package/esm/options/1_21.d.ts +1 -1
- package/esm/options/1_21.d.ts.map +1 -1
- package/esm/options/1_21.js +1 -1
- package/esm/options/1_21.js.map +1 -1
- package/esm/options/1_22.d.ts +5 -8
- package/esm/options/1_22.d.ts.map +1 -1
- package/esm/options/1_22.js +4 -17
- package/esm/options/1_22.js.map +1 -1
- package/esm/options/1_23.d.ts +4 -4
- package/esm/options/1_23.d.ts.map +1 -1
- package/esm/options/1_23.js +1 -1
- package/esm/options/1_23.js.map +1 -1
- package/esm/options/1_24.d.ts +1 -1
- package/esm/options/1_24.d.ts.map +1 -1
- package/esm/options/1_24.js.map +1 -1
- package/esm/options/index.d.ts +1 -1
- package/esm/options/index.d.ts.map +1 -1
- package/esm/options/index.js +1 -1
- package/esm/options/index.js.map +1 -1
- package/esm/options/types.d.ts +45 -0
- package/esm/options/types.d.ts.map +1 -0
- package/esm/options/{common.js → types.js} +1 -1
- package/esm/options/types.js.map +1 -0
- package/package.json +24 -24
- package/src/adb/client.ts +292 -0
- package/src/{connection.ts → adb/connection.ts} +35 -38
- package/src/adb/index.ts +3 -0
- package/src/adb/options/1_16.ts +23 -0
- package/src/adb/options/1_22.ts +20 -0
- package/src/adb/options/index.ts +3 -0
- package/src/adb/options/types.ts +55 -0
- package/src/control/index.ts +7 -0
- package/src/control/inject-keycode.ts +59 -0
- package/src/control/inject-text.ts +12 -0
- package/src/control/inject-touch.ts +34 -0
- package/src/control/rotate-device.ts +10 -0
- package/src/control/serializer.ts +86 -0
- package/src/control/set-screen-power-mode.ts +17 -0
- package/src/control/type.ts +17 -0
- package/src/device-message/clipboard.ts +11 -0
- package/src/device-message/index.ts +3 -0
- package/src/device-message/stream.ts +19 -0
- package/src/device-message/type.ts +5 -0
- package/src/index.ts +3 -6
- package/src/options/1_16/codec-options.ts +48 -0
- package/src/options/1_16/index.ts +3 -345
- package/src/options/1_16/options.ts +294 -0
- package/src/options/1_18.ts +12 -10
- package/src/options/1_21.ts +16 -6
- package/src/options/1_22.ts +10 -21
- package/src/options/1_23.ts +7 -5
- package/src/options/1_24.ts +3 -2
- package/src/options/index.ts +1 -1
- package/src/options/{common.ts → types.ts} +32 -13
- package/tsconfig.build.json +3 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.test.tsbuildinfo +1 -0
- package/esm/client.d.ts +0 -48
- package/esm/client.d.ts.map +0 -1
- package/esm/client.js +0 -341
- package/esm/client.js.map +0 -1
- package/esm/connection.d.ts +0 -37
- package/esm/connection.d.ts.map +0 -1
- package/esm/connection.js.map +0 -1
- package/esm/message.d.ts +0 -98
- package/esm/message.d.ts.map +0 -1
- package/esm/message.js +0 -98
- package/esm/message.js.map +0 -1
- package/esm/options/common.d.ts +0 -34
- package/esm/options/common.d.ts.map +0 -1
- package/esm/options/common.js.map +0 -1
- package/esm/push-server.d.ts +0 -6
- package/esm/push-server.d.ts.map +0 -1
- package/esm/push-server.js +0 -16
- package/esm/push-server.js.map +0 -1
- package/esm/utils.d.ts +0 -2
- package/esm/utils.d.ts.map +0 -1
- package/esm/utils.js +0 -6
- package/esm/utils.js.map +0 -1
- package/src/client.ts +0 -435
- package/src/decoder/index.ts +0 -3
- package/src/decoder/tinyh264/index.ts +0 -112
- package/src/decoder/tinyh264/types.d.ts +0 -137
- package/src/decoder/tinyh264/worker.ts +0 -2
- package/src/decoder/tinyh264/wrapper.ts +0 -89
- package/src/decoder/types.ts +0 -35
- package/src/decoder/web-codecs/index.ts +0 -99
- package/src/message.ts +0 -113
- package/src/push-server.ts +0 -24
- package/src/utils.ts +0 -5
package/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
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
|
+
},
|
|
4
19
|
{
|
|
5
20
|
"version": "0.0.16",
|
|
6
21
|
"tag": "@yume-chan/scrcpy_v0.0.16",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Change Log - @yume-chan/scrcpy
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
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.
|
|
4
12
|
|
|
5
13
|
## 0.0.16
|
|
6
14
|
Sat, 28 May 2022 03:56:37 GMT
|
package/README.md
CHANGED
|
@@ -2,17 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript implementation of [Scrcpy](https://github.com/Genymobile/scrcpy) client.
|
|
4
4
|
|
|
5
|
-
It
|
|
5
|
+
It's compatible with the official Scrcpy server binaries.
|
|
6
6
|
|
|
7
7
|
**WARNING:** The public API is UNSTABLE. If you have any questions, please open an issue.
|
|
8
8
|
|
|
9
|
-
|
|
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)
|
|
10
29
|
|
|
11
|
-
|
|
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.
|
|
12
39
|
|
|
13
40
|
The server binary is subject to [Apache License 2.0](https://github.com/Genymobile/scrcpy/blob/master/LICENSE).
|
|
14
41
|
|
|
15
|
-
|
|
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:
|
|
16
47
|
|
|
17
48
|
```
|
|
18
49
|
$ npx fetch-scrcpy-server <version>
|
|
@@ -21,30 +52,86 @@ $ npx fetch-scrcpy-server <version>
|
|
|
21
52
|
For example:
|
|
22
53
|
|
|
23
54
|
```
|
|
24
|
-
$ npx fetch-scrcpy-server 1.
|
|
55
|
+
$ npx fetch-scrcpy-server 1.24
|
|
25
56
|
```
|
|
26
57
|
|
|
27
|
-
You can also add it to the `postinstall` script
|
|
58
|
+
You can also add it to the `postinstall` script in your `package.json`. After that, running `npm install` will automatically invoke the script.
|
|
28
59
|
|
|
29
60
|
```json
|
|
30
61
|
"scripts": {
|
|
31
|
-
"postinstall": "fetch-scrcpy-server 1.
|
|
62
|
+
"postinstall": "fetch-scrcpy-server 1.24",
|
|
32
63
|
},
|
|
33
64
|
```
|
|
34
65
|
|
|
35
|
-
|
|
66
|
+
The server binary will be named `bin/scrcpy-server` in this package's installation directory (usually in `node_modules`).
|
|
36
67
|
|
|
37
|
-
|
|
38
|
-
|
|
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);
|
|
39
80
|
```
|
|
40
81
|
|
|
41
|
-
|
|
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
|
+
```
|
|
42
127
|
|
|
43
128
|
## Option versions
|
|
44
129
|
|
|
45
|
-
Scrcpy server
|
|
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.
|
|
46
131
|
|
|
47
|
-
|
|
132
|
+
The latest one may continue to work for future server versions, but there is no guarantee.
|
|
133
|
+
|
|
134
|
+
| Version | Type |
|
|
48
135
|
| --------- | ------------------- |
|
|
49
136
|
| 1.16~1.17 | `ScrcpyOptions1_16` |
|
|
50
137
|
| 1.18~1.20 | `ScrcpyOptions1_18` |
|
|
@@ -53,38 +140,188 @@ Scrcpy server has no backward compatibility on options input format. Currently t
|
|
|
53
140
|
| 1.23 | `ScrcpyOptions1_23` |
|
|
54
141
|
| 1.24 | `ScrcpyOptions1_24` |
|
|
55
142
|
|
|
56
|
-
|
|
143
|
+
When using `AdbScrcpyClient`, there is another `AdbScrcpyOptions` contains `@yume-chan/adb` related logics:
|
|
57
144
|
|
|
58
|
-
|
|
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
|
+
```
|
|
59
170
|
|
|
60
|
-
|
|
171
|
+
Example using `pipeTo()`:
|
|
61
172
|
|
|
62
|
-
|
|
63
|
-
|
|
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
|
+
```
|
|
64
184
|
|
|
65
|
-
|
|
66
|
-
| ----------------- | ------ | ------- | ------ | ------------------------------- | ----------------------------- |
|
|
67
|
-
| WebCodecs decoder | 94 | No | No | High with Hardware acceleration | High level 5 |
|
|
68
|
-
| TinyH264 decoder | 57 | 52 | 11 | Poor | Baseline level 4 |
|
|
185
|
+
### Start server on device
|
|
69
186
|
|
|
70
|
-
|
|
187
|
+
To start the server, use the `AdbScrcpyClient.start()` method. It automatically sets up port forwarding, launches the server, and connects to it.
|
|
71
188
|
|
|
72
|
-
|
|
73
|
-
|
|
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';
|
|
74
192
|
|
|
75
|
-
|
|
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.
|
|
76
218
|
|
|
77
219
|
```ts
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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!");
|
|
90
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"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { AdbSubprocessNoneProtocol } from '@yume-chan/adb';
|
|
2
|
+
import { AbortController, DecodeUtf8Stream, InspectStream, ReadableStream, SplitStringStream, WrapWritableStream, WritableStream } from '@yume-chan/stream-extra';
|
|
3
|
+
import { ScrcpyControlMessageSerializer } from '../control/index.js';
|
|
4
|
+
import { ScrcpyDeviceMessageDeserializeStream } from '../device-message/index.js';
|
|
5
|
+
import { DEFAULT_SERVER_PATH } from '../options/index.js';
|
|
6
|
+
class ArrayToStream extends ReadableStream {
|
|
7
|
+
array;
|
|
8
|
+
index = 0;
|
|
9
|
+
constructor(array) {
|
|
10
|
+
super({
|
|
11
|
+
start: async () => {
|
|
12
|
+
await Promise.resolve();
|
|
13
|
+
this.array = array;
|
|
14
|
+
},
|
|
15
|
+
pull: (controller) => {
|
|
16
|
+
if (this.index < this.array.length) {
|
|
17
|
+
controller.enqueue(this.array[this.index]);
|
|
18
|
+
this.index += 1;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
controller.close();
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
class ConcatStream extends ReadableStream {
|
|
28
|
+
streams;
|
|
29
|
+
index = 0;
|
|
30
|
+
reader;
|
|
31
|
+
constructor(...streams) {
|
|
32
|
+
super({
|
|
33
|
+
start: async (controller) => {
|
|
34
|
+
await Promise.resolve();
|
|
35
|
+
this.streams = streams;
|
|
36
|
+
this.advance(controller);
|
|
37
|
+
},
|
|
38
|
+
pull: async (controller) => {
|
|
39
|
+
const result = await this.reader.read();
|
|
40
|
+
if (!result.done) {
|
|
41
|
+
controller.enqueue(result.value);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.advance(controller);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
advance(controller) {
|
|
49
|
+
if (this.index < this.streams.length) {
|
|
50
|
+
this.reader = this.streams[this.index].getReader();
|
|
51
|
+
this.index += 1;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
controller.close();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export class AdbScrcpyClient {
|
|
59
|
+
static pushServer(adb, path = DEFAULT_SERVER_PATH) {
|
|
60
|
+
let sync;
|
|
61
|
+
return new WrapWritableStream({
|
|
62
|
+
async start() {
|
|
63
|
+
sync = await adb.sync();
|
|
64
|
+
return sync.write(path);
|
|
65
|
+
},
|
|
66
|
+
async close() {
|
|
67
|
+
await sync.dispose();
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
static async start(adb, path, version, options) {
|
|
72
|
+
const connection = options.createConnection(adb);
|
|
73
|
+
let process;
|
|
74
|
+
try {
|
|
75
|
+
await connection.initialize();
|
|
76
|
+
process = await adb.subprocess.spawn([
|
|
77
|
+
// cspell: disable-next-line
|
|
78
|
+
`CLASSPATH=${path}`,
|
|
79
|
+
'app_process',
|
|
80
|
+
/* unused */ '/',
|
|
81
|
+
'com.genymobile.scrcpy.Server',
|
|
82
|
+
version,
|
|
83
|
+
...options.formatServerArguments(),
|
|
84
|
+
], {
|
|
85
|
+
// Scrcpy server doesn't use stderr,
|
|
86
|
+
// so disable Shell Protocol to simplify processing
|
|
87
|
+
protocols: [AdbSubprocessNoneProtocol],
|
|
88
|
+
});
|
|
89
|
+
const stdout = process.stdout
|
|
90
|
+
.pipeThrough(new DecodeUtf8Stream())
|
|
91
|
+
.pipeThrough(new SplitStringStream('\n'));
|
|
92
|
+
// Read stdout, otherwise `process.exit` won't resolve.
|
|
93
|
+
const output = [];
|
|
94
|
+
const abortController = new AbortController();
|
|
95
|
+
const pipe = stdout
|
|
96
|
+
.pipeTo(new WritableStream({
|
|
97
|
+
write(chunk) {
|
|
98
|
+
output.push(chunk);
|
|
99
|
+
}
|
|
100
|
+
}), {
|
|
101
|
+
signal: abortController.signal,
|
|
102
|
+
preventCancel: true,
|
|
103
|
+
})
|
|
104
|
+
.catch(() => { });
|
|
105
|
+
const result = await Promise.race([
|
|
106
|
+
process.exit,
|
|
107
|
+
connection.getStreams(),
|
|
108
|
+
]);
|
|
109
|
+
if (typeof result === 'number') {
|
|
110
|
+
const error = new Error('scrcpy server exited prematurely');
|
|
111
|
+
error.output = output;
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
abortController.abort();
|
|
115
|
+
await pipe;
|
|
116
|
+
const [videoStream, controlStream] = result;
|
|
117
|
+
return new AdbScrcpyClient(options, process, new ConcatStream(new ArrayToStream(output), stdout), videoStream, controlStream);
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
await process?.kill();
|
|
121
|
+
throw e;
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
connection.dispose();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* This method will modify the given `options`,
|
|
129
|
+
* so don't reuse it elsewhere.
|
|
130
|
+
*/
|
|
131
|
+
static async getEncoders(adb, path, version, options) {
|
|
132
|
+
// Provide an invalid encoder name
|
|
133
|
+
// So the server will return all available encoders
|
|
134
|
+
options.value.encoderName = '_';
|
|
135
|
+
// Disable control for faster connection in 1.22+
|
|
136
|
+
options.value.control = false;
|
|
137
|
+
options.value.sendDeviceMeta = false;
|
|
138
|
+
options.value.sendDummyByte = false;
|
|
139
|
+
// Scrcpy server will open connections, before initializing encoder
|
|
140
|
+
// Thus although an invalid encoder name is given, the start process will success
|
|
141
|
+
const client = await AdbScrcpyClient.start(adb, path, version, options);
|
|
142
|
+
const encoderNameRegex = options.getOutputEncoderNameRegex();
|
|
143
|
+
const encoders = [];
|
|
144
|
+
await client.stdout.pipeTo(new WritableStream({
|
|
145
|
+
write(line) {
|
|
146
|
+
const match = line.match(encoderNameRegex);
|
|
147
|
+
if (match) {
|
|
148
|
+
encoders.push(match[1]);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
}));
|
|
152
|
+
return encoders;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* This method will modify the given `options`,
|
|
156
|
+
* so don't reuse it elsewhere.
|
|
157
|
+
*/
|
|
158
|
+
static async getDisplays(adb, path, version, options) {
|
|
159
|
+
// Similar to `getEncoders`, pass an invalid option and parse the output
|
|
160
|
+
options.value.displayId = -1;
|
|
161
|
+
options.value.control = false;
|
|
162
|
+
options.value.sendDeviceMeta = false;
|
|
163
|
+
options.value.sendDummyByte = false;
|
|
164
|
+
try {
|
|
165
|
+
// Server will exit before opening connections when an invalid display id was given.
|
|
166
|
+
await AdbScrcpyClient.start(adb, path, version, options);
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
if (e instanceof Error) {
|
|
170
|
+
const output = e.output;
|
|
171
|
+
const displayIdRegex = /\s+scrcpy --display (\d+)/;
|
|
172
|
+
const displays = [];
|
|
173
|
+
for (const line of output) {
|
|
174
|
+
const match = line.match(displayIdRegex);
|
|
175
|
+
if (match) {
|
|
176
|
+
displays.push(Number.parseInt(match[1], 10));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return displays;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
throw new Error('failed to get displays');
|
|
183
|
+
}
|
|
184
|
+
process;
|
|
185
|
+
_stdout;
|
|
186
|
+
get stdout() { return this._stdout; }
|
|
187
|
+
get exit() { return this.process.exit; }
|
|
188
|
+
_screenWidth;
|
|
189
|
+
get screenWidth() { return this._screenWidth; }
|
|
190
|
+
_screenHeight;
|
|
191
|
+
get screenHeight() { return this._screenHeight; }
|
|
192
|
+
_videoStream;
|
|
193
|
+
get videoStream() { return this._videoStream; }
|
|
194
|
+
_controlMessageSerializer;
|
|
195
|
+
get controlMessageSerializer() { return this._controlMessageSerializer; }
|
|
196
|
+
_deviceMessageStream;
|
|
197
|
+
get deviceMessageStream() { return this._deviceMessageStream; }
|
|
198
|
+
constructor(options, process, stdout, videoStream, controlStream) {
|
|
199
|
+
this.process = process;
|
|
200
|
+
this._stdout = stdout;
|
|
201
|
+
this._videoStream = videoStream
|
|
202
|
+
.pipeThrough(options.createVideoStreamTransformer())
|
|
203
|
+
.pipeThrough(new InspectStream(packet => {
|
|
204
|
+
if (packet.type === 'configuration') {
|
|
205
|
+
this._screenWidth = packet.data.croppedWidth;
|
|
206
|
+
this._screenHeight = packet.data.croppedHeight;
|
|
207
|
+
}
|
|
208
|
+
}));
|
|
209
|
+
if (controlStream) {
|
|
210
|
+
this._controlMessageSerializer = new ScrcpyControlMessageSerializer(controlStream.writable, options);
|
|
211
|
+
this._deviceMessageStream = controlStream.readable.pipeThrough(new ScrcpyDeviceMessageDeserializeStream());
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async close() {
|
|
215
|
+
await this.process.kill();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=client.js.map
|