ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

云服务器跑LiveTalking数字人连不上?两个 TCP 端口全搞定

云服务器跑LiveTalking数字人连不上?两个 TCP 端口全搞定 在云 GPU 服务器上跑 LiveTalking 数字人最崩溃的瞬间不是模型加载慢而是——画面推不出去。WebRTC 默认走 UDP而 AutoDL、企业防火墙、家庭对称型 NAT统统把 UDP 封得死死的。你兴冲冲部署好浏览器一打开黑屏、转圈、连不上。端口开了几十个还是不行其实你只需要开放两个 TCP 端口nginx 服务端口和 MediaMtx 的媒体端口。为什么 WebRTC 这么挑剔WebRTC 媒体流默认用 UDPSRTP传输还要做 ICE 连通性检查常常需要在 1~65535 整个 UDP 区间里试端口。在自有服务器上这没问题但在云环境里算力平台AutoDL 等只放行少量 TCP 端口UDP 基本全封企业网络防火墙策略严格UDP 入站直接拒绝家庭宽带对称型 NATUDP 穿透几乎必败。结果就是——服务端在客户端也在但媒体流就是过不去。MediaMtx 代理把 UDP 流拐进 TCPMediaMtx 是一个开源媒体服务器原生支持 WebRTC关键能力是可以通过 TCP 传输 WebRTC 媒体webrtcLocalTCPAddress。部署思路如下LiveTalking 把数字人画面作为 WebRTC 源推给同机的 MediaMtxMediaMtx按客户端请求主动从 LiveTalking 拉流然后 MediaMtx 以 WHEP 协议通过单个 TCP 媒体端口例如:8189对外服务客户端浏览器只跟 nginx 和这个 TCP 端口打交道。换句话说对外只暴露两个 TCP 端口nginx 服务端口 MediaMtx 媒体端口UDP 那一套全在服务器内网闭环根本不需要出网。三种方案对比看清差异LiveTalking 的网络部署有三套方案方案需开放端口适用环境A. WebRTC 全端口TCP 8010 UDP 1-65536自有服务器B. MediaMtx 代理2 个 TCP 端口nginx 服务端口 MediaMtx:8189云环境 / 防火墙首选C. SRS中转2 个 TCP 端口nginx 服务端口 srs:8000需要用rtcpush推流模式方案 B 的核心优势在 AutoDL 这类只给 TCP 的环境里它几乎是唯一能跑通 WebRTC 推流的方案。MediaMtx主动拉流 TCP 承载天然绕开 UDP 封锁和对称 NAT 穿透难题——UDP 被拒就换 TCP客户端连的是 TCP穿透难度天差地别。offer 接口 vs WHEP 接口差在哪LiveTalking 默认是直连方式前端把 WebRTC 的 SDP offer 直接 POST 到 LiveTalking 自己的/offer或类似自定义接口:8010LiveTalking 作为 WebRTC 对端直接回 answer随后把数字人画面用 UDP 推给浏览器。这条链路里浏览器和 LiveTalking 是直接点对点的连接所有 ICE、NAT 穿透、UDP 端口问题都得自己扛。WHEPWebRTC-HTTP Egress ProtocolRFC 8865是一套标准化的 WebRTC 信令协议客户端把 SDP offer 用一次 HTTP POST 发给服务端 WHEP 端点服务端回 answer并给一个资源 URL 用于断开。它把建连变成了一个简单的 HTTP 请求。引入 MediaMtx 后WHEP 端点从 LiveTalking 转移到了 MediaMtx 上客户端不再直连 LiveTalking而是把 offer 发给 MediaMtx 的/avatar/sessionid/whepMediaMtx 作为面向客户端的 WebRTC 对端再用WHEP 客户端身份反向去 LiveTalking 的whep://127.0.0.1:8010/whep拉流。区别一目了然offer 接口客户端 ↔ LiveTalking 直连LiveTalking 既是业务端又是 WebRTC 对端媒体走 UDP 直推WHEP 接口经 MediaMtx客户端 ↔ MediaMtxWebRTC 对端TCP:8189MediaMtx ↔ LiveTalking内网 WHEP 拉流:8010。媒体流量被 MediaMtx 兜了一层对外只走 TCP。一句话offer 接口是客户端直接怼 LiveTalkingWHEP 接口是客户端怼 MediaMtxMediaMtx 再去怼 LiveTalking——多了一跳但换来了只用 TCP 端口的部署自由。配置实战三处改动① MediaMtxmediamtx.yml— 关掉 UDPwebrtcLocalUDPAddress: 只留 TCP:8189path 用正则~^avatar/(.)$每个 sessionid 对应独立的 source 连接source 指向 LiveTalking 的 WHEP# mediamtx.yml webrtcLocalUDPAddress: webrtcLocalTCPAddress: :8189 # 配置 tcp 映射端口 webrtcAdditionalHosts: [] # 配置外网 ip 地址 paths: # 用正则匹配每个不同的 sessionid 创建独立的 source 连接 # 客户端访问: /avatar/sessionid/whep?avatarxxxttsyyy # $G1 sessionid, $MTX_QUERY avatarxxxttsyyy ~^avatar/(.)$: source: whep://127.0.0.1:8010/whep?sessionid$G1$MTX_QUERY sourceOnDemand: yes② nginx/etc/nginx/sites-enabled/default—/avatar全部转发到 MediaMtx 的 HTTP 端口:8889其余/转发到 LiveTalking:8010server { # /avatar 路由 → MediaMtx location ^~ /avatar { proxy_pass http://127.0.0.1:8889; } location / { rewrite ^/$ /index-whep.html break; proxy_pass http://127.0.0.1:8010; } }③ LiveTalking 前端— 把原来访问/offer的接口改成访问 MediaMtx 上的 WHEPsessionid 在客户端生成并拼进路径参数走 query stringMediaMtx 再代理到 LiveTalking// 客户端生成 sessionid放入路径中每个不同 sessionid 独立 source 连接 if (!sessionid) setSessionId(crypto.randomUUID()); // sessionid 在客户端生成 if (avatar) params.set(avatar, avatar); if (refAudio) params.set(refaudio, refAudio); if (refText) params.set(reftext, refText); const queryString params.toString(); // 参数配置在 query param // 访问接口由 offer 改成访问 mediamtx 上的 whep由 mediamtx 代理到 livetalking return fetch(/avatar/ sessionid /whep (queryString ? ? queryString : ), { method: POST, headers: { Content-Type: application/sdp }, body: offer.sdp });原本要开的几万个 UDP 端口被压缩成两个 TCP 端口nginx 服务端口 MediaMtx 媒体端口——这就是 MediaMtx 代理的价值。已在autodl上跑通整个流程镜像地址https://www.codewithgpu.com/i/lipku/livetalking/base下次在云上部署数字人推流卡住别再死磕 UDP 了。一个 nginx两个 TCP 端口问题就解决了。你踩过 WebRTC 端口的坑吗用的是哪种方案评论区聊聊 LiveTalking— 开源实时交互数字人引擎。GitHubhttps://github.com/lipku/LiveTalking文档https://doc.livetalking.ai
返回列表