说在前面

折腾这个最初的目的其实是在学校信息课上摸鱼(笑)

本文的目的是使用最低的成本达到在浏览器上远程控制手机的效果。该方案延迟偏高,可能不适用于某些应用场景。(实际上我个人使用的也不是这套方案,而是ws-scrcpy+rpi4+frp,但这样一来会产生成本。以后有时间可能会写篇文章详细谈谈)

准备工作

1.一部安卓手机(Android11及以上,aarch64架构)

2.一个Cloudflare账号

3.一个域名,并解析至Cloudflare(域名为本文唯一可能产生成本的地方)(可以去Freenom免费注册,但是更推荐在有条件的情况下去Namesilo等注册商处购买)

4.在国内上网的神奇妙妙工具,保证操作时连接畅通

5.手机上安装Termux并安装好完整Linux容器(参考我的上篇文章

本文使用的是Debian 12

安装ws-scrcpy

首先,进入容器。

1.安装nodejs和node-gyp

ws-scrcpy上一个Release已经是2022年的事了,并不支持最新版的nodejs。所以我们得使用nvm安装nodejs v14.20.0:

curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
source ~/.bashrc
nvm install 14.20.0

同样地,node-gyp也要使用旧版本:

apt install gcc make g++
npm install -g node-gyp@7.1.2

2.安装Python

Debian 12的apt源里只有Python3.11这一个版本。但3.11太新了,和nodejs一样,会报错。所以我们面临着一个很悲催的现实:编译安装Python3.9.5(当然,如果你有别的办法安装Python3.9.5那就用别的方法,编译一遍真的太麻烦了)

安装依赖:

apt install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-openssl git

下载源文件并进行编译(过程漫长):

wget https://www.python.org/ftp/python/3.9.5/Python-3.9.5.tar.xz
tar -xvf Python-3.9.5.tar.xz
cd Python-3.9.5
./configure --prefix=/usr/local/python3 --enable-optimizations
make
make install

创建软链接:

ln -s /usr/local/python3/bin/python3.9 /usr/bin/python3
python3 -V

输出Python 3.9.5

3.安装ws-scrcpy

首先,克隆项目:

git clone https://github.com/NetrisTV/ws-scrcpy.git
cd ws-scrcpy

然后,执行:

npm install
npm start

这时候不出意外在局域网内访问http://ip:8000就能打开ws-scrcpy的界面了。确定能用后,我们先暂时Ctrl+C关闭程序。

接下来,配置adb。退出容器,返回Termux终端,执行pkg i android-tools ,然后按照正常无线调试流程进行配对与连接。完成后,重新进入容器。(详细操作见我的上一篇文章

配置Cloudflare Tunnel

目前为止,我们只能在局域网内访问。现在我们使用Cloudflare Tunnel实现公网访问。

(请确保有一个域名正确解析至Cloudflare)

1.安装与登录

首先下载并安装cloudflared:

wget https://github.com/cloudflare/cloudflared/releases/download/2024.2.1/cloudflared-linux-arm64.deb
dpkg -i cloudflared-linux-arm64.deb

安装好之后,登录Cloudflare:

cloudflared tunnel login

2.配置Tunnel

首先,创建一个隧道:

cloudflared tunnel create ws-scrcpy

其中ws-scrcpy 是隧道的名字,可以根据自己的喜好命名。

接着为隧道指定二级域名:

cloudflared tunnel route dns 隧道名 你指定的域名
#如:cloudflared tunnel route dns ws-scrcpy scrcpy.example.com

然后,启动ws-scrcpy并让隧道连接上本地服务(用nohup挂起):

nohup npm start > scrcpy.log 2>&1 &
nohup cloudflared tunnel --protocol http2 run --url 127.0.0.1:8000 隧道名 > argotunnel.log 2>&1 &

此时,正常的话你就可以通过浏览器访问scrcpy.example.com 来进入后台了。但这样有一个很大的问题:没有鉴权。这意味着任何访问该网址的人都有权限操控手机,这是风险极大且我们不愿意看到的。接下来我们用Cloudflare Workers添加鉴权。

3.添加鉴权

首先,登录Cloudflare官网,然后按以下步骤操作:

在打开的编辑器中填入:

const username = "XXX"//用户名
const password = "123456"//密码
 
const handle = (req) => {
    const auth = req.headers.get('Authorization') || "Basic "
    if (auth.split(' ')[1] == btoa(username + ":" + password)) return fetch(req)
    return new Response(null, {
        status: 401,
        headers: {
            'WWW-Authenticate': 'Basic realm="This is a Private App!"'
        },
        body: 'Your ip has been recorded, please do not try to crack the password.'
    })
}
 
addEventListener('fetch', event => {
    event.respondWith(handle(event.request))
})

接着,进入到域名的控制面板,配置域名(*.workers.dev被GFW了):

至此,访问scrcpy.example.com ,大功告成。

写在后面

若Termux挂在后台经常自动退出,在Termux终端执行tmoe m ,选择"修复 android 12(signal 9)"并根据指示操作。

参考链接:

https://blog.imoeq.com/scrcpy-run-a-android-web-page

https://github.com/NetrisTV/ws-scrcpy