Start server
The server is a jar
file, so it's not directly executable. On Android, app_process
is the program to start the system server, all the apps, and standalone Java applications:
Equivalent ADB command
adb shell CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 2.1
With @yume-chan/scrcpy
@yume-chan/scrcpy
only provides APIs to serialize and deserialize Scrcpy protocol messages. It can't start the server directly.
The ScrcpyOptions#serialize
method generates the command line arguments for the specified options:
- JavaScript
- TypeScript
import { ScrcpyOptions2_1 } from "@yume-chan/scrcpy";
const options = ScrcpyOptions2_1({
// options
});
const commandLineArguments = options.serialize();
import { ScrcpyOptions2_1 } from "@yume-chan/scrcpy";
const options = ScrcpyOptions2_1({
// options
});
const commandLineArguments: string[] = options.serialize();
With @yume-chan/adb-scrcpy
Use AdbScrcpyClient.start()
method with an option class to start the server. It automatically sets up port forwarding, launches the server, and connects to it.
- JavaScript
- TypeScript
import { AdbScrcpyClient, AdbScrcpyOptions2_1 } from "@yume-chan/adb-scrcpy";
import { DEFAULT_SERVER_PATH, ScrcpyOptions2_1 } from "@yume-chan/scrcpy";
const options = new AdbScrcpyOptions2_1(
ScrcpyOptions2_1({
// options
}),
);
const client = await AdbScrcpyClient.start(
adb,
DEFAULT_SERVER_PATH,
// If server binary was downloaded manually, must provide the correct version
VERSION,
options,
);
const stdout = client.stdout;
// `undefined` if `video: false` option was given
if (client.videoSteam) {
const { metadata: videoMetadata, stream: videoPacketStream } = await client.videoStream;
}
// `undefined` if `audio: false` option was given
if (client.audioStream) {
const metadata = await client.audioStream;
switch (metadata.type) {
case "disabled":
// Audio not supported by device
break;
case "errored":
// Other error when initializing audio
break;
case "success":
// Audio packets in the codec specified in options
const audioPacketStream = metadata.stream;
break;
}
}
// `undefined` if `control: false` option was given
const controller = client.controller;
const clipboardStream = options.clipboard;
clipboardStream
.pipeTo(
new WritableStream({
write(chunk) {
// Handle device clipboard change
console.log(chunk);
},
}),
)
.catch((error) => {
console.error(error);
});
// to stop the server
client.close();
import { AdbScrcpyClient, AdbScrcpyOptions2_1 } from "@yume-chan/adb-scrcpy";
import { DEFAULT_SERVER_PATH, ScrcpyOptions2_1 } from "@yume-chan/scrcpy";
const options = new AdbScrcpyOptions2_1(
ScrcpyOptions2_1({
// options
}),
);
const client: AdbScrcpyClient = await AdbScrcpyClient.start(
adb,
DEFAULT_SERVER_PATH,
// If server binary was downloaded manually, must provide the correct version
VERSION,
options,
);
const stdout: ReadableStream<string> = client.stdout;
// `undefined` if `video: false` option was given
if (client.videoSteam) {
const { metadata: videoMetadata, stream: videoPacketStream } = await client.videoStream;
}
// `undefined` if `audio: false` option was given
if (client.audioStream) {
const metadata = await client.audioStream;
switch (metadata.type) {
case "disabled":
// Audio not supported by device
break;
case "errored":
// Other error when initializing audio
break;
case "success":
// Audio packets in the codec specified in options
const audioPacketStream: ReadableStream<ScrcpyMediaStreamPacket> = metadata.stream;
break;
}
}
// `undefined` if `control: false` option was given
const controller: ScrcpyControlMessageWriter | undefined = client.controller;
const clipboardStream: ReadableStream<string> = options.clipboard;
clipboardStream
.pipeTo(
new WritableStream<string>({
write(chunk) {
// Handle device clipboard change
console.log(chunk);
},
}),
)
.catch((error) => {
console.error(error);
});
// to stop the server
client.close();
With Tango
Subprocess#spawn can start a process on device:
- JavaScript
- TypeScript
const process = await adb.subprocess.spawn(
"CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 2.1",
);
await process.stdout.pipeThrough(new DecodeUtf8Stream()).pipeTo(
new WritableStream({
write(chunk) {
console.log(chunk);
},
}),
);
import type { Adb } from "@yume-chan/adb";
declare const adb: Adb;
const process = await adb.subprocess.spawn(
"CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 2.1",
);
await process.stdout.pipeThrough(new DecodeUtf8Stream()).pipeTo(
new WritableStream<string>({
write(chunk) {
console.log(chunk);
},
}),
);