9b9t服务器显示连接超时,在WebRTC中ICE连接失败

我们正在尝试将浏览器(客户端)与aiortc库(服务器,发送单个视频流)连接起来。目前,连接已成功建立(on signalingstatechange稳定)。但是,媒体连接从未建立,因为ICE连接失败。这两台主机在同一个局域网上,并且已经验证了直接连接。使用的STUN服务器是STUN.l。谷歌:19302. 在

服务器上的日志如下:DEBUG:asyncio:Using selector: EpollSelector

DEBUG:ice:Connection(0) protocol(0) connection_made(<_selectordatagramtransport fd="11" read="idle" write="<idle," bufsize="0">>)

DEBUG:ice:Connection(0) protocol(0) > ('66.102.1.127', 19302) Message(message_method=Method.BINDING, message_class=Class.REQUEST, transaction_id=b'\xb1\x1f\xdek(\x9c\x10\xe8\x86\xd1Wn')

DEBUG:ice:Connection(0) protocol(0) < ('66.102.1.127', 19302) Message(message_method=Method.BINDING, message_class=Class.RESPONSE, transaction_id=b'\xb1\x1f\xdek(\x9c\x10\xe8\x86\xd1Wn')

Raw messages:

SDP offer:

v=0

o=- 7142951019689507792 2 IN IP4 127.0.0.1

s=-

t=0 0

a=group:BUNDLE video

a=msid-semantic: WMS

m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 123 127 122 125 107 108 109 124

c=IN IP4 0.0.0.0

a=rtcp:9 IN IP4 0.0.0.0

a=ice-ufrag:A5nH

a=ice-pwd:P0LIjOkkOl/wTtup5n1JA1mC

a=ice-options:trickle

a=fingerprint:sha-256 E3:8E:87:44:E8:D3:A7:02:C0:70:EA:D8:7F:84:F6:80:17:42:33:07:D8:C3:5D:44:FF:DC:25:4C:68:7E:09:19

a=setup:actpass

a=mid:video

a=extmap:2 urn:ietf:params:rtp-hdrext:toffset

a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time

a=extmap:4 urn:3gpp:video-orientation

a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01

a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay

a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type

a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing

a=extmap:10 http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07

a=recvonly

a=rtcp-mux

a=rtcp-rsize

a=rtpmap:96 VP8/90000

a=rtcp-fb:96 goog-remb

a=rtcp-fb:96 transport-cc

a=rtcp-fb:96 ccm fir

a=rtcp-fb:96 nack

a=rtcp-fb:96 nack pli

a=rtpmap:97 rtx/90000

a=fmtp:97 apt=96

a=rtpmap:98 VP9/90000

a=rtcp-fb:98 goog-remb

a=rtcp-fb:98 transport-cc

a=rtcp-fb:98 ccm fir

a=rtcp-fb:98 nack

a=rtcp-fb:98 nack pli

a=fmtp:98 profile-id=0

a=rtpmap:99 rtx/90000

a=fmtp:99 apt=98

a=rtpmap:100 H264/90000

a=rtcp-fb:100 goog-remb

a=rtcp-fb:100 transport-cc

a=rtcp-fb:100 ccm fir

a=rtcp-fb:100 nack

a=rtcp-fb:100 nack pli

a=fmtp:100 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f

a=rtpmap:101 rtx/90000

a=fmtp:101 apt=100

a=rtpmap:102 H264/90000

a=rtcp-fb:102 goog-remb

a=rtcp-fb:102 transport-cc

a=rtcp-fb:102 ccm fir

a=rtcp-fb:102 nack

a=rtcp-fb:102 nack pli

a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f

a=rtpmap:123 rtx/90000

a=fmtp:123 apt=102

a=rtpmap:127 H264/90000

a=rtcp-fb:127 goog-remb

a=rtcp-fb:127 transport-cc

a=rtcp-fb:127 ccm fir

a=rtcp-fb:127 nack

a=rtcp-fb:127 nack pli

a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f

a=rtpmap:122 rtx/90000

a=fmtp:122 apt=127

a=rtpmap:125 H264/90000

a=rtcp-fb:125 goog-remb

a=rtcp-fb:125 transport-cc

a=rtcp-fb:125 ccm fir

a=rtcp-fb:125 nack

a=rtcp-fb:125 nack pli

a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f

a=rtpmap:107 rtx/90000

a=fmtp:107 apt=125

a=rtpmap:108 red/90000

a=rtpmap:109 rtx/90000

a=fmtp:109 apt=108

a=rtpmap:124 ulpfec/90000

SDP answer:

v=0

o=- 3760099490 3760099490 IN IP4 0.0.0.0

s=-

t=0 0

a=group:BUNDLE video

a=msid-semantic:WMS *

m=video 36695 UDP/TLS/RTP/SAVPF 96 97 100 101 127 122

c=IN IP4 147.175.160.240

a=sendonly

a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time

a=mid:video

a=msid:25c4a009-f81c-4fe7-b811-a39c525da778 6ffba6fa-08fb-401f-9555-8df85942bd71

a=rtcp:9 IN IP4 0.0.0.0

a=rtcp-mux

a=ssrc-group:FID 461163217 873864728

a=ssrc:461163217 cname:{af4834d3-8db4-41cc-a9cd-6565cb8d82bd}

a=ssrc:873864728 cname:{af4834d3-8db4-41cc-a9cd-6565cb8d82bd}

a=rtpmap:96 VP8/90000

