GStreamer WebRTCbin跨网仅获Host类型ICE候选,连接失败求助
GStreamer WebRTCbin Android跨网络ICE连接失败问题排查
问题现象
- 本地网络环境下WebRTC功能正常,跨网络场景中WebRTC暂停,Android端生成的ICE候选均为
typ host类型,无服务器反射(srflx)或中继(relay)候选 - 设置
GST_WEBRTC_ICE_TRANSPORT_POLICY_RELAY后,Android端无任何ICE候选输出 - 无法通过Wireshark捕获到STUN数据包,最终ICE连接状态为
GST_WEBRTC_ICE_CONNECTION_STATE_FAILED(对应数值4)
相关配置与日志
STUN/TURN服务器配置
#define STUN_SERVER " stun-server=stun://47.104.15.123:3478 " #define TURN_SERVER " turn-server=turn://jianxi:jianxi@47.104.15.123:3478 " webrtc->pipe = gst_parse_launch ("webrtcbin bundle-policy=max-bundle name=sendrecv " STUN_SERVER TURN_SERVER
信号连接代码
g_signal_connect (webrtc->webrtcbin, "on-ice-candidate", G_CALLBACK (send_ice_candidate_message), webrtc); g_signal_connect (webrtc->webrtcbin, "notify::ice-gathering-state", G_CALLBACK (on_ice_gathering_state_notify), NULL); g_signal_connect (webrtc->webrtcbin, "notify::ice-connection-state", G_CALLBACK (on_ice_gathering_state_notify), NULL);
ICE状态通知函数
static void on_ice_gathering_state_notify (GstElement * webrtcbin, GParamSpec * pspec, gpointer user_data) { GstWebRTCICEConnectionState ice_connect_state; GstWebRTCICEGatheringState ice_gather_state; gchar *stunser = NULL, *turnser = NULL; const gchar *new_state = "unknown"; g_object_get (webrtcbin, "stun-server", &stunser, NULL); if(stunser) { gst_print("stun-server: %s\n", stunser); g_free(stunser); } g_object_get (webrtcbin, "turn-server", &turnser, NULL); if(turnser) { gst_print("turn-server: %s\n", turnser); g_free(turnser); } g_object_get (webrtcbin, "ice-gathering-state", &ice_gather_state, NULL); g_object_get (webrtcbin, "ice-connection-state", &ice_connect_state, NULL); switch (ice_gather_state) { case GST_WEBRTC_ICE_GATHERING_STATE_NEW: new_state = "new"; break; case GST_WEBRTC_ICE_GATHERING_STATE_GATHERING: new_state = "gathering"; break; case GST_WEBRTC_ICE_GATHERING_STATE_COMPLETE: new_state = "complete"; break; } gst_print ("ICE gathering state changed to %s, %d\n", new_state, ice_connect_state); }
输出日志
2022-11-23 11:35:50.239 1638-5461 GLib+stdout org.freedesktop.gstreamer.webrtc I stun-server: stun://47.104.15.123:3478 2022-11-23 11:35:50.239 1638-5461 GLib+stdout org.freedesktop.gstreamer.webrtc I turn-server: turn://jianxi:jianxi@47.104.15.123:3478 2022-11-23 11:35:50.239 1638-5461 GLib+stdout org.freedesktop.gstreamer.webrtc I ICE gathering state changed to complete, 4
排查建议
修正STUN/TURN配置的空格问题
当前配置宏的开头和结尾存在多余空格,拼接后可能导致GStreamer解析参数异常。修改为:#define STUN_SERVER "stun-server=stun://47.104.15.123:3478" #define TURN_SERVER "turn-server=turn://jianxi:jianxi@47.104.15.123:3478"确认Android网络权限
检查AndroidManifest.xml是否添加必要权限:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />无INTERNET权限会导致设备无法连接STUN/TURN服务器。
测试STUN/TURN服务器可达性
通过adb shell在设备上执行:ping 47.104.15.123 nc -zv 47.104.15.123 3478确认设备能访问服务器IP和端口,同时验证TURN服务器的用户名、密码与服务器端配置一致。
提升日志级别排查细节
添加环境变量GST_DEBUG=webrtcbin:6,ice:6,查看ICE收集过程中的详细日志,确认是否有STUN请求发送失败、服务器响应错误等信息。检查ICE候选交换逻辑
确认send_ice_candidate_message函数是否正确传递所有ICE候选到对端,同时确保对端的候选也能正确接收并添加到本地webrtcbin。验证TURN服务器relay功能
使用trickle-ice等工具测试TURN服务器,确认其能正常返回relay类型候选,排除服务器配置问题。
内容的提问来源于stack exchange,提问作者jianxi sun
相关产品推荐
相关产品推荐

