Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit af7ae1ec authored by Simon Chan's avatar Simon Chan
Browse files

feat(scrcpy): adopt 1.23

fix #386
parent 1f14dcc2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
    "version": "0.1.0",
    "private": true,
    "scripts": {
        "postinstall": "fetch-scrcpy-server 1.22",
        "postinstall": "fetch-scrcpy-server 1.23",
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
+7 −13
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import { CommandBar, Dialog, Dropdown, ICommandBarItemProps, Icon, IconButton, I
import { useId } from "@fluentui/react-hooks";
import { ADB_SYNC_MAX_PACKET_SIZE, ChunkStream, InspectStream, ReadableStream, WritableStream } from '@yume-chan/adb';
import { EventEmitter } from "@yume-chan/event";
import { AndroidKeyCode, AndroidKeyEventAction, AndroidMotionEventAction, CodecOptions, DEFAULT_SERVER_PATH, H264Decoder, H264DecoderConstructor, pushServer, ScrcpyClient, ScrcpyLogLevel, ScrcpyOptions1_22, ScrcpyScreenOrientation, TinyH264Decoder, VideoStreamPacket, WebCodecsDecoder } from "@yume-chan/scrcpy";
import { AndroidKeyCode, AndroidKeyEventAction, AndroidMotionEventAction, CodecOptions, DEFAULT_SERVER_PATH, H264Decoder, H264DecoderConstructor, pushServer, ScrcpyClient, ScrcpyLogLevel, ScrcpyOptions1_23, ScrcpyScreenOrientation, TinyH264Decoder, WebCodecsDecoder, type VideoStreamPacket } from "@yume-chan/scrcpy";
import SCRCPY_SERVER_VERSION from '@yume-chan/scrcpy/bin/version';
import { action, autorun, makeAutoObservable, observable, runInAction } from "mobx";
import { observer } from "mobx-react-lite";
@@ -433,12 +433,16 @@ class ScrcpyPageState {
                globalState.device,
                DEFAULT_SERVER_PATH,
                SCRCPY_SERVER_VERSION,
                new ScrcpyOptions1_22({
                new ScrcpyOptions1_23({
                    logLevel: ScrcpyLogLevel.Debug,
                    bitRate: 4_000_000,
                    tunnelForward: this.tunnelForward,
                    sendDeviceMeta: false,
                    sendDummyByte: false,
                    control: false,
                    // Don't cleanup when getting encoders,
                    // so doesn't need to push server binary again
                    cleanup: false,
                })
            );
            if (encoders.length === 0) {
@@ -449,23 +453,13 @@ class ScrcpyPageState {
                this.encoders = encoders;
            });

            // Run scrcpy once will delete the server file
            // Re-push it
            await new ReadableStream<Uint8Array>({
                start(controller) {
                    controller.enqueue(serverBuffer);
                    controller.close();
                },
            })
                .pipeTo(pushServer(globalState.device));

            const factory = this.selectedDecoder.factory;
            const decoder = new factory();
            runInAction(() => {
                this.decoder = decoder;
            });

            const options = new ScrcpyOptions1_22({
            const options = new ScrcpyOptions1_23({
                logLevel: ScrcpyLogLevel.Debug,
                maxSize: this.resolution,
                bitRate: this.bitRate,
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ Scrcpy server has no backward compatibility on options input format. Currently t
| 1.18~1.20 | `ScrcpyOptions1_18` |
| 1.21      | `ScrcpyOptions1_21` |
| 1.22      | `ScrcpyOptions1_22` |
| 1.23      | `ScrcpyOptions1_23` |

You must use the correct type according to the server version.

+3 −3
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ export class ScrcpyClient {
        adb: Adb,
        options: ScrcpyOptions<any>,
        process: AdbSubprocessProtocol,
        videoStream: AdbBufferedStream,
        videoStream: AdbSocket,
        controlStream: AdbSocket | undefined,
    ) {
        this._adb = adb;
@@ -155,8 +155,8 @@ export class ScrcpyClient {
                },
            }));

        this._videoStream = options
            .parseVideoStream(videoStream)
        this._videoStream = videoStream.readable
            .pipeThrough(options.createVideoStreamTransformer())
            .pipeThrough(new InspectStream(packet => {
                if (packet.type === 'configuration') {
                    this._screenWidth = packet.data.croppedWidth;
+33 −11
Original line number Diff line number Diff line
import { Adb, AdbBufferedStream, AdbSocket } from "@yume-chan/adb";
import type { Adb, AdbSocket } from "@yume-chan/adb";
import type { Disposable } from "@yume-chan/event";
import type { ValueOrPromise } from "@yume-chan/struct";
import { delay } from "./utils.js";
@@ -29,7 +29,7 @@ export abstract class ScrcpyClientConnection implements Disposable {

    public initialize(): ValueOrPromise<void> { }

    public abstract getStreams(): ValueOrPromise<[videoSteam: AdbBufferedStream, controlStream: AdbSocket | undefined]>;
    public abstract getStreams(): ValueOrPromise<[videoSteam: AdbSocket, controlStream: AdbSocket | undefined]>;

    public dispose(): void { }
}
@@ -50,26 +50,39 @@ export class ScrcpyClientForwardConnection extends ScrcpyClientConnection {
        throw new Error(`Can't connect to server after 100 retries`);
    }

    private async connectVideoStream(): Promise<AdbBufferedStream> {
        const socket = await this.connectAndRetry();
        const stream = new AdbBufferedStream(socket);
    private async connectVideoStream(): Promise<AdbSocket> {
        const stream = await this.connectAndRetry();
        if (this.options.sendDummyByte) {
            const reader = stream.readable.getReader();
            const { done, value } = await reader.read();
            // server will write a `0` to signal connection success
            await stream.read(1);
            if (done || value.byteLength !== 1 || value[0] !== 0) {
                throw new Error('Unexpected response from server');
            }
            reader.releaseLock();
        }
        return stream;
    }

    public async getStreams(): Promise<[videoSteam: AdbBufferedStream, controlStream: AdbSocket | undefined]> {
    public async getStreams(): Promise<[videoSteam: AdbSocket, controlStream: AdbSocket | undefined]> {
        const videoStream = await this.connectVideoStream();

        let controlStream: AdbSocket | undefined;
        if (this.options.control) {
            controlStream = await this.connectAndRetry();
        }

        // Server only writes device meta after control socket is connected (if enabled)
        if (this.options.sendDeviceMeta) {
            const reader = videoStream.readable.getReader();
            const { done, value } = await reader.read();
            // 64 bytes device name + 2 bytes video width + 2 bytes video height
            await videoStream.read(64 + 2 + 2);
            if (done || value.byteLength !== 64 + 2 + 2) {
                throw new Error('Unexpected response from server');
            }
            reader.releaseLock();
        }

        return [videoStream, controlStream];
    }
}
@@ -101,16 +114,25 @@ export class ScrcpyClientReverseConnection extends ScrcpyClientConnection {
        return (await this.streams.read()).value!;
    }

    public async getStreams(): Promise<[videoSteam: AdbBufferedStream, controlStream: AdbSocket | undefined]> {
        const videoStream = new AdbBufferedStream(await this.accept());
    public async getStreams(): Promise<[videoSteam: AdbSocket, controlStream: AdbSocket | undefined]> {
        const videoStream = await this.accept();

        let controlStream: AdbSocket | undefined;
        if (this.options.control) {
            controlStream = await this.accept();
        }

        // Server only writes device meta after control socket is connected (if enabled)
        if (this.options.sendDeviceMeta) {
            const reader = videoStream.readable.getReader();
            const { done, value } = await reader.read();
            // 64 bytes device name + 2 bytes video width + 2 bytes video height
            await videoStream.read(64 + 2 + 2);
            if (done || value.byteLength !== 64 + 2 + 2) {
                throw new Error('Unexpected response from server');
            }
            reader.releaseLock();
        }

        return [videoStream, controlStream];
    }

Loading