amazon-s3 - 将实时视频从 Raspberry Pi 摄像头流式传输到 Android 应用程序
问题描述
- 我家和办公室(出版商)有多个带有本机摄像头的 Raspberry Pi 设备。- Publisher(Pi) 他们位于防火墙/路由器后面的本地网络上并连接到互联网。
- 我有一个 EC2 网络服务器(代理)。它可通过公共 IP 地址公开访问。
- 我的手机上有一个 Android 应用程序。它通过 4G 网络连接互联网。(订阅者/消费者/客户)
我正在尝试在我的 Android 应用程序上查看每个覆盆子相机的实时信息。这个问题更多是概念性的而不是技术性的。在成本和延迟方面,我无法决定什么是正确的方法和最有效的方法来实现这一目标。
方法,我根据对此的研究得出了结论:-
方法 1:
1. 通过 raspvid/ffmpeg 在 pi 设备中以 RTSP / RTMP 流式传输相机
2. 在 pi 设备中有一个读取 RTSP 流的代码将其保存到 AWS S3
3. 有一个对 RTSP 流进行转码的中间件和将其保存为移动应用可通过 S3 url 访问的格式
方法 2:
1. 通过 raspvid/ffmpeg 在 pi 设备中以 RTSP / RTMP 流式传输相机
2. 在 pi 设备中使用读取 RTSP 流的代码将其推送到远程帧收集 (ImageZMQ) 服务器。EC2 可以在这里使用。
3. 有一个中间件,将帧转码为 RTSP 流,并将其保存为 S3 上的格式,移动应用程序可以通过可公开访问的 S3 URL 访问该格式
方法 3:
1. 通过启动 Web 浏览器以 WebRTC 格式流式传输相机。
2. 将流发送到像 Kurento 这样的媒体服务器。EC2 可以在这里使用。
3. 为每个流生成唯一的 webrtc 可公开访问 url
4. 通过移动应用访问 webrtc 视频
方法 4:
1. 通过 raspvid/ffmpeg 在 pi 设备中以 RTSP / RTMP 流式传输相机
2. 通过设备上安装的 Amazon Kinesis 客户端获取流。
3. 将 Kinesis 流发布到 AWS 云
4. 让 Lambda 存储对其进行转码并将其存储在 S3 中
5. 让移动应用程序通过可公开访问的 S3 url 访问视频流
方法 5: - (相当复杂的涉及 STUN/TURN 服务器绕过 NAT)
1. 通过 raspvid/ffmpeg 在 pi 设备中以 RTSP / RTMP 流式传输相机
2. 获取流并将其发送到像 gstreamer 这样的媒体服务器。EC2 可以在这里使用。
3. 使用 live555 代理或 ngnix RTMP 模块。EC2 可以在这里使用。
4. 为每个设备生成一个唯一的可公开访问的链接,但在同一端口上运行
5. 让移动应用程序通过设备链接访问视频流
只要我不使用任何第三方商业解决方案,如 wowza、antmedia、dataplicity、aws kinesis,我对任何视频格式都持开放态度。我拥有的最重要的限制是我的所有设备都是无头的,我只能通过 ssh 访问它们。因此,我排除了涉及手动设置或与 PUBLISHERS(Pis) 的桌面界面交互的任何此类选项。我可以创建脚本来自动化所有这些。
最终目标是我希望为每个 Raspberry PI 摄像头提供公共 url,但它们都在相同的套接字/端口号上运行,如下所示:-
rtsp://cam1-frontdesk.mycompany.com:554/
rtsp://cam2-backoffice.mycompany.com:554/
rtsp://cam3-home.mycompany.com:554/
rtsp://cam4-club.mycompany.com:554/
解决方案
哪种解决方案合适主要取决于您是否在本机应用程序(例如 VLC)中查看视频以及“直播”的含义——通常,“直播”使用 HLS,通常至少增加 5 个并且通常更接近下载和播放短视频文件序列时的延迟为 30 秒。
如果您可以容忍延迟,HLS 是最简单的解决方案。
如果您想要实时(< 0.300 秒的延迟)并通过本机应用程序观看视频,RTSP 是最简单的解决方案。
如果您想要实时内容并希望在 Web 浏览器中查看它,Broadway.js、媒体源扩展 (MSE) 和 WebRTC 是三种可用的解决方案。Broadway.js 仅限于 H.264 基线,并且仅在 GPU 加速画布支持的情况下表现良好——并非所有浏览器都支持。并非所有浏览器都支持 MSE。WebRTC 拥有最好的支持,但也是三者中最复杂的。
对于可在任何浏览器中运行的 Raspberry Pi 的实时视频,请查看Alohacam.io(完整披露:我是作者)。
推荐阅读
- java - 给定一个 Gradle 项目,如何将 `build.gradle.kts` 文件中的 JAR 依赖项提取到给定文件夹?
- linux - 通过匹配特定列来连接两个文件
- node.js - Node.js 脚本复制文件覆盖以前的文件?
- powershell - Powershell:复制Excel数据透视图并保存
- flutter - Flutter 创建密码规则对话框
- tf.keras - 将函数应用于 tf.keras.Model 输出到批次中的每个样本
- android - App Bundles (AAB) 是否自动使用 APK 签名方案 v2?
- python - 如何使用 PyWinAuto 在后台发送密钥?
- scala - 如何在 scala.meta quasiquotes 中使自定义类型可提升
- r - 嵌套数据的 Dplyr 逻辑成员资格测试