Skip to content

Commit

Permalink
update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
yume-chan committed Dec 12, 2023
1 parent 7dd69a6 commit c20c090
Show file tree
Hide file tree
Showing 15 changed files with 2,456 additions and 737 deletions.
27 changes: 27 additions & 0 deletions docs/scrcpy/create-options.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
sidebar_position: 4
---

# Create options

Scrcpy protocol changes over time, and are usually not backward compatible. In Tango's implementation, the options actually have two proposals:

* It defines which server options are available
* It normalize the behavior between different server versions

It's important to use the correct options class for the server version you're using. Using an incorrect version almost always results in a error.

## Available versions

| Version | Type |
| --------- | ------------------- |
| 1.16 | `ScrcpyOptions1_16` |
| 1.17 | `ScrcpyOptions1_17` |
| 1.18~1.20 | `ScrcpyOptions1_18` |
| 1.21 | `ScrcpyOptions1_21` |
| 1.22 | `ScrcpyOptions1_22` |
| 1.23 | `ScrcpyOptions1_23` |
| 1.24 | `ScrcpyOptions1_24` |
| 1.25 | `ScrcpyOptions1_25` |
| 2.0 | `ScrcpyOptions2_0` |
| 2.1 | `ScrcpyOptions2_1` |
48 changes: 48 additions & 0 deletions docs/scrcpy/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
sidebar_position: 1
---

# Quick Start

