Expo React Native与SIP设备间SDP协商RTP及视频显示问题
解决方案:React Native Expo 与 SIP 设备的 RTP 视频通话
一、向 SIP 设备发送正确的 SDP
你需要构造符合 RFC3264 规范的 SDP,明确告知 SIP 设备你的应用接收媒体流的 IP 和端口,同时指定双方兼容的视频编码格式:
- 基础 SDP 结构示例:
v=0 o=- 12345 12345 IN IP4 192.168.1.XX # 替换为你的设备本地IP s=- c=IN IP4 192.168.1.XX # 与上面的IP一致 t=0 0 m=video 5004 RTP/AVP 96 # 5004是你的应用接收RTP的端口,96是H.264的负载类型 a=rtpmap:96 H264/90000 # 指定编码为H.264,时钟频率90000 a=fmtp:96 profile-level-id=42e01f;packetization-mode=1 # H.264的参数,确保与SIP设备兼容 a=recvonly # 如果你的应用只接收视频,用这个;如果需要双向通话,用a=sendrecv
- 核心要点:
m=行的端口是你的应用接收RTP流的端口,必须是设备上未被占用的端口。 - 编码选择:优先使用 SIP 设备支持的编码(通常H.264兼容性最好),确保
rtpmap和fmtp参数与设备匹配。
- 关键注意事项:
- 必须使用设备的本地局域网IP(而非127.0.0.1),确保SIP设备能访问到你的应用。
- 如果你的应用处于NAT环境下,可能需要启用STUN/TURN来获取公网候选地址,但这需要SIP设备支持ICE协议。
二、在 React Native 应用中显示接收的视频
针对 Expo Video 无法直接从SDP获取发送端口的问题,可按以下步骤处理:
1. 常规场景:利用 SIP 设备的普遍实现
虽然 RFC3264 未强制,但绝大多数 SIP 设备会使用SDP中声明的接收端口来发送RTP流。也就是说,你可以从 SIP 设备返回的 SDP 的m=行中提取端口,直接构造 Expo Video 的源地址:
// 假设从SIP设备的SDP中解析出IP为192.168.1.100,端口为5000 const rtpSource = `rtp://192.168.1.100:5000`; // 在组件中使用Expo Video <Video source={{ uri: rtpSource }} style={{ width: 300, height: 200 }} resizeMode="contain" shouldPlay />
2. 特殊场景:设备不使用接收端口发送流
如果上述方法失效,说明设备使用了不同的发送端口,此时需要借助ICE协议来协商实际的媒体传输地址:
- Expo Video 本身不支持ICE,建议改用
react-native-webrtc库:它原生支持SIP信令交互、ICE协商和RTP流处理,能直接获取对方的媒体发送地址,并且可以将WebRTC的媒体流渲染到组件中。 - 若必须使用 Expo Video,需要开发自定义原生模块,监听指定端口的RTP流,将其转换为Expo Video可识别的本地流格式(如RTSP或本地文件流),再传递给Video组件。
3. 排查要点
- 确保设备和应用处于同一局域网,端口未被防火墙或路由器屏蔽。
- 验证RTP流是否到达应用的接收端口:可以使用Wireshark抓包,查看是否有来自SIP设备的RTP数据包。
内容的提问来源于stack exchange,提问作者Antti_M
相关产品推荐
相关产品推荐

