更新时间:2024-06-25 05:50:43下载pdf
涂鸦 IPC 开发框架支持 P2P 实时预览 和 WebRTC 预览 两种预览模式。
P2P 实时预览
涂鸦实时预览与对讲,基于自研 P2P(Peer-to-peer)技术,建立设备和 App 之间点对点、安全加密的数据传输通路,实现了设备端音视频数据的实时预览和对讲功能。
WebRTC 预览
WebRTC(Web Real-Time Communication),即网页即时通信技术。涂鸦支持 WebRTC 能力,能够与支持 WebRTC 的浏览器、音箱等建立连接,实时传输音视频数据。
P2P 技术的出现,主要是为了解决,两台不同局域网下的设备,由于 NAT(网络地址转换)的存在,无法通过局域网 IP 地址,直连通信的问题。
P2P 通信的双方,通过标准的 STUN(Session Traversal Utilities for NAT))协议,向 STUN 服务器发送请求,获取自身的公网 IP。当通信的双方,获取到公网 IP 地址后,即可通过公网 IP 直连通信。
然而,P2P 并不能穿透所有的 NAT,在部分 NAT 类型下,无法穿透成功,即无法直连通信。不同类型的 NAT,穿透性如下:
NAT 类型 | 全锥型 | 受限锥型 | 端口受限锥型 | 对称型 |
---|---|---|---|---|
全锥型 | 可以 | 可以 | 可以 | 可以 |
受限锥型 | 可以 | 可以 | 可以 | 可以 |
端口受限锥型 | 可以 | 可以 | 可以 | 不可以 |
对称型 | 可以 | 可以 | 不可以 | 不可以 |
针对 P2P 直连无法穿透的场景,可以通过云端服务器进行转发。
涂鸦自研 P2P 技术,在 P2P 传输通道上,对音视频数据进行了 AES 加密,保证了数据的安全传输。
WebRTC 基于已有的 P2P 技术,在 P2P 传输通道上,实现了安全的数据传输。
tuya_ipc_media_adapter.h
tuya_ipc_media_stream.h
tuya_ipc_media_stream_event.h
涂鸦的音视频业务,基本都涉及到网络、时间等基础业务,所以正常的音视频业务,需要等待 MQTT 上线以及同步到时间,然后才进行初始化启动。但是在低功耗设备上,MQTT 本身上线需要时间,在这个等待上线的阶段,可以将音视频的部分业务(不依赖网络的部分)先启动,以提升出流速度。
常供电设备一般采用涂鸦 Demo 中的示例流程,顺序启动即可。参考下图:
低功耗设备设备可以创建单独的线程去启动音视频业务。参考下图:
针对低功耗设备,未激活时,请勿提前启动音视频业务。音视频业务启动中,需要读取设备的一些激活信息,若读取失败,会导致后续的拉流失败,需要重启才能恢复。所以可以通过 tuya_ipc_get_register_status
判断当前是 E_IPC_ACTIVEATED
状态后才启动音视频业务。
App 实时预览设备画面,可以分为两个大部分:
连接建立
主要在设备和 App 直接建立一个可用的网络链路,用于后续协议、数据的收发。
业务协议交互及音视频收发
设备和 App 可以进行一些信令交互(开始预览、切换清晰度等),也可以进行音视频数据的收发。
下文按照一次 App 预览请求的流程顺序,介绍内部的一些设计思路和问题排查方式。
此阶段对应于 App 上展示的 正在构建加密通道 阶段:
App 和设备建立连接的大致流程如下:
每路 App 和设备的连接均会消耗内存资源和连接路数。以 Linux 为例,具体消耗情况如下:
连接方式 | 内存消耗 | 连接路数消耗 |
---|---|---|
P2P | 1MB | 1 |
WebRTC | 1.5MB | 1 |
在音视频业务初始化时,您可以根据自己的硬件规格来设定同时支持的连接路数(一般建议 3~5 路为宜)和可供音视频业务消耗的内存大小。若超过以上限制,新建连接会被强制关闭。
最大连接路数设置方式
tuya_ipc_media_stream_init
时,设置参数 MEDIA_STREAM_VAR_T:max_client_num
。
最大内存资源设置方式
tuya_ipc_media_adapter_init
时,设置参数 TUYA_IPC_MEDIA_ADAPTER_VAR_T:available_media_memory
。
因为音视频数据大部分涉及隐私,故 App 和设备建立连接后,会进行一次鉴权,保证此 App 用户有权限查看设备的视频。
鉴权需要以下两个关键信息,均由涂鸦 SDK 内部管理:
以上任一信息错误,均会导致鉴权失败,进而引起关闭会话。
此阶段对应于 App 上展示的 正在获取视频流 界面:
连接建立,设备和 App 的交互主要有信令交互、数据收发等流程。
信令交互。主要进行清晰度设置、预览开关、音频开关等。
数据收发。根据信令的交互,向 App 发送对应的音视频数据。
对讲。将 App 对讲数据发送给设备,并由客户进行播放。
上面流程有两点需要关注:
正常情况下,App 退出预览界面,会主动发起关闭会话的请求。还有一些异常情况,也会引起设备关闭会话:
连接资源的回收需要时间,App 上快速的退出预览,再进入,有可能会因为连接资源未完成回收,导致极短时间内多占用一路连接。
出流速度
通过大数据分析,常供电设备的出流速度基本在 2.5 秒左右。
延迟
此数据受网络影响较大。实验室数据分析,延迟一般在 250~400 毫秒之间。
卡顿
设备 SDK 和 App 均采用多个缓冲区,来对抗网络的抖动,保证播放流畅性。在网络抖动较大或者网络较差时,可能会有卡顿现象。
跳帧
若设备的码率大于设备与 App 之间的带宽,会导致数据堆积,此时会发生跳帧现象。当临时的网络变差,导致数据发送较慢时,也会发生此现象。
花屏
涂鸦 SDK 内部采用多种算法,对抗网络丢包,保证传输的可靠性。在您的音视频数据正常的情况下,App 预览不会发生花屏现象。Web 端采用 WebRTC 框架,在网络较差,丢包严重的情况下,可能会有花屏出现。
视频
建议分辨率和编码等级(Profile)与对应的编码格式(H264、H265 等)要求匹配,否则在某些性能较低的手机上,会因为资源不足,而产生解码异常。
音频
每次送入的音频数据大小不可超过 800 字节。
时间 PTS
若在放入环形缓冲区前,提供了 PTS,请使用微秒时间。
可以根据如下现象来判断连接失败:
listen ok
或者 __p2p_deal_with_listen
的日志打印。在排查问题前,需要先了解如何识别上述 MQTT 消息:
如何判断设备收到 MQTT 消息
设备日志(DEBUG 级别)中存在 Rev MQTT:
"的打印,后面的内容即为 MQTT 消息内容。
如何判断收到的 MQTT 消息是 App 发出的建立连接需要的报文
MQTT 消息中,存在 "protocol":302
的打印,意为 302 号 MQTT 消息。302 号 MQTT 消息是流媒体使用的协议。
如何判断设备是否发出去建立连接需要的 MQTT 报文
设备日志(DEBUG 级别)中存在 Send MQTT Msg.P:302
的打印
然后参考 连接建立流程 步骤序号,按照以下步骤排查:
MQTT 链路是否通畅,排查是否有 MQTT 消息的交互
App 或者设备 MQTT 不通,会导致后续的所有 MQTT 报文无法交互。
第 3 步是否拿到连接配置信息
此处需要依赖 App 日志排查,也可以简单根据是否走到第 5 步来确认。
设备是否收到连接请求报文(第 5 步和第 6 步是否正常)
连接请求的 MQTT 消息一般会比较长,导致无法完全打印。可以是否收到包含 tcp_token"、
token、
sdp` 等字段的 302 号 MQTT 消息。
设备是否发出连接请求回复报文(第 7 步是否正常)
可以查看设备是否发出去了 302 号 MQTT 协议,其中包含 "type":"answer"
、"tcp_token"
、 sdp
等字段。
设备是否收到了 App 的 IP 地址(第 11 步和第 12 步是否正常)
查看设备是否收到了包含 "type":"candidate"
302 号 MQTT 协议。
设备是否发出去了自己的 IP 地址(第 13 步是否正常)
查看设备是否发出了包含 "type":"candidate"
302 号 MQTT 协议。
若以上步骤均无问题,请 提交工单 联系涂鸦排查问题。
可以根据设备日志来判断会话满
设备日志出现 incoming connection refused
或者 alloc resource failed
或者 no value able session please check process
App 提示设备忙线
会话路数管理,基本不受您的代码影响,若频繁出现,可以按照以下顺序处理:
可以根据如下现象来判断鉴权失败:
auth failed
-105
排查方向:
是否收到鉴权信息
若设备日志中,出现 get userinfo timeout
或者 get userinfo error
,说明接收 App 鉴权信息出错。
设备本地维护的 P2P 密码是否正确
设备日志中(DEBUG 级别)出现 get p2p passwd =
,后面的字符串即为 P2P password(此字段仅用于设备和 App 的鉴权,且仅为鉴权所需的部分信息,无需担心日志泄露造成安全隐患)。若此字段不以 ad
开头,则为错误密码。P2P password 出现错误,需要排查设备 DB 文件是否正常。
App 清除缓存后,重试是否恢复
App 可能会使用缓存的 P2P 密码或者设备激活信息,用来鉴权。删除缓存后,使用云端提供的信息,如果能成功,则需要排查 App 的缓存策略是否符合当前场景要求。
当 App 长时间处于 正在获取视频流 界面,最终提示 获取视频流失败 时,一般是信令交互或者数据收发出现了问题。
参考 音视频业务流程,按照以下步骤排查:
信令是否正确
可以通过音视频服务的事件回调来判断当前收到了哪些指令,例如开始拉流、开启伴音等。指令为枚举型 MEDIA_STREAM_EVENT_E
,可以参考名称定义来确定其功能。
数据发送线程是否正常
设备日志(DEBUG 级别)是否周期打印 media send proc alive
,若有周期性打印,说明线程工作正常。
环形缓冲区数据读取是否正常
观察设备日志(DEBUG 级别),是否突然出现大量 tuya_ring_buffer.c
文件中的打印,若存在打印,说明音视频数据放入环形缓冲区有问题。
发送帧数量统计是否变化
观察设备日志(DEBUG 级别)是否周期性打印 session send video cnt
(发送视频帧数量)和 session send audio cnt
(发送音频数量),若数量持续增加,说明在正常发送数据。
若以上步骤均无问题,请 提交工单 联系涂鸦排查问题。
同时预览的连接数量,已达到 tuya_ipc_media_stream_init
接口设置的最大值 max_client_num
。
tuya_ipc_media_adapter_set_media_info
接口设置的参数。ring buffer
未塞入音视频流。ring buffer
塞入的音视频时间戳存在问题,timestamp
时间戳要求毫秒量级,pts
时间戳要求微秒量级。MEDIA_STREAM_EVENT_CB
回调产生 MEDIA_STREAM_LIVE_VIDEO_START
事件,表示预览开始。MEDIA_STREAM_EVENT_CB
回调产生 MEDIA_STREAM_LIVE_VIDEO_STOP
事件,表示预览结束。App 上正常退出预览时,App 向设备发送关闭连接请求,设备收到 MEDIA_STREAM_LIVE_VIDEO_STOP
预览结束事件。IOS 上直接杀掉 App 进程,App 不会向设备发送关闭连接请求,需要等待设备心跳超时,超时时间大约 1~2 分钟。
MEDIA_STREAM_LIVE_VIDEO_START
预览开始事件中,通过C2C_TRANS_CTRL_VIDEO_START
结构体中的 type
字段区分:
type = TRANSFER_SOURCE_TYPE_P2P
,表示 App 预览。type = TRANSFER_SOURCE_TYPE_WEBRTC
,表示 WebRTC 预览。检查一下 Web 端,是否打开麦克风权限。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