[Scrcpy](https://github.com/Genymobile/scrcpy) is an open-source tool to mirror Android screen to desktop, and control it from desktop. It has two parts:

* A client written in C++: It uses SDL for cross-platform display and input, and FFMpeg for video encoding.
* A server written in Java: It runs on Android devices, and uses Android system APIs to capture screen and inject input events. The server is started by client using ADB, thus having much more privileges than a regular app.

Tango provides a TypeScript implementation of the client, so that it can run in browsers and Node.js. It's fully compatible with the original Scrcpy server, so latest features and bug fixes are available immediately.

The implementation are separated into multiple packages:

## `@yume-chan/scrcpy`

The core implementation of Scrcpy protocol. This package alone can't start the server, nor render the video and audio. It only provides low-level APIs to serialize and deserialize Scrcpy protocol messages.

It doesn't use any Web or Node.js APIs, so it can be used in any JavaScript environment.

## `@yume-chan/adb-scrcpy`

Combining `@yume-chan/scrcpy` and [Tango ADB](../tango/index.md), this package provides high-level APIs to start the server, establish the connection, and control the device.

It also doesn't use any Web or Node.js APIs, nor providing any UI components. You can create your own UI in your favorite framework using the APIs provided by this package.

## `@yume-chan/fetch-scrcpy-server`

A script to download Scrcpy server binary from official GitHub releases.

This package can be integrated into your NPM scripts to help you prepare the server binary.

## `@yume-chan/scrcpy-decoder-tinyh264`

Decode and render H.264 streams in Web browsers using TinyH264, the (now deprecated and removed) Android H.264 software decoder.

The video stream will be decoded into YUV frames on CPU, then converted to RGB using a WebGL shader (using GPU). It's slow, and only supports H.264 main profile at level 4, but works on most browsers.

## `@yume-chan/scrcpy-decoder-webcodecs`

Decode and render H.264 streams in Web browsers using [WebCodecs API](https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API), the new Web standard for hardware-accelerated video decoding.

It's fast, uses less hardware resources, and supports more H.264 profiles and levels. However, it's only available in recent versions of Chrome and Safari.

## `@yume-chan/pcm-player`

Play raw PCM audio in Web browsers using Web Audio API. It can help you play the audio stream from Scrcpy server.
140 changes: 140 additions & 0 deletions docs/scrcpy/prepare-server.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
sidebar_position: 2
---

# Prepare the server binary

Scrcpy server is a Java application that runs on Android devices. Tango uses the unmodified, official Scrcpy server binary, so you don't need to build it yourself.

You can download the server binary from [official GitHub releases](https://github.com/Genymobile/scrcpy/releases) and copy into your project, use `@yume-chan/fetch-scrcpy-server` package to automate the process, or build the server yourself.

## Embed manually downloaded or built server

Depends on your runtime, bundler and framework, you may need to consume `server.bin` differently.

For frontend meta frameworks, usually there are two ways to include a binary file:

1. Put it in `public` folder, and reference it using a fixed URL
2. Import it from a JavaScript source file and let the bundler handle it

We recommend the second approach, because it's more flexible, less error-prone, and has better cache control.

Assume you have downloaded the server binary to `src/server.bin`, and you want to embed it into your app.

<Tabs className="runtime-tabs" groupId="bundler">
<TabItem label="Webpack 5" value="webpack-5">

```ts transpile
const url = new URL("./server.bin", import.meta.url);
const server: ArrayBuffer = await fetch(url)
.then((res) => res.arrayBuffer())
```

</TabItem>
<TabItem label="Vite" value="vite">

```ts transpile
const url = new URL("./server.bin", import.meta.url);
const server: ArrayBuffer = await fetch(url)
.then((res) => res.arrayBuffer())
```

</TabItem>
<TabItem label="Node.js" value="node">

```ts transpile
import fs from "fs/promises";

const url = new URL("./server.bin", import.meta.url);
const server: Buffer = fs.readFile(url)
```

</TabItem>
</Tabs>

## Use `@yume-chan/fetch-scrcpy-server`

```sh npm2yarn
npm i -D @yume-chan/fetch-scrcpy-server
```

Usage:

```sh
npx fetch-scrcpy-server <version>
```

For example:

```sh
npx fetch-scrcpy-server 2.1
```

The server binary is written to `server.bin` and the version is written to `version.js` in this package's root (in your `node_modules`).

Importing this package will give you two variables:

* `BIN`: A URL to the server binary. It can be used in `fetch` or `fs.readFile` similar to the manual approach.
* `VERSION`: A string containing the downloaded server version. It's required when starting the server.

<Tabs className="runtime-tabs" groupId="bundler">
<TabItem label="Webpack 5" value="webpack-5">

```ts transpile
import { BIN, VERSION } from "@yume-chan/fetch-scrcpy-server";

console.log(VERSION); // 2.1
const server: ArrayBuffer = await fetch(BIN)
.then((res) => res.arrayBuffer())
```

</TabItem>
<TabItem label="Vite" value="vite">

```ts transpile
import { BIN, VERSION } from "@yume-chan/fetch-scrcpy-server";

console.log(VERSION); // 2.1
const server: ArrayBuffer = await fetch(BIN)
.then((res) => res.arrayBuffer())
```

</TabItem>
<TabItem label="Node.js" value="node">

```ts transpile
import { BIN, VERSION } from "@yume-chan/fetch-scrcpy-server";

console.log(VERSION); // 2.1
const server: Buffer = fs.readFile(BIN)
```

</TabItem>
</Tabs>

### Run the script automatically

After installing the package, you can add it to your NPM scripts, so every time you run `npm install`, the script will be executed automatically.

```json
{
"scripts": {
"postinstall": "fetch-scrcpy-server 2.1"
}
}
```

## Build the server

The easiest way to modify and build the server is to use [Android Studio](https://developer.android.com/studio).

1. Clone Scrcpy
```sh
git clone https://github.com/Genymobile/scrcpy.git
```

2. Open the root folder in Android Studio
3. (Optional) Change `Build Variant` to `release` from `Build` -> `Select Build Variant` menu item
4. Select `Build` -> `Make Project` menu item

The server binary will be written to `server/build/outputs/apk/debug/server-debug.apk` (`debug` variant) or `server/build/outputs/apk/release/server-release-unsigned.apk` (`release` variant).
7 changes: 7 additions & 0 deletions docs/scrcpy/push-server.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
sidebar_position: 3
---

# Push and start server

Before version 2.3, the path of Scrcpy server binary is hard-coded in the server itself. So you must push it to the exact path on the device, otherwise the clean up steps won't work.
2 changes: 1 addition & 1 deletion docs/tango/commands/_category_.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
position: 6
position: 7
label: 'Commands'
collapsed: false
2 changes: 1 addition & 1 deletion docs/tango/custom-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ As mentioned before, the main function of `AdbTransport` is the `connect` method

Other fields:

- `serial`: The serial number of the device. `Adb` class doesn't use it, but it's useful for logging.
- `serial`: The serial number of the device. It's not used by Tango, but it helps you to identify the device.
- `maxPayloadSize`: The maximum payload size of the device. `AdbSync#write` will split data into multiple packets if it's larger than this value. If you don't know this value, use 4KB.
- `banner`: ADB banner returned from the device. It contains the list of ADB features the device supports, which is important for many command to choose the correct behavior.
- `disconnected`: A promise that resolves when the transport is disconnected.
Expand Down
5 changes: 1 addition & 4 deletions docs/tango/daemon/connect-device.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
sidebar_position: 5
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

# Handshake and authenticate

## Authenticate with device
Expand All @@ -23,7 +20,7 @@ const transport: AdbDaemonTransport = await AdbDaemonTransport.authenticate({

:::info

The `serial` field is for bookkeeping purpose. It can be any string if you don't need it.
The `serial` field is not used by Tango, but it helps you to identify the device.

:::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ sidebar_position: 2
Currently no browser supports this API.
</TabItem>
<TabItem value="node" label="Node.js">
Install `@types/node` package for code suggestions and type checking of Node.js APIs:

```sh npm2yarn
npm i -D @types/node
```

The following code converts Node.js's `net.Socket` to a `TCPSocket`:

```ts transpile
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 7
sidebar_position: 8
---

# Forward tunnel
Expand Down
2 changes: 1 addition & 1 deletion docs/tango/server/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Gets all connected devices.

:::info

Some lazy manufacturers use the same `serial` for all devices. It's possible that multiple devices with the same `serial` will be returned.
Some lazy manufacturers use the same `serial` for all devices. It's possible that multiple devices with the same `serial` will be returned. So it's recommended to use `transportId` to identify devices.

:::

Expand Down
File renamed without changes.
6 changes: 6 additions & 0 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ export default {
position: "left",
label: "Tango",
},
{
type: "doc",
docId: "scrcpy/index",
position: "left",
label: "Scrcpy",
},
{
type: "doc",
docId: "internal/index",
Expand Down
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "^3.0.0",
"@docusaurus/preset-classic": "^3.0.0",
"@docusaurus/remark-plugin-npm2yarn": "^3.0.0",
"@docusaurus/theme-mermaid": "^3.0.0",
"@docusaurus/core": "^3.0.1",
"@docusaurus/preset-classic": "^3.0.1",
"@docusaurus/remark-plugin-npm2yarn": "^3.0.1",
"@docusaurus/theme-mermaid": "^3.0.1",
"@easyops-cn/docusaurus-search-local": "^0.38.1",
"@mdx-js/react": "^3.0.0",
"@svgr/webpack": "^8.1.0",
"clsx": "^2.0.0",
"file-loader": "^6.2.0",
"prettier": "^3.1.0",
"prettier": "^3.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.3.2",
"typescript": "^5.3.3",
"url-loader": "^4.1.1"
},
"browserslist": {
Expand All @@ -42,12 +42,12 @@
]
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.0.0",
"@docusaurus/theme-classic": "^3.0.0",
"@docusaurus/tsconfig": "^3.0.0",
"@docusaurus/types": "^3.0.0",
"@docusaurus/module-type-aliases": "^3.0.1",
"@docusaurus/theme-classic": "^3.0.1",
"@docusaurus/tsconfig": "^3.0.1",
"@docusaurus/types": "^3.0.1",
"@types/mdast": "^4.0.3",
"@types/node": "^20.10.1",
"@types/node": "^20.10.4",
"mini-svg-data-uri": "^1.3.3",
"plantuml-encoder": "^1.4.0",
"prism-react-renderer": "^2.3.0",
Expand Down
Loading

0 comments on commit c20c090

Please sign in to comment.