@yume-chan/scrcpy 0.0.13 → 0.0.16
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 +45 -0
- package/CHANGELOG.md +25 -1
- package/LICENSE +21 -21
- package/README.md +90 -89
- package/bin/scrcpy-server +0 -0
- package/bin/version.d.ts +1 -1
- package/bin/version.js +1 -1
- package/esm/client.d.ts +14 -2
- package/esm/client.d.ts.map +1 -1
- package/esm/client.js +275 -143
- package/esm/client.js.map +1 -1
- package/esm/connection.d.ts.map +1 -1
- package/esm/connection.js +74 -86
- package/esm/connection.js.map +1 -1
- package/esm/decoder/tinyh264/index.js +48 -48
- package/esm/decoder/tinyh264/index.js.map +1 -1
- package/esm/decoder/tinyh264/wrapper.js +3 -2
- package/esm/decoder/tinyh264/wrapper.js.map +1 -1
- package/esm/decoder/web-codecs/index.js +26 -21
- package/esm/decoder/web-codecs/index.js.map +1 -1
- package/esm/message.d.ts +13 -8
- package/esm/message.d.ts.map +1 -1
- package/esm/message.js +14 -8
- package/esm/message.js.map +1 -1
- package/esm/options/1_16/index.d.ts +8 -4
- package/esm/options/1_16/index.d.ts.map +1 -1
- package/esm/options/1_16/index.js +44 -18
- package/esm/options/1_16/index.js.map +1 -1
- package/esm/options/1_16/sps.js +3 -2
- package/esm/options/1_16/sps.js.map +1 -1
- package/esm/options/1_18.d.ts +3 -2
- package/esm/options/1_18.d.ts.map +1 -1
- package/esm/options/1_18.js +24 -1
- package/esm/options/1_18.js.map +1 -1
- package/esm/options/1_21.js +4 -1
- package/esm/options/1_21.js.map +1 -1
- package/esm/options/1_22.d.ts +3 -3
- package/esm/options/1_22.d.ts.map +1 -1
- package/esm/options/1_22.js +9 -6
- package/esm/options/1_22.js.map +1 -1
- package/esm/options/1_23.js +4 -1
- package/esm/options/1_23.js.map +1 -1
- package/esm/options/1_24.d.ts +9 -0
- package/esm/options/1_24.d.ts.map +1 -0
- package/esm/options/1_24.js +13 -0
- package/esm/options/1_24.js.map +1 -0
- package/esm/options/common.d.ts +2 -0
- package/esm/options/common.d.ts.map +1 -1
- package/esm/options/common.js.map +1 -1
- package/esm/options/index.d.ts +1 -0
- package/esm/options/index.d.ts.map +1 -1
- package/esm/options/index.js +1 -0
- package/esm/options/index.js.map +1 -1
- package/esm/push-server.js +5 -10
- package/esm/push-server.js.map +1 -1
- package/package.json +8 -8
- package/scrcpy.LICENSE +203 -203
- package/scripts/fetch-server.cjs +28 -28
- package/src/client.ts +435 -275
- package/src/codec.ts +35 -35
- package/src/connection.ts +148 -145
- package/src/decoder/index.ts +3 -3
- package/src/decoder/tinyh264/index.ts +112 -112
- package/src/decoder/tinyh264/types.d.ts +137 -137
- package/src/decoder/tinyh264/worker.ts +2 -2
- package/src/decoder/tinyh264/wrapper.ts +89 -89
- package/src/decoder/types.ts +35 -35
- package/src/decoder/web-codecs/index.ts +99 -99
- package/src/index.ts +8 -8
- package/src/message.ts +113 -105
- package/src/options/1_16/index.ts +345 -315
- package/src/options/1_16/sps.ts +300 -300
- package/src/options/1_18.ts +61 -41
- package/src/options/1_21.ts +34 -34
- package/src/options/1_22.ts +78 -80
- package/src/options/1_24.ts +18 -0
- package/src/options/common.ts +66 -63
- package/src/options/index.ts +7 -6
- package/src/push-server.ts +24 -24
- package/src/utils.ts +5 -5
|
@@ -1,315 +1,345 @@
|
|
|
1
|
-
import { StructDeserializeStream, TransformStream, type Adb } from "@yume-chan/adb";
|
|
2
|
-
import Struct
|
|
3
|
-
import type { AndroidCodecLevel, AndroidCodecProfile } from "../../codec.js";
|
|
4
|
-
import { ScrcpyClientConnection, ScrcpyClientForwardConnection, ScrcpyClientReverseConnection, type ScrcpyClientConnectionOptions } from "../../connection.js";
|
|
5
|
-
import { AndroidKeyEventAction, ScrcpyControlMessageType } from "../../message.js";
|
|
6
|
-
import type { ScrcpyBackOrScreenOnEvent1_18 } from "../1_18.js";
|
|
7
|
-
import type { ScrcpyInjectScrollControlMessage1_22 } from "../1_22.js";
|
|
8
|
-
import { toScrcpyOptionValue, type ScrcpyOptions, type ScrcpyOptionValue, type VideoStreamPacket } from "../common.js";
|
|
9
|
-
import { parse_sequence_parameter_set } from "./sps.js";
|
|
10
|
-
|
|
11
|
-
export enum ScrcpyLogLevel {
|
|
12
|
-
Verbose = 'verbose',
|
|
13
|
-
Debug = 'debug',
|
|
14
|
-
Info = 'info',
|
|
15
|
-
Warn = 'warn',
|
|
16
|
-
Error = 'error',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export enum
|
|
20
|
-
Initial = -2,
|
|
21
|
-
Unlocked = -1,
|
|
22
|
-
Portrait = 0,
|
|
23
|
-
Landscape = 1,
|
|
24
|
-
PortraitFlipped = 2,
|
|
25
|
-
LandscapeFlipped = 3,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface CodecOptionsInit {
|
|
29
|
-
profile: AndroidCodecProfile;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
*
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* the
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.
|
|
131
|
-
.
|
|
132
|
-
.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
public
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
1
|
+
import { StructDeserializeStream, TransformStream, type Adb } from "@yume-chan/adb";
|
|
2
|
+
import Struct from "@yume-chan/struct";
|
|
3
|
+
import type { AndroidCodecLevel, AndroidCodecProfile } from "../../codec.js";
|
|
4
|
+
import { ScrcpyClientConnection, ScrcpyClientForwardConnection, ScrcpyClientReverseConnection, type ScrcpyClientConnectionOptions } from "../../connection.js";
|
|
5
|
+
import { AndroidKeyEventAction, ScrcpyControlMessageType, ScrcpySimpleControlMessage } from "../../message.js";
|
|
6
|
+
import type { ScrcpyBackOrScreenOnEvent1_18 } from "../1_18.js";
|
|
7
|
+
import type { ScrcpyInjectScrollControlMessage1_22 } from "../1_22.js";
|
|
8
|
+
import { toScrcpyOptionValue, type ScrcpyOptions, type ScrcpyOptionValue, type VideoStreamPacket } from "../common.js";
|
|
9
|
+
import { parse_sequence_parameter_set } from "./sps.js";
|
|
10
|
+
|
|
11
|
+
export enum ScrcpyLogLevel {
|
|
12
|
+
Verbose = 'verbose',
|
|
13
|
+
Debug = 'debug',
|
|
14
|
+
Info = 'info',
|
|
15
|
+
Warn = 'warn',
|
|
16
|
+
Error = 'error',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export enum ScrcpyVideoOrientation {
|
|
20
|
+
Initial = -2,
|
|
21
|
+
Unlocked = -1,
|
|
22
|
+
Portrait = 0,
|
|
23
|
+
Landscape = 1,
|
|
24
|
+
PortraitFlipped = 2,
|
|
25
|
+
LandscapeFlipped = 3,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface CodecOptionsInit {
|
|
29
|
+
profile: AndroidCodecProfile;
|
|
30
|
+
level: AndroidCodecLevel;
|
|
31
|
+
|
|
32
|
+
iFrameInterval: number;
|
|
33
|
+
repeatPreviousFrameAfter: number;
|
|
34
|
+
maxPtsGapToEncoder: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function toDashCase(input: string) {
|
|
38
|
+
return input.replace(/([A-Z])/g, '-$1').toLowerCase();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const CODEC_OPTION_TYPES: Partial<Record<keyof CodecOptionsInit, 'long' | 'float' | 'string'>> = {
|
|
42
|
+
repeatPreviousFrameAfter: 'long',
|
|
43
|
+
maxPtsGapToEncoder: 'long',
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export class CodecOptions implements ScrcpyOptionValue {
|
|
47
|
+
public value: Partial<CodecOptionsInit>;
|
|
48
|
+
|
|
49
|
+
public constructor(value: Partial<CodecOptionsInit>) {
|
|
50
|
+
this.value = value;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public toOptionValue(): string | undefined {
|
|
54
|
+
const entries = Object.entries(this.value)
|
|
55
|
+
.filter(([key, value]) => value !== undefined);
|
|
56
|
+
|
|
57
|
+
if (entries.length === 0) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return entries
|
|
62
|
+
.map(([key, value]) => {
|
|
63
|
+
const type = CODEC_OPTION_TYPES[key as keyof CodecOptionsInit];
|
|
64
|
+
return `${toDashCase(key)}${type ? `:${type}` : ''}=${value}`;
|
|
65
|
+
})
|
|
66
|
+
.join(',');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ScrcpyOptionsInit1_16 {
|
|
71
|
+
logLevel: ScrcpyLogLevel;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The maximum value of both width and height.
|
|
75
|
+
*/
|
|
76
|
+
maxSize: number;
|
|
77
|
+
|
|
78
|
+
bitRate: number;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 0 for unlimited.
|
|
82
|
+
*
|
|
83
|
+
* @default 0
|
|
84
|
+
*/
|
|
85
|
+
maxFps: number;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The orientation of the video stream.
|
|
89
|
+
*
|
|
90
|
+
* It will not keep the device screen in specific orientation,
|
|
91
|
+
* only the captured video will in this orientation.
|
|
92
|
+
*/
|
|
93
|
+
lockVideoOrientation: ScrcpyVideoOrientation;
|
|
94
|
+
|
|
95
|
+
tunnelForward: boolean;
|
|
96
|
+
|
|
97
|
+
crop: string;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Send PTS so that the client may record properly
|
|
101
|
+
*
|
|
102
|
+
* Note: When `sendFrameMeta: false` is specified,
|
|
103
|
+
* `onChangeEncoding` event won't fire and `onVideoData` event doesn't
|
|
104
|
+
* merge sps/pps frame and first video frame. Which means you can't use
|
|
105
|
+
* the shipped decoders to render the video
|
|
106
|
+
* (You can still record the stream into a file).
|
|
107
|
+
*
|
|
108
|
+
* @default true
|
|
109
|
+
*/
|
|
110
|
+
sendFrameMeta: boolean;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @default true
|
|
114
|
+
*/
|
|
115
|
+
control: boolean;
|
|
116
|
+
|
|
117
|
+
displayId: number;
|
|
118
|
+
|
|
119
|
+
showTouches: boolean;
|
|
120
|
+
|
|
121
|
+
stayAwake: boolean;
|
|
122
|
+
|
|
123
|
+
codecOptions: CodecOptions;
|
|
124
|
+
|
|
125
|
+
encoderName: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const VideoPacket =
|
|
129
|
+
new Struct()
|
|
130
|
+
.uint64('pts')
|
|
131
|
+
.uint32('size')
|
|
132
|
+
.uint8Array('data', { lengthField: 'size' });
|
|
133
|
+
|
|
134
|
+
export const NO_PTS = BigInt(1) << BigInt(63);
|
|
135
|
+
|
|
136
|
+
export const ScrcpyBackOrScreenOnEvent1_16 =
|
|
137
|
+
ScrcpySimpleControlMessage;
|
|
138
|
+
|
|
139
|
+
export const ScrcpyInjectScrollControlMessage1_16 =
|
|
140
|
+
new Struct()
|
|
141
|
+
.fields(ScrcpySimpleControlMessage)
|
|
142
|
+
.uint32('pointerX')
|
|
143
|
+
.uint32('pointerY')
|
|
144
|
+
.uint16('screenWidth')
|
|
145
|
+
.uint16('screenHeight')
|
|
146
|
+
.int32('scrollX')
|
|
147
|
+
.int32('scrollY');
|
|
148
|
+
|
|
149
|
+
export class ScrcpyOptions1_16<T extends ScrcpyOptionsInit1_16 = ScrcpyOptionsInit1_16> implements ScrcpyOptions<T> {
|
|
150
|
+
public value: Partial<T>;
|
|
151
|
+
|
|
152
|
+
public constructor(value: Partial<ScrcpyOptionsInit1_16>) {
|
|
153
|
+
if (new.target === ScrcpyOptions1_16 &&
|
|
154
|
+
value.logLevel === ScrcpyLogLevel.Verbose) {
|
|
155
|
+
value.logLevel = ScrcpyLogLevel.Debug;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (new.target === ScrcpyOptions1_16 &&
|
|
159
|
+
value.lockVideoOrientation === ScrcpyVideoOrientation.Initial) {
|
|
160
|
+
value.lockVideoOrientation = ScrcpyVideoOrientation.Unlocked;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.value = value as Partial<T>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
protected getArgumentOrder(): (keyof T)[] {
|
|
167
|
+
return [
|
|
168
|
+
'logLevel',
|
|
169
|
+
'maxSize',
|
|
170
|
+
'bitRate',
|
|
171
|
+
'maxFps',
|
|
172
|
+
'lockVideoOrientation',
|
|
173
|
+
'tunnelForward',
|
|
174
|
+
'crop',
|
|
175
|
+
'sendFrameMeta',
|
|
176
|
+
'control',
|
|
177
|
+
'displayId',
|
|
178
|
+
'showTouches',
|
|
179
|
+
'stayAwake',
|
|
180
|
+
'codecOptions',
|
|
181
|
+
'encoderName',
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
protected getDefaultValue(): T {
|
|
186
|
+
return {
|
|
187
|
+
logLevel: ScrcpyLogLevel.Debug,
|
|
188
|
+
maxSize: 0,
|
|
189
|
+
bitRate: 8_000_000,
|
|
190
|
+
maxFps: 0,
|
|
191
|
+
lockVideoOrientation: ScrcpyVideoOrientation.Unlocked,
|
|
192
|
+
tunnelForward: false,
|
|
193
|
+
crop: '-',
|
|
194
|
+
sendFrameMeta: true,
|
|
195
|
+
control: true,
|
|
196
|
+
displayId: 0,
|
|
197
|
+
showTouches: false,
|
|
198
|
+
stayAwake: false,
|
|
199
|
+
codecOptions: new CodecOptions({}),
|
|
200
|
+
encoderName: '-',
|
|
201
|
+
} as T;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public formatServerArguments(): string[] {
|
|
205
|
+
const defaults = this.getDefaultValue();
|
|
206
|
+
return this.getArgumentOrder()
|
|
207
|
+
.map(key => toScrcpyOptionValue(this.value[key] || defaults[key], '-'));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public createConnection(adb: Adb): ScrcpyClientConnection {
|
|
211
|
+
const options: ScrcpyClientConnectionOptions = {
|
|
212
|
+
// Old scrcpy connection always have control stream no matter what the option is
|
|
213
|
+
control: true,
|
|
214
|
+
sendDummyByte: true,
|
|
215
|
+
sendDeviceMeta: true,
|
|
216
|
+
};
|
|
217
|
+
if (this.value.tunnelForward) {
|
|
218
|
+
return new ScrcpyClientForwardConnection(adb, options);
|
|
219
|
+
} else {
|
|
220
|
+
return new ScrcpyClientReverseConnection(adb, options);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public getOutputEncoderNameRegex(): RegExp {
|
|
225
|
+
return /\s+scrcpy --encoder-name '(.*?)'/;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
public createVideoStreamTransformer(): TransformStream<Uint8Array, VideoStreamPacket> {
|
|
229
|
+
// Optimized path for video frames only
|
|
230
|
+
if (this.value.sendFrameMeta === false) {
|
|
231
|
+
return new TransformStream({
|
|
232
|
+
transform(chunk, controller) {
|
|
233
|
+
controller.enqueue({
|
|
234
|
+
type: 'frame',
|
|
235
|
+
data: chunk,
|
|
236
|
+
});
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
let header: Uint8Array | undefined;
|
|
242
|
+
|
|
243
|
+
let deserializeStream = new StructDeserializeStream(VideoPacket);
|
|
244
|
+
return {
|
|
245
|
+
writable: deserializeStream.writable,
|
|
246
|
+
readable: deserializeStream.readable.pipeThrough(new TransformStream({
|
|
247
|
+
transform(packet, controller) {
|
|
248
|
+
if (packet.pts === NO_PTS) {
|
|
249
|
+
const sequenceParameterSet = parse_sequence_parameter_set(packet.data.slice().buffer);
|
|
250
|
+
|
|
251
|
+
const {
|
|
252
|
+
profile_idc: profileIndex,
|
|
253
|
+
constraint_set: constraintSet,
|
|
254
|
+
level_idc: levelIndex,
|
|
255
|
+
pic_width_in_mbs_minus1,
|
|
256
|
+
pic_height_in_map_units_minus1,
|
|
257
|
+
frame_mbs_only_flag,
|
|
258
|
+
frame_crop_left_offset,
|
|
259
|
+
frame_crop_right_offset,
|
|
260
|
+
frame_crop_top_offset,
|
|
261
|
+
frame_crop_bottom_offset,
|
|
262
|
+
} = sequenceParameterSet;
|
|
263
|
+
|
|
264
|
+
const encodedWidth = (pic_width_in_mbs_minus1 + 1) * 16;
|
|
265
|
+
const encodedHeight = (pic_height_in_map_units_minus1 + 1) * (2 - frame_mbs_only_flag) * 16;
|
|
266
|
+
const cropLeft = frame_crop_left_offset * 2;
|
|
267
|
+
const cropRight = frame_crop_right_offset * 2;
|
|
268
|
+
const cropTop = frame_crop_top_offset * 2;
|
|
269
|
+
const cropBottom = frame_crop_bottom_offset * 2;
|
|
270
|
+
|
|
271
|
+
const croppedWidth = encodedWidth - cropLeft - cropRight;
|
|
272
|
+
const croppedHeight = encodedHeight - cropTop - cropBottom;
|
|
273
|
+
|
|
274
|
+
header = packet.data;
|
|
275
|
+
controller.enqueue({
|
|
276
|
+
type: 'configuration',
|
|
277
|
+
data: {
|
|
278
|
+
profileIndex,
|
|
279
|
+
constraintSet,
|
|
280
|
+
levelIndex,
|
|
281
|
+
encodedWidth,
|
|
282
|
+
encodedHeight,
|
|
283
|
+
cropLeft,
|
|
284
|
+
cropRight,
|
|
285
|
+
cropTop,
|
|
286
|
+
cropBottom,
|
|
287
|
+
croppedWidth,
|
|
288
|
+
croppedHeight,
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
let frameData: Uint8Array;
|
|
295
|
+
if (header) {
|
|
296
|
+
frameData = new Uint8Array(header.byteLength + packet.data.byteLength);
|
|
297
|
+
frameData.set(header);
|
|
298
|
+
frameData.set(packet.data, header.byteLength);
|
|
299
|
+
header = undefined;
|
|
300
|
+
} else {
|
|
301
|
+
frameData = packet.data;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
controller.enqueue({
|
|
305
|
+
type: 'frame',
|
|
306
|
+
pts: packet.pts,
|
|
307
|
+
data: frameData,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}))
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
public getControlMessageTypes(): ScrcpyControlMessageType[] {
|
|
315
|
+
return [
|
|
316
|
+
/* 0 */ ScrcpyControlMessageType.InjectKeycode,
|
|
317
|
+
/* 1 */ ScrcpyControlMessageType.InjectText,
|
|
318
|
+
/* 2 */ ScrcpyControlMessageType.InjectTouch,
|
|
319
|
+
/* 3 */ ScrcpyControlMessageType.InjectScroll,
|
|
320
|
+
/* 4 */ ScrcpyControlMessageType.BackOrScreenOn,
|
|
321
|
+
/* 5 */ ScrcpyControlMessageType.ExpandNotificationPanel,
|
|
322
|
+
/* 6 */ ScrcpyControlMessageType.CollapseNotificationPanel,
|
|
323
|
+
/* 7 */ ScrcpyControlMessageType.GetClipboard,
|
|
324
|
+
/* 8 */ ScrcpyControlMessageType.SetClipboard,
|
|
325
|
+
/* 9 */ ScrcpyControlMessageType.SetScreenPowerMode,
|
|
326
|
+
/* 10 */ ScrcpyControlMessageType.RotateDevice,
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
public serializeBackOrScreenOnControlMessage(
|
|
331
|
+
message: ScrcpyBackOrScreenOnEvent1_18,
|
|
332
|
+
) {
|
|
333
|
+
if (message.action === AndroidKeyEventAction.Down) {
|
|
334
|
+
return ScrcpyBackOrScreenOnEvent1_16.serialize(message);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
public serializeInjectScrollControlMessage(
|
|
341
|
+
message: ScrcpyInjectScrollControlMessage1_22,
|
|
342
|
+
): Uint8Array {
|
|
343
|
+
return ScrcpyInjectScrollControlMessage1_16.serialize(message);
|
|
344
|
+
}
|
|
345
|
+
}
|