android - Android Camerax 视频序列化与传输
问题描述
对于一个涉及光学相机通信 (OCC) 的研究项目,我需要主动分析视频帧,我目前正在使用 python 和 opencv 在我的电脑上离线进行分析(我用智能手机录制视频,然后进行处理)。我想使用我的三星 Galaxy A40 上的相机实时处理视频。我对android开发相当陌生,所以我只想创建一个基本的应用程序来捕获视频并将其传输到我的电脑进行分析。我的应用程序需要 30 fps 或更高的 1080p 捕获。
我目前正在使用提供 imageAnalysis 用例的 Android Camerax API,它使我能够访问原始图像平面:我获得了YUV_420_888 格式的ImageProxy。
我仍在熟悉 API,但已经能够根据在线示例重现一些基本应用程序。我还有一个具体的问题:
将图像序列化并将图像传输到我在电脑上的 python 应用程序的最佳方法是什么? 我正计划使用套接字创建一个简单的 TCP 连接,将图像转换为位图并像这样直接发送它。但是,我不确定这种方法是否非常有效,并且我不知道如何转换图像并对其进行缓冲。代码示例当然是受欢迎的。有线连接(我的电脑的 USB 电缆)也是可能的,但我没有找到任何支持。
欢迎任何想法!提前致谢。
解决方案
如果你真的关心性能,你应该使用 UDP 而不是 TCP。请记住,UDP 不能保证您发送的数据包以相同的顺序到达接收方,或者根本不能保证您可以在单个 UDP 消息中发送的最大数据包大小为 65535 字节。因此,您有责任在接收方实现某种逻辑来重新排序数据包,并告诉发送方您错过了一些东西。
一般来说,像 Stadia、PS Remote Play 等实时流媒体应用程序使用某种 FEC(前向纠错)机制,以便接收者可以自行恢复丢失的数据包。对于我的流媒体应用,我使用了 jerasure。但是使用 FEC 当然是可选的。
YUV_420_888 格式在压缩方面也不是非常理想,对于流媒体,我建议使用 h.264 或 VP8 之类的格式。您会在互联网上找到一些示例,例如(该项目有点旧,但可能有助于了解这个想法)
https://github.com/bytestar/android-h264-stream-demo
一个非常好的开源流媒体应用程序是月光。它也可用于 Android,这绝对值得一看,看看它是如何工作的。
有些东西对你的项目来说可能是多余的,但至少我建议使用 UDP 并将一个大的 YUV_420_888 帧分成几个较小的帧。在所有这些小数据包中,包括接收方的以下信息
- 唯一标识符(以便接收方知道数据包属于哪个 YUV_420_888 帧)
- 序列号(如果将 YUV_420_888 帧分成 10 块,则索引在 0 到 9 之间)
- 有关接收器可以预期拆分 YUV_420_888 帧的序列号的信息
拆分大 YUV_420_888 帧的原因是为了避免MTU问题(大于当前默认 MTU 值的消息将被丢弃,通常在 1500 字节左右)。
推荐阅读
- php - 仅当容器重新启动时,本地更改才会传播到 docker 容器
- html - 下拉按钮不展开
- rust - 如何从 Rc 内部返回结构?
- c++ - Ceres Solver:对非线性最小二乘使用平滑近似
- java - Dijkstra 的最短路径
- xml - 递归连接父属性 - 并保留元素数据
- android - 关于 Google Cloud Platform (GCP) API 密钥的 Google Play 安全警报
- swift - 如何从 ViewController 在 ARKit 中重复调用一个函数来识别对象/图像?
- javascript - React - 未处理的拒绝(TypeError)this.function不是函数
- ios - WatchOS 检测用户是否已关闭手表/锁定屏幕