@yume-chan/scrcpy 0.0.16 → 0.0.18
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 +36 -3
- package/CHANGELOG.md +21 -4
- package/LICENSE +1 -1
- package/README.md +291 -37
- package/bin/scrcpy-server +0 -0
- package/bin/version.d.ts +1 -1
- package/bin/version.js +1 -1
- package/esm/adb/client.d.ts +41 -0
- package/esm/adb/client.d.ts.map +1 -0
- package/esm/adb/client.js +243 -0
- package/esm/adb/client.js.map +1 -0
- package/esm/adb/connection.d.ts +47 -0
- package/esm/adb/connection.d.ts.map +1 -0
- package/esm/{connection.js → adb/connection.js} +35 -31
- 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 +24 -0
- package/esm/adb/options/types.d.ts.map +1 -0
- package/esm/adb/options/types.js +37 -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/back-or-screen-on.d.ts +3 -0
- package/esm/control/back-or-screen-on.d.ts.map +1 -0
- package/esm/control/back-or-screen-on.js +2 -0
- package/esm/control/back-or-screen-on.js.map +1 -0
- package/esm/control/hover-helper.d.ts +18 -0
- package/esm/control/hover-helper.d.ts.map +1 -0
- package/esm/control/hover-helper.js +44 -0
- package/esm/control/hover-helper.js.map +1 -0
- package/esm/control/index.d.ts +12 -0
- package/esm/control/index.d.ts.map +1 -0
- package/esm/control/index.js +12 -0
- package/esm/control/index.js.map +1 -0
- package/esm/control/inject-keycode.d.ts +61 -0
- package/esm/control/inject-keycode.d.ts.map +1 -0
- package/esm/control/inject-keycode.js +62 -0
- package/esm/control/inject-keycode.js.map +1 -0
- package/esm/control/inject-scroll.d.ts +3 -0
- package/esm/control/inject-scroll.d.ts.map +1 -0
- package/esm/control/inject-scroll.js +2 -0
- package/esm/control/inject-scroll.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 +38 -0
- package/esm/control/inject-touch.d.ts.map +1 -0
- package/esm/control/inject-touch.js +63 -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 +34 -0
- package/esm/control/serializer.d.ts.map +1 -0
- package/esm/control/serializer.js +79 -0
- package/esm/control/serializer.js.map +1 -0
- package/esm/control/set-clipboard.d.ts +3 -0
- package/esm/control/set-clipboard.d.ts.map +1 -0
- package/esm/control/set-clipboard.js +2 -0
- package/esm/control/set-clipboard.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/device-message/ack-clipboard.d.ts +9 -0
- package/esm/device-message/ack-clipboard.d.ts.map +1 -0
- package/esm/device-message/ack-clipboard.js +6 -0
- package/esm/device-message/ack-clipboard.js.map +1 -0
- 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 +5 -0
- package/esm/device-message/index.d.ts.map +1 -0
- package/esm/device-message/index.js +5 -0
- package/esm/device-message/index.js.map +1 -0
- package/esm/device-message/stream.d.ts +8 -0
- package/esm/device-message/stream.d.ts.map +1 -0
- package/esm/device-message/stream.js +20 -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 +20 -0
- package/esm/options/1_16/codec-options.d.ts.map +1 -0
- package/esm/options/1_16/codec-options.js +26 -0
- package/esm/options/1_16/codec-options.js.map +1 -0
- package/esm/options/1_16/h264-configuration.d.ts +49 -0
- package/esm/options/1_16/h264-configuration.d.ts.map +1 -0
- package/esm/options/1_16/h264-configuration.js +414 -0
- package/esm/options/1_16/h264-configuration.js.map +1 -0
- package/esm/options/1_16/index.d.ts +4 -110
- package/esm/options/1_16/index.d.ts.map +1 -1
- package/esm/options/1_16/index.js +4 -226
- package/esm/options/1_16/index.js.map +1 -1
- package/esm/options/1_16/options.d.ts +94 -0
- package/esm/options/1_16/options.d.ts.map +1 -0
- package/esm/options/1_16/options.js +190 -0
- package/esm/options/1_16/options.js.map +1 -0
- package/esm/options/1_16/scroll.d.ts +27 -0
- package/esm/options/1_16/scroll.d.ts.map +1 -0
- package/esm/options/1_16/scroll.js +56 -0
- package/esm/options/1_16/scroll.js.map +1 -0
- package/esm/options/1_16/sps.d.ts +1 -1
- package/esm/options/1_16/sps.d.ts.map +1 -1
- package/esm/options/1_16/sps.js +25 -17
- package/esm/options/1_16/sps.js.map +1 -1
- 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 +7 -7
- package/esm/options/1_18.js.map +1 -1
- package/esm/options/1_21.d.ts +13 -2
- package/esm/options/1_21.d.ts.map +1 -1
- package/esm/options/1_21.js +14 -3
- package/esm/options/1_21.js.map +1 -1
- package/esm/options/1_22/index.d.ts +3 -0
- package/esm/options/1_22/index.d.ts.map +1 -0
- package/esm/options/1_22/index.js +3 -0
- package/esm/options/1_22/index.js.map +1 -0
- package/esm/options/1_22/options.d.ts +29 -0
- package/esm/options/1_22/options.d.ts.map +1 -0
- package/esm/options/1_22/options.js +26 -0
- package/esm/options/1_22/options.js.map +1 -0
- package/esm/options/1_22/scroll.d.ts +17 -0
- package/esm/options/1_22/scroll.d.ts.map +1 -0
- package/esm/options/1_22/scroll.js +15 -0
- package/esm/options/1_22/scroll.js.map +1 -0
- package/esm/options/1_23.d.ts +5 -5
- package/esm/options/1_23.d.ts.map +1 -1
- package/esm/options/1_23.js +7 -6
- 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/1_25/index.d.ts +3 -0
- package/esm/options/1_25/index.d.ts.map +1 -0
- package/esm/options/1_25/index.js +3 -0
- package/esm/options/1_25/index.js.map +1 -0
- package/esm/options/1_25/options.d.ts +6 -0
- package/esm/options/1_25/options.d.ts.map +1 -0
- package/esm/options/1_25/options.js +8 -0
- package/esm/options/1_25/options.js.map +1 -0
- package/esm/options/1_25/scroll.d.ts +19 -0
- package/esm/options/1_25/scroll.d.ts.map +1 -0
- package/esm/options/1_25/scroll.js +33 -0
- package/esm/options/1_25/scroll.js.map +1 -0
- package/esm/options/index.d.ts +5 -4
- package/esm/options/index.d.ts.map +1 -1
- package/esm/options/index.js +5 -4
- package/esm/options/index.js.map +1 -1
- package/esm/options/types.d.ts +47 -0
- package/esm/options/types.d.ts.map +1 -0
- package/esm/options/types.js +18 -0
- package/esm/options/types.js.map +1 -0
- package/package.json +32 -25
- package/scripts/fetch-server.cjs +19 -9
- package/src/adb/client.ts +345 -0
- package/src/adb/connection.ts +192 -0
- package/src/adb/index.ts +3 -0
- package/src/adb/options/1_16.ts +30 -0
- package/src/adb/options/1_22.ts +26 -0
- package/src/adb/options/index.ts +3 -0
- package/src/adb/options/types.ts +75 -0
- package/src/control/back-or-screen-on.ts +4 -0
- package/src/control/hover-helper.ts +56 -0
- package/src/control/index.ts +11 -0
- package/src/control/inject-keycode.ts +72 -0
- package/src/control/inject-scroll.ts +4 -0
- package/src/control/inject-text.ts +12 -0
- package/src/control/inject-touch.ts +78 -0
- package/src/control/rotate-device.ts +10 -0
- package/src/control/serializer.ts +151 -0
- package/src/control/set-clipboard.ts +4 -0
- package/src/control/set-screen-power-mode.ts +17 -0
- package/src/control/type.ts +17 -0
- package/src/device-message/ack-clipboard.ts +10 -0
- package/src/device-message/clipboard.ts +11 -0
- package/src/device-message/index.ts +4 -0
- package/src/device-message/stream.ts +29 -0
- package/src/device-message/type.ts +5 -0
- package/src/index.ts +3 -6
- package/src/options/1_16/codec-options.ts +55 -0
- package/src/options/1_16/h264-configuration.ts +485 -0
- package/src/options/1_16/index.ts +4 -345
- package/src/options/1_16/options.ts +339 -0
- package/src/options/1_16/scroll.ts +76 -0
- package/src/options/1_18.ts +24 -12
- package/src/options/1_21.ts +34 -6
- package/src/options/1_22/index.ts +2 -0
- package/src/options/1_22/options.ts +58 -0
- package/src/options/1_22/scroll.ts +26 -0
- package/src/options/1_23.ts +33 -19
- package/src/options/1_24.ts +3 -2
- package/src/options/1_25/index.ts +2 -0
- package/src/options/1_25/options.ts +12 -0
- package/src/options/1_25/scroll.ts +52 -0
- package/src/options/index.ts +5 -4
- package/src/options/types.ts +102 -0
- package/tsconfig.build.json +3 -0
- package/tsconfig.build.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/decoder/index.d.ts +0 -4
- package/esm/decoder/index.d.ts.map +0 -1
- package/esm/decoder/index.js +0 -4
- package/esm/decoder/index.js.map +0 -1
- package/esm/decoder/tinyh264/index.d.ts +0 -20
- package/esm/decoder/tinyh264/index.d.ts.map +0 -1
- package/esm/decoder/tinyh264/index.js +0 -86
- package/esm/decoder/tinyh264/index.js.map +0 -1
- package/esm/decoder/tinyh264/worker.d.ts +0 -2
- package/esm/decoder/tinyh264/worker.d.ts.map +0 -1
- package/esm/decoder/tinyh264/worker.js +0 -3
- package/esm/decoder/tinyh264/worker.js.map +0 -1
- package/esm/decoder/tinyh264/wrapper.d.ts +0 -21
- package/esm/decoder/tinyh264/wrapper.d.ts.map +0 -1
- package/esm/decoder/tinyh264/wrapper.js +0 -68
- package/esm/decoder/tinyh264/wrapper.js.map +0 -1
- package/esm/decoder/types.d.ts +0 -28
- package/esm/decoder/types.d.ts.map +0 -1
- package/esm/decoder/types.js +0 -2
- package/esm/decoder/types.js.map +0 -1
- package/esm/decoder/web-codecs/index.d.ts +0 -22
- package/esm/decoder/web-codecs/index.d.ts.map +0 -1
- package/esm/decoder/web-codecs/index.js +0 -81
- package/esm/decoder/web-codecs/index.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/1_22.d.ts +0 -43
- package/esm/options/1_22.d.ts.map +0 -1
- package/esm/options/1_22.js +0 -43
- package/esm/options/1_22.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 +0 -16
- 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/connection.ts +0 -148
- 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/options/1_16/sps.ts +0 -300
- package/src/options/1_22.ts +0 -78
- package/src/options/common.ts +0 -66
- package/src/push-server.ts +0 -24
- package/src/utils.ts +0 -5
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Struct, { NumberFieldDefinition, NumberFieldType, } from "@yume-chan/struct";
|
|
2
|
+
import { clamp, ScrcpyControlMessageType, } from "../../control/index.js";
|
|
3
|
+
export const ScrcpyFloatToInt16NumberType = {
|
|
4
|
+
size: 2,
|
|
5
|
+
signed: true,
|
|
6
|
+
deserialize(array, littleEndian) {
|
|
7
|
+
const value = NumberFieldType.Int16.deserialize(array, littleEndian);
|
|
8
|
+
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/server/src/main/java/com/genymobile/scrcpy/Binary.java#L34
|
|
9
|
+
return value === 0x7fff ? 1 : value / 0x8000;
|
|
10
|
+
},
|
|
11
|
+
serialize(dataView, offset, value, littleEndian) {
|
|
12
|
+
// https://github.com/Genymobile/scrcpy/blob/1f138aef41de651668043b32c4effc2d4adbfc44/app/src/util/binary.h#L65
|
|
13
|
+
value = clamp(value, -1, 1);
|
|
14
|
+
value = value === 1 ? 0x7fff : value * 0x8000;
|
|
15
|
+
NumberFieldType.Int16.serialize(dataView, offset, value, littleEndian);
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
const ScrcpyFloatToInt16FieldDefinition = new NumberFieldDefinition(ScrcpyFloatToInt16NumberType);
|
|
19
|
+
export const ScrcpyInjectScrollControlMessage1_25 = new Struct()
|
|
20
|
+
.uint8("type", ScrcpyControlMessageType.InjectScroll)
|
|
21
|
+
.uint32("pointerX")
|
|
22
|
+
.uint32("pointerY")
|
|
23
|
+
.uint16("screenWidth")
|
|
24
|
+
.uint16("screenHeight")
|
|
25
|
+
.field("scrollX", ScrcpyFloatToInt16FieldDefinition)
|
|
26
|
+
.field("scrollY", ScrcpyFloatToInt16FieldDefinition)
|
|
27
|
+
.int32("buttons");
|
|
28
|
+
export class ScrcpyScrollController1_25 {
|
|
29
|
+
serializeScrollMessage(message) {
|
|
30
|
+
return ScrcpyInjectScrollControlMessage1_25.serialize(message);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=scroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll.js","sourceRoot":"","sources":["../../../src/options/1_25/scroll.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EACX,qBAAqB,EACrB,eAAe,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACH,KAAK,EACL,wBAAwB,GAE3B,MAAM,wBAAwB,CAAC;AAGhC,MAAM,CAAC,MAAM,4BAA4B,GAAoB;IACzD,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,IAAI;IACZ,WAAW,CAAC,KAAK,EAAE,YAAY;QAC3B,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QACrE,gJAAgJ;QAChJ,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;IACjD,CAAC;IACD,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY;QAC3C,+GAA+G;QAC/G,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,KAAK,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;QAC9C,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC3E,CAAC;CACJ,CAAC;AAEF,MAAM,iCAAiC,GAAG,IAAI,qBAAqB,CAC/D,4BAA4B,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,oCAAoC,GAAG,IAAI,MAAM,EAAE;KAC3D,KAAK,CAAC,MAAM,EAAE,wBAAwB,CAAC,YAAqB,CAAC;KAC7D,MAAM,CAAC,UAAU,CAAC;KAClB,MAAM,CAAC,UAAU,CAAC;KAClB,MAAM,CAAC,aAAa,CAAC;KACrB,MAAM,CAAC,cAAc,CAAC;KACtB,KAAK,CAAC,SAAS,EAAE,iCAAiC,CAAC;KACnD,KAAK,CAAC,SAAS,EAAE,iCAAiC,CAAC;KACnD,KAAK,CAAC,SAAS,CAAC,CAAC;AAKtB,MAAM,OAAO,0BAA0B;IACnC,sBAAsB,CAClB,OAAyC;QAEzC,OAAO,oCAAoC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACnE,CAAC;CACJ"}
|
package/esm/options/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export * from './1_16/index.js';
|
|
2
2
|
export * from './1_18.js';
|
|
3
3
|
export * from './1_21.js';
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
4
|
+
export * from "./1_22/index.js";
|
|
5
|
+
export * from "./1_23.js";
|
|
6
|
+
export * from "./1_24.js";
|
|
7
|
+
export * from "./1_25/index.js";
|
|
8
|
+
export * from "./types.js";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/options/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/options/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
|
package/esm/options/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export * from './1_16/index.js';
|
|
2
2
|
export * from './1_18.js';
|
|
3
3
|
export * from './1_21.js';
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
4
|
+
export * from "./1_22/index.js";
|
|
5
|
+
export * from "./1_23.js";
|
|
6
|
+
export * from "./1_24.js";
|
|
7
|
+
export * from "./1_25/index.js";
|
|
8
|
+
export * from "./types.js";
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/esm/options/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/options/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/options/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type TransformStream } from "@yume-chan/stream-extra";
|
|
2
|
+
import { type ScrcpyBackOrScreenOnControlMessage, type ScrcpyControlMessageType, type ScrcpySetClipboardControlMessage } from "../control/index.js";
|
|
3
|
+
import { type ScrcpyScrollController } from "./1_16/scroll.js";
|
|
4
|
+
export declare const DEFAULT_SERVER_PATH = "/data/local/tmp/scrcpy-server.jar";
|
|
5
|
+
export interface ScrcpyOptionValue {
|
|
6
|
+
toOptionValue(): string | undefined;
|
|
7
|
+
}
|
|
8
|
+
export declare function isScrcpyOptionValue(value: unknown): value is ScrcpyOptionValue;
|
|
9
|
+
export declare function toScrcpyOptionValue<T>(value: unknown, empty: T): string | T;
|
|
10
|
+
export interface H264Configuration {
|
|
11
|
+
profileIndex: number;
|
|
12
|
+
constraintSet: number;
|
|
13
|
+
levelIndex: number;
|
|
14
|
+
encodedWidth: number;
|
|
15
|
+
encodedHeight: number;
|
|
16
|
+
cropLeft: number;
|
|
17
|
+
cropRight: number;
|
|
18
|
+
cropTop: number;
|
|
19
|
+
cropBottom: number;
|
|
20
|
+
croppedWidth: number;
|
|
21
|
+
croppedHeight: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ScrcpyVideoStreamConfigurationPacket {
|
|
24
|
+
type: "configuration";
|
|
25
|
+
sequenceParameterSet: Uint8Array;
|
|
26
|
+
pictureParameterSet: Uint8Array;
|
|
27
|
+
data: H264Configuration;
|
|
28
|
+
}
|
|
29
|
+
export interface ScrcpyVideoStreamFramePacket {
|
|
30
|
+
type: "frame";
|
|
31
|
+
keyframe?: boolean | undefined;
|
|
32
|
+
pts?: bigint | undefined;
|
|
33
|
+
data: Uint8Array;
|
|
34
|
+
}
|
|
35
|
+
export type ScrcpyVideoStreamPacket = ScrcpyVideoStreamConfigurationPacket | ScrcpyVideoStreamFramePacket;
|
|
36
|
+
export interface ScrcpyOptions<T extends object> {
|
|
37
|
+
value: Partial<T>;
|
|
38
|
+
getDefaultValue(): T;
|
|
39
|
+
formatServerArguments(): string[];
|
|
40
|
+
getOutputEncoderNameRegex(): RegExp;
|
|
41
|
+
createVideoStreamTransformer(): TransformStream<Uint8Array, ScrcpyVideoStreamPacket>;
|
|
42
|
+
getControlMessageTypes(): ScrcpyControlMessageType[];
|
|
43
|
+
serializeBackOrScreenOnControlMessage(message: ScrcpyBackOrScreenOnControlMessage): Uint8Array | undefined;
|
|
44
|
+
serializeSetClipboardControlMessage(message: ScrcpySetClipboardControlMessage): Uint8Array;
|
|
45
|
+
getScrollController(): ScrcpyScrollController;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/options/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EACH,KAAK,kCAAkC,EACvC,KAAK,wBAAwB,EAC7B,KAAK,gCAAgC,EACxC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,eAAO,MAAM,mBAAmB,sCAAsC,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAC9B,aAAa,IAAI,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,wBAAgB,mBAAmB,CAC/B,KAAK,EAAE,OAAO,GACf,KAAK,IAAI,iBAAiB,CAO5B;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAW3E;AAED,MAAM,WAAW,iBAAiB;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAEtB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IAEnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oCAAoC;IACjD,IAAI,EAAE,eAAe,CAAC;IACtB,oBAAoB,EAAE,UAAU,CAAC;IACjC,mBAAmB,EAAE,UAAU,CAAC;IAChC,IAAI,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA4B;IACzC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,MAAM,uBAAuB,GAC7B,oCAAoC,GACpC,4BAA4B,CAAC;AAEnC,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM;IAC3C,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAElB,eAAe,IAAI,CAAC,CAAC;IAErB,qBAAqB,IAAI,MAAM,EAAE,CAAC;IAElC,yBAAyB,IAAI,MAAM,CAAC;IAEpC,4BAA4B,IAAI,eAAe,CAC3C,UAAU,EACV,uBAAuB,CAC1B,CAAC;IAEF,sBAAsB,IAAI,wBAAwB,EAAE,CAAC;IAErD,qCAAqC,CACjC,OAAO,EAAE,kCAAkC,GAC5C,UAAU,GAAG,SAAS,CAAC;IAE1B,mCAAmC,CAC/B,OAAO,EAAE,gCAAgC,GAC1C,UAAU,CAAC;IAEd,mBAAmB,IAAI,sBAAsB,CAAC;CACjD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const DEFAULT_SERVER_PATH = "/data/local/tmp/scrcpy-server.jar";
|
|
2
|
+
export function isScrcpyOptionValue(value) {
|
|
3
|
+
return (typeof value === "object" &&
|
|
4
|
+
value !== null &&
|
|
5
|
+
"toOptionValue" in value &&
|
|
6
|
+
typeof value.toOptionValue === "function");
|
|
7
|
+
}
|
|
8
|
+
export function toScrcpyOptionValue(value, empty) {
|
|
9
|
+
if (isScrcpyOptionValue(value)) {
|
|
10
|
+
value = value.toOptionValue();
|
|
11
|
+
}
|
|
12
|
+
// `value` may become `undefined` after `toOptionValue`
|
|
13
|
+
if (value === undefined) {
|
|
14
|
+
return empty;
|
|
15
|
+
}
|
|
16
|
+
return String(value);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/options/types.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,mBAAmB,GAAG,mCAAmC,CAAC;AAMvE,MAAM,UAAU,mBAAmB,CAC/B,KAAc;IAEd,OAAO,CACH,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,eAAe,IAAI,KAAK;QACxB,OAAO,KAAK,CAAC,aAAa,KAAK,UAAU,CAC5C,CAAC;AACN,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAI,KAAc,EAAE,KAAQ;IAC3D,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE;QAC5B,KAAK,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;KACjC;IAED,uDAAuD;IACvD,IAAI,KAAK,KAAK,SAAS,EAAE;QACrB,OAAO,KAAK,CAAC;KAChB;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/scrcpy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "TypeScript implementation of Scrcpy.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adb",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"email": "cnsimonchan@live.com",
|
|
14
14
|
"url": "https://chensi.moe/blog"
|
|
15
15
|
},
|
|
16
|
-
"homepage": "https://github.com/yume-chan/ya-webadb/tree/
|
|
16
|
+
"homepage": "https://github.com/yume-chan/ya-webadb/tree/main/packages/scrcpy#readme",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
19
|
"url": "git+https://github.com/yume-chan/ya-webadb.git",
|
|
@@ -29,33 +29,40 @@
|
|
|
29
29
|
"main": "esm/index.js",
|
|
30
30
|
"types": "esm/index.d.ts",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@yume-chan/
|
|
33
|
-
"@yume-chan/
|
|
34
|
-
"@yume-chan/
|
|
35
|
-
"@yume-chan/struct": "^0.0.
|
|
36
|
-
"tslib": "^2.
|
|
32
|
+
"@yume-chan/async": "^2.2.0",
|
|
33
|
+
"@yume-chan/event": "^0.0.18",
|
|
34
|
+
"@yume-chan/stream-extra": "^0.0.18",
|
|
35
|
+
"@yume-chan/struct": "^0.0.18",
|
|
36
|
+
"tslib": "^2.4.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@jest/globals": "^
|
|
40
|
-
"@
|
|
41
|
-
"@yume-chan/
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
39
|
+
"@jest/globals": "^29.3.1",
|
|
40
|
+
"@yume-chan/adb": "^0.0.18",
|
|
41
|
+
"@yume-chan/eslint-config": "^1.0.0",
|
|
42
|
+
"@yume-chan/tsconfig": "^1.0.0",
|
|
43
|
+
"cross-env": "^7.0.3",
|
|
44
|
+
"eslint": "^8.31.0",
|
|
45
|
+
"gh-release-fetch": "^3.0.2",
|
|
46
|
+
"jest": "^29.3.1",
|
|
47
|
+
"ts-jest": "^29.0.4",
|
|
48
|
+
"typescript": "^4.9.4"
|
|
48
49
|
},
|
|
49
50
|
"peerDependencies": {
|
|
50
|
-
"@
|
|
51
|
-
"
|
|
52
|
-
"yuv-buffer": "^1.0.0",
|
|
53
|
-
"yuv-canvas": "^1.2.7"
|
|
51
|
+
"@yume-chan/adb": "^0.0.18",
|
|
52
|
+
"gh-release-fetch": "^3.0.2"
|
|
54
53
|
},
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"@yume-chan/adb": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"gh-release-fetch": {
|
|
59
|
+
"optional": true
|
|
60
|
+
}
|
|
59
61
|
},
|
|
60
|
-
"
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsc -b tsconfig.build.json",
|
|
64
|
+
"build:watch": "tsc -b tsconfig.build.json",
|
|
65
|
+
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage",
|
|
66
|
+
"lint": "eslint src/**/*.ts --fix"
|
|
67
|
+
}
|
|
61
68
|
}
|
package/scripts/fetch-server.cjs
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { fetchVersion } = require(
|
|
4
|
-
const path = require(
|
|
5
|
-
const fs = require(
|
|
3
|
+
const { fetchVersion } = require("gh-release-fetch");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs").promises;
|
|
6
6
|
|
|
7
7
|
(async () => {
|
|
8
8
|
const serverVersion = process.argv[2];
|
|
9
|
-
|
|
9
|
+
if (!serverVersion) {
|
|
10
|
+
console.log("Usage: fetch-scrcpy-server <version>");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
console.log(`Downloading Scrcpy server binary version ${serverVersion}...`);
|
|
15
|
+
const binFolder = path.resolve(__dirname, "..", "bin");
|
|
12
16
|
|
|
13
17
|
await fetchVersion({
|
|
14
|
-
repository:
|
|
18
|
+
repository: "Genymobile/scrcpy",
|
|
15
19
|
version: `v${serverVersion}`,
|
|
16
20
|
package: `scrcpy-server-v${serverVersion}`,
|
|
17
21
|
destination: binFolder,
|
|
@@ -20,9 +24,15 @@ const fs = require('fs').promises;
|
|
|
20
24
|
|
|
21
25
|
await fs.rename(
|
|
22
26
|
path.resolve(binFolder, `scrcpy-server-v${serverVersion}`),
|
|
23
|
-
path.resolve(binFolder,
|
|
27
|
+
path.resolve(binFolder, "scrcpy-server")
|
|
24
28
|
);
|
|
25
29
|
|
|
26
|
-
fs.writeFile(
|
|
27
|
-
|
|
30
|
+
fs.writeFile(
|
|
31
|
+
path.resolve(binFolder, "version.js"),
|
|
32
|
+
`export default '${serverVersion}';`
|
|
33
|
+
);
|
|
34
|
+
fs.writeFile(
|
|
35
|
+
path.resolve(binFolder, "version.d.ts"),
|
|
36
|
+
`export default '${serverVersion}';`
|
|
37
|
+
);
|
|
28
38
|
})();
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AdbSubprocessNoneProtocol,
|
|
3
|
+
type Adb,
|
|
4
|
+
type AdbSubprocessProtocol,
|
|
5
|
+
type AdbSync,
|
|
6
|
+
} from "@yume-chan/adb";
|
|
7
|
+
import {
|
|
8
|
+
AbortController,
|
|
9
|
+
DecodeUtf8Stream,
|
|
10
|
+
InspectStream,
|
|
11
|
+
ReadableStream,
|
|
12
|
+
SplitStringStream,
|
|
13
|
+
WrapWritableStream,
|
|
14
|
+
WritableStream,
|
|
15
|
+
type ReadableStreamDefaultController,
|
|
16
|
+
type ReadableStreamDefaultReader,
|
|
17
|
+
type ReadableWritablePair,
|
|
18
|
+
} from "@yume-chan/stream-extra";
|
|
19
|
+
|
|
20
|
+
import { ScrcpyControlMessageSerializer } from "../control/index.js";
|
|
21
|
+
import {
|
|
22
|
+
ScrcpyDeviceMessageDeserializeStream,
|
|
23
|
+
type ScrcpyDeviceMessage,
|
|
24
|
+
} from "../device-message/index.js";
|
|
25
|
+
import {
|
|
26
|
+
DEFAULT_SERVER_PATH,
|
|
27
|
+
type ScrcpyVideoStreamPacket,
|
|
28
|
+
} from "../options/index.js";
|
|
29
|
+
|
|
30
|
+
import { type AdbScrcpyOptions } from "./options/index.js";
|
|
31
|
+
|
|
32
|
+
class ArrayToStream<T> extends ReadableStream<T> {
|
|
33
|
+
private array!: T[];
|
|
34
|
+
private index = 0;
|
|
35
|
+
|
|
36
|
+
constructor(array: T[]) {
|
|
37
|
+
super({
|
|
38
|
+
start: async () => {
|
|
39
|
+
await Promise.resolve();
|
|
40
|
+
this.array = array;
|
|
41
|
+
},
|
|
42
|
+
pull: (controller) => {
|
|
43
|
+
if (this.index < this.array.length) {
|
|
44
|
+
controller.enqueue(this.array[this.index]!);
|
|
45
|
+
this.index += 1;
|
|
46
|
+
} else {
|
|
47
|
+
controller.close();
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
class ConcatStream<T> extends ReadableStream<T> {
|
|
55
|
+
private streams!: ReadableStream<T>[];
|
|
56
|
+
private index = 0;
|
|
57
|
+
private reader!: ReadableStreamDefaultReader<T>;
|
|
58
|
+
|
|
59
|
+
constructor(...streams: ReadableStream<T>[]) {
|
|
60
|
+
super({
|
|
61
|
+
start: async (controller) => {
|
|
62
|
+
await Promise.resolve();
|
|
63
|
+
|
|
64
|
+
this.streams = streams;
|
|
65
|
+
this.advance(controller);
|
|
66
|
+
},
|
|
67
|
+
pull: async (controller) => {
|
|
68
|
+
const result = await this.reader.read();
|
|
69
|
+
if (!result.done) {
|
|
70
|
+
controller.enqueue(result.value);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.advance(controller);
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private advance(controller: ReadableStreamDefaultController<T>) {
|
|
79
|
+
if (this.index < this.streams.length) {
|
|
80
|
+
this.reader = this.streams[this.index]!.getReader();
|
|
81
|
+
this.index += 1;
|
|
82
|
+
} else {
|
|
83
|
+
controller.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export class ScrcpyExitedError extends Error {
|
|
89
|
+
public output: string[];
|
|
90
|
+
|
|
91
|
+
public constructor(output: string[]) {
|
|
92
|
+
super("scrcpy server exited prematurely");
|
|
93
|
+
this.output = output;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export class AdbScrcpyClient {
|
|
98
|
+
public static pushServer(adb: Adb, path = DEFAULT_SERVER_PATH) {
|
|
99
|
+
let sync!: AdbSync;
|
|
100
|
+
return new WrapWritableStream<Uint8Array>({
|
|
101
|
+
async start() {
|
|
102
|
+
sync = await adb.sync();
|
|
103
|
+
return sync.write(path);
|
|
104
|
+
},
|
|
105
|
+
async close() {
|
|
106
|
+
await sync.dispose();
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public static async start(
|
|
112
|
+
adb: Adb,
|
|
113
|
+
path: string,
|
|
114
|
+
version: string,
|
|
115
|
+
options: AdbScrcpyOptions<object>
|
|
116
|
+
) {
|
|
117
|
+
const connection = options.createConnection(adb);
|
|
118
|
+
let process: AdbSubprocessProtocol | undefined;
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
await connection.initialize();
|
|
122
|
+
|
|
123
|
+
process = await adb.subprocess.spawn(
|
|
124
|
+
[
|
|
125
|
+
// cspell: disable-next-line
|
|
126
|
+
`CLASSPATH=${path}`,
|
|
127
|
+
"app_process",
|
|
128
|
+
/* unused */ "/",
|
|
129
|
+
"com.genymobile.scrcpy.Server",
|
|
130
|
+
version,
|
|
131
|
+
...options.formatServerArguments(),
|
|
132
|
+
],
|
|
133
|
+
{
|
|
134
|
+
// Scrcpy server doesn't use stderr,
|
|
135
|
+
// so disable Shell Protocol to simplify processing
|
|
136
|
+
protocols: [AdbSubprocessNoneProtocol],
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const stdout = process.stdout
|
|
141
|
+
.pipeThrough(new DecodeUtf8Stream())
|
|
142
|
+
.pipeThrough(new SplitStringStream("\n"));
|
|
143
|
+
|
|
144
|
+
// Read stdout, otherwise `process.exit` won't resolve.
|
|
145
|
+
const output: string[] = [];
|
|
146
|
+
const abortController = new AbortController();
|
|
147
|
+
const pipe = stdout
|
|
148
|
+
.pipeTo(
|
|
149
|
+
new WritableStream({
|
|
150
|
+
write(chunk) {
|
|
151
|
+
output.push(chunk);
|
|
152
|
+
},
|
|
153
|
+
}),
|
|
154
|
+
{
|
|
155
|
+
signal: abortController.signal,
|
|
156
|
+
preventCancel: true,
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
.catch((e) => {
|
|
160
|
+
void e;
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const result = await Promise.race([
|
|
164
|
+
process.exit,
|
|
165
|
+
connection.getStreams(),
|
|
166
|
+
]);
|
|
167
|
+
|
|
168
|
+
if (typeof result === "number") {
|
|
169
|
+
throw new ScrcpyExitedError(output);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
abortController.abort();
|
|
173
|
+
await pipe;
|
|
174
|
+
|
|
175
|
+
const [videoStream, controlStream] = result;
|
|
176
|
+
return new AdbScrcpyClient(
|
|
177
|
+
options,
|
|
178
|
+
process,
|
|
179
|
+
new ConcatStream(new ArrayToStream(output), stdout),
|
|
180
|
+
videoStream,
|
|
181
|
+
controlStream
|
|
182
|
+
);
|
|
183
|
+
} catch (e) {
|
|
184
|
+
await process?.kill();
|
|
185
|
+
throw e;
|
|
186
|
+
} finally {
|
|
187
|
+
connection.dispose();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* This method will modify the given `options`,
|
|
193
|
+
* so don't reuse it elsewhere.
|
|
194
|
+
*/
|
|
195
|
+
public static async getEncoders(
|
|
196
|
+
adb: Adb,
|
|
197
|
+
path: string,
|
|
198
|
+
version: string,
|
|
199
|
+
options: AdbScrcpyOptions<object>
|
|
200
|
+
): Promise<string[]> {
|
|
201
|
+
Object.assign(options.value, {
|
|
202
|
+
// Provide an invalid encoder name
|
|
203
|
+
// So the server will return all available encoders
|
|
204
|
+
encoderName: "_",
|
|
205
|
+
// Disable control for faster connection in 1.22+
|
|
206
|
+
control: false,
|
|
207
|
+
sendDeviceMeta: false,
|
|
208
|
+
sendDummyByte: false,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Scrcpy server will open connections, before initializing encoder
|
|
212
|
+
// Thus although an invalid encoder name is given, the start process will success
|
|
213
|
+
const client = await AdbScrcpyClient.start(adb, path, version, options);
|
|
214
|
+
|
|
215
|
+
const encoderNameRegex = options.getOutputEncoderNameRegex();
|
|
216
|
+
const encoders: string[] = [];
|
|
217
|
+
await client.stdout.pipeTo(
|
|
218
|
+
new WritableStream({
|
|
219
|
+
write(line) {
|
|
220
|
+
const match = line.match(encoderNameRegex);
|
|
221
|
+
if (match) {
|
|
222
|
+
encoders.push(match[1]!);
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
return encoders;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* This method will modify the given `options`,
|
|
233
|
+
* so don't reuse it elsewhere.
|
|
234
|
+
*/
|
|
235
|
+
public static async getDisplays(
|
|
236
|
+
adb: Adb,
|
|
237
|
+
path: string,
|
|
238
|
+
version: string,
|
|
239
|
+
options: AdbScrcpyOptions<object>
|
|
240
|
+
): Promise<number[]> {
|
|
241
|
+
Object.assign(options.value, {
|
|
242
|
+
// Similar to `getEncoders`, pass an invalid option and parse the output
|
|
243
|
+
displayId: -1,
|
|
244
|
+
// Disable control for faster connection in 1.22+
|
|
245
|
+
control: false,
|
|
246
|
+
sendDeviceMeta: false,
|
|
247
|
+
sendDummyByte: false,
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
// Server will exit before opening connections when an invalid display id was given.
|
|
252
|
+
await AdbScrcpyClient.start(adb, path, version, options);
|
|
253
|
+
} catch (e) {
|
|
254
|
+
if (e instanceof ScrcpyExitedError) {
|
|
255
|
+
const displayIdRegex = /\s+scrcpy --display (\d+)/;
|
|
256
|
+
const displays: number[] = [];
|
|
257
|
+
for (const line of e.output) {
|
|
258
|
+
const match = line.match(displayIdRegex);
|
|
259
|
+
if (match) {
|
|
260
|
+
displays.push(Number.parseInt(match[1]!, 10));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return displays;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
throw new Error("failed to get displays");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private process: AdbSubprocessProtocol;
|
|
271
|
+
|
|
272
|
+
private _stdout: ReadableStream<string>;
|
|
273
|
+
public get stdout() {
|
|
274
|
+
return this._stdout;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
public get exit() {
|
|
278
|
+
return this.process.exit;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private _screenWidth: number | undefined;
|
|
282
|
+
public get screenWidth() {
|
|
283
|
+
return this._screenWidth;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
private _screenHeight: number | undefined;
|
|
287
|
+
public get screenHeight() {
|
|
288
|
+
return this._screenHeight;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private _videoStream: ReadableStream<ScrcpyVideoStreamPacket>;
|
|
292
|
+
public get videoStream() {
|
|
293
|
+
return this._videoStream;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
private _controlMessageSerializer:
|
|
297
|
+
| ScrcpyControlMessageSerializer
|
|
298
|
+
| undefined;
|
|
299
|
+
public get controlMessageSerializer() {
|
|
300
|
+
return this._controlMessageSerializer;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private _deviceMessageStream:
|
|
304
|
+
| ReadableStream<ScrcpyDeviceMessage>
|
|
305
|
+
| undefined;
|
|
306
|
+
public get deviceMessageStream() {
|
|
307
|
+
return this._deviceMessageStream;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
public constructor(
|
|
311
|
+
options: AdbScrcpyOptions<object>,
|
|
312
|
+
process: AdbSubprocessProtocol,
|
|
313
|
+
stdout: ReadableStream<string>,
|
|
314
|
+
videoStream: ReadableStream<Uint8Array>,
|
|
315
|
+
controlStream: ReadableWritablePair<Uint8Array, Uint8Array> | undefined
|
|
316
|
+
) {
|
|
317
|
+
this.process = process;
|
|
318
|
+
this._stdout = stdout;
|
|
319
|
+
|
|
320
|
+
this._videoStream = videoStream
|
|
321
|
+
.pipeThrough(options.createVideoStreamTransformer())
|
|
322
|
+
.pipeThrough(
|
|
323
|
+
new InspectStream((packet) => {
|
|
324
|
+
if (packet.type === "configuration") {
|
|
325
|
+
this._screenWidth = packet.data.croppedWidth;
|
|
326
|
+
this._screenHeight = packet.data.croppedHeight;
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
if (controlStream) {
|
|
332
|
+
this._controlMessageSerializer = new ScrcpyControlMessageSerializer(
|
|
333
|
+
controlStream.writable,
|
|
334
|
+
options
|
|
335
|
+
);
|
|
336
|
+
this._deviceMessageStream = controlStream.readable.pipeThrough(
|
|
337
|
+
new ScrcpyDeviceMessageDeserializeStream()
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
public async close() {
|
|
343
|
+
await this.process.kill();
|
|
344
|
+
}
|
|
345
|
+
}
|