安基网 首页 手机 手机学院 查看内容

scrcpy 投屏原理简单解析

2020-5-7 14:21| 投稿: |来自:


免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!

摘要: 最近一个项目中需要用到 screen mapping、remote control 等功能,仔细对比之后选择了 scrcpy 这个方案。scrcpy 是一种主要用于 display 和 control 的简单易行的联机方案,主要特点是非侵入性(不需要主动安装应用程序),结构简单,方法易行。下面,让我们来简要分析一下它的工作原理。我们以 Win 版 ...

最近一个项目中需要用到 screen mapping、remote control 等功能,仔细对比之后选择了 scrcpy 这个方案。scrcpy 是一种主要用于 display 和 control 的简单易行的联机方案,主要特点是非侵入性(不需要主动安装应用程序),结构简单,方法易行。下面,让我们来简要分析一下它的工作原理。

我们以 Win 版为例,解压文件后,可以看到如下这么几个文件。

adb.exe

AdbWinApi.dll

AdbWinUsbApi.dll

avcodec-58.dll

avformat-58.dll

avutil-56.dll

scrcpy-noconsole。exe

scrcpy-server

scrcpy.exe

SDL2.dll

swresample-3.dll

swscale-5.dll

仔细阅读源码,发现工作原理很简单,那就是:从 server 端,这里指定为 PC 端,发送一个 jar 文件到 client 端。然后在 client 端执行,利用的是 Android 平台中 classloader 执行命令行的特性,先将 jar 包利用 adb 推送到 /data/local/tmp,然后执行,但是整个过程用户除了运行一个可执行命令、都是无感知的,这操作好骚气~~~

另外一点,前几期阶段,server 文件只是一个 jar 包,而后期 scrcpy 改变了策略,由这个文件来生成 jar 包,这样做是为了什么?小编我先在这里卖个关子。

上述文件执行之后,会在 server / client 之间生成一个 socks 连接,该 socks 连接中传输的是什么?没错,看到 ffmpeg 没有,传输的就是 stream 流,最后经 ffmpeg 解码还原成图像。至此,图像传输的基本过程结束。下面贴出一段代码,可以看到虽然 scrcpy 这个小工具结构简单、但是还是能够打印输出/调试信息,功能还是蛮全的。

public static DesktopConnection open(Device device, boolean tunnelForward) throws IOException {

LocalSocket videoSocket;

LocalSocket controlSocket;

if (tunnelForward) {

LocalServerSocket localServerSocket = new LocalServerSocket(SOCKET_NAME);

try {

System。out。println("Waiting for video socket connection。。。");

videoSocket = localServerSocket.accept();

System。out。println("video socket is connected。");

// send one byte so the client may read() to detect a connection error

videoSocket.getOutputStream().write(0);

try {

System.out.println("Waiting for input socket connection...");

controlSocket = localServerSocket。accept();

System。out。println("input socket is connected。");

} catch (IOException | RuntimeException e) {

videoSocket.close();

throw e;

}

} finally {

localServerSocket。close();

}

} else {

videoSocket = connect(SOCKET_NAME);

try {

controlSocket = connect(SOCKET_NAME);

} catch (IOException | RuntimeException e) {

videoSocket.close();

throw e;

}

}

DesktopConnection connection = new DesktopConnection(videoSocket, controlSocket);

Size videoSize = device.getScreenInfo().getVideoSize();

connection.send(Device.getDeviceName(), videoSize.getWidth(), videoSize.getHeight());

return connection;

}

需要注意的是,这个过程每次都需要执行一遍,也就是说,每次都会推送一遍这个 file....

效果图如下




小编推荐:欲学习电脑技术、系统维护、网络管理、编程开发和安全攻防等高端IT技术,请 点击这里 注册账号,公开课频道价值万元IT培训教程免费学,让您少走弯路、事半功倍,好工作升职加薪!

本文出自:https://www.toutiao.com/a6823688226918629891/

免责声明:本站系公益性非盈利IT技术普及网,本文由投稿者转载自互联网的公开文章,文末均已注明出处,其内容和图片版权归原网站或作者所有,文中所述不代表本站观点,若有无意侵权或转载不当之处请从网站右下角联系我们处理,谢谢合作!

相关阅读

最新评论

 最新
返回顶部
上海11选5 e乐彩票计划群 极速快三 上海11选5 山东11选5 头奖彩票计划群 北京赛车怎么玩 极速赛车冠军怎么看 极速赛车是谁开的 豪门会彩票计划群