a=rtcp-fb:96 nack

a=rtcp-fb:96 nack pli

a=rtcp-fb:96 goog-remb

a=rtpmap:97 rtx/90000

a=fmtp:97 apt=96

a=rtpmap:100 H264/90000

a=rtcp-fb:100 nack

a=rtcp-fb:100 nack pli

a=rtcp-fb:100 goog-remb

a=fmtp:100 packetization-mode=1;level-asymmetry-allowed=1;profile-level-id=42001f

a=rtpmap:101 rtx/90000

a=fmtp:101 apt=100

a=rtpmap:127 H264/90000

a=rtcp-fb:127 nack

a=rtcp-fb:127 nack pli

a=rtcp-fb:127 goog-remb

a=fmtp:127 packetization-mode=1;level-asymmetry-allowed=1;profile-level-id=42e01f

a=rtpmap:122 rtx/90000

a=fmtp:122 apt=127

a=candidate:a2cdfa74ef4f12d00d150bfa588cf805 1 udp 2130706431 147.175.160.240 36695 typ host

a=candidate:237395b2276e331724a06e8dbed92f44 1 udp 1694498815 147.175.160.240 36695 typ srflx raddr 147.175.160.240 rport 36695

a=end-of-candidates

a=ice-ufrag:IHJz

a=ice-pwd:RNwQMxbAm2EjNIBxklFZKd

a=fingerprint:sha-256 9B:BB:E0:63:DE:5D:BC:1F:CC:A2:FA:FA:0B:29:EB:F1:46:24:D6:A4:E7:9C:B3:C1:50:9D:A3:FB:83:EC:74:2D

a=setup:active

{"candidate":"candidate:1963203886 1 udp 2113937151 147.175.160.205 36583 typ host generation 0 ufrag A5nH network-cost 999","sdpMid":"video","sdpMLineIndex":0,"type":"candidate"}

服务器代码:

^{pr2}$

前端代码(重要部分):var configuration = { iceServers: [

{urls: 'stun:stun.l.google.com:19302'}]

};

this.pc = new RTCPeerConnection(configuration);

const offerOptions = {

offerToReceiveVideo: 1,

offerToReceiveAudio: 0

};

let offer = this.pc.createOffer(offerOptions);

offer.then(async value => {

await this.pc.setLocalDescription(value);

this.connection.send(JSON.stringify(value))

});

this.connection.onmessage = async event => {

let data = JSON.parse(event.data);

if (data) {

if (data.type === 'offer') {

await this.pc.setRemoteDescription(data);

await this.pc.setLocalDescription(await this.pc.createAnswer());

this.connection.send({ 'desc': this.pc.localDescription }.toString());

} else if (data.type === 'answer') {

await this.pc.setRemoteDescription(data);

}

}

};

this.pc.onnegotiationneeded = async () => {

await this.pc.setLocalDescription(await this.pc.createOffer());

this.connection.send({ 'desc': this.pc.localDescription }.toString());

};

this.pc.onicecandidate = (event) => {

if (event.candidate !== null) {

let data = JSON.parse(JSON.stringify(event.candidate));

data['type'] = 'candidate';

this.connection.send(JSON.stringify(data));

}

};

03-11
### aiortc 库的使用与文档 aiortc 是一个用于 WebRTC 的 Python 实现,它允许开发者创建支持实时通信的应用程序。该库基于 asyncio 并提供了简单易用的 API 来处理音视频流和其他数据传输。 #### 安装 aiortc 要安装 aiortc 可以通过 pip 工具来完成: ```bash pip install aiortc ``` 对于 macOS 用户可能还需要额外安装依赖项如 `av` 和 `opuslib`[^1]。 #### 创建简单的 PeerConnection 下面是一个基本的例子展示如何建立两个节点之间的连接并交换媒体流: ```python import asyncio from aiortc import RTCPeerConnection, RTCSessionDescription from aiortc.contrib.signaling import BYE, TcpSocketSignaling async def main(): pc = RTCPeerConnection() # 处理本地描述符 @pc.on("localdescription") async def on_localdescription(description): await signaling.send(description) # 远程轨道事件处理器 @pc.add_transceiver(&#39;video&#39;).on("track") def on_track(track): print(f"Receiving {track.kind}") # 设置信令服务器 signaling = TcpSocketSignaling("localhost", 8080) await signaling.connect() # 接收远程会话描述 remote_description = await signaling.receive() await pc.setRemoteDescription(RTCSessionDescription(**remote_description)) if isinstance(remote_description, RTCSessionDescription): offer = await pc.createOffer() await pc.setLocalDescription(offer) while True: msg = await signaling.receive() if isinstance(msg, RTCSessionDescription): await pc.setRemoteDescription(msg) answer = await pc.createAnswer() await pc.setLocalDescription(answer) await signaling.send(pc.localDescription) elif msg is BYE: print("Exiting.") break if __name__ == "__main__": try: loop = asyncio.get_event_loop_policy().get_event_loop() loop.run_until_complete(main()) except KeyboardInterrupt: pass ``` 这段代码展示了怎样设置一个完整的 WebRTC 流水线,包括初始化 peer connection 对象、定义回调函数以及管理 SDP 描述和 ICE 候选者消息传递过程中的交互逻辑[^2]。 #### 文档资源 官方 GitHub 页面包含了详细的 README 文件和技术说明文档,可以访问 [aiortc GitHub](https://github.com/aiortc/aiortc) 获取更多信息和支持材料[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值