You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:40:36