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

Android WebRTC设置远程描述报mid='0'错误但Chrome运行正常如何解决?

背景信息
  • 正在尝试构建Android端WebRTC客户端,用于订阅通过NodeJS和JavaScript广播的视频流。
  • 广播端方案在Chrome端运行完全正常:本地访问http://localhost:4000/broadcaster.html无异常,同网络下其他设备访问本机IP也可以近乎实时看到视频画面。
  • 分别用内置摄像头和USB摄像头测试过,JavaScript实现的广播端和Web客户端都可以正常运行,只有Android客户端始终无法正常工作。
当前任务

跑通示例代码后要自己实现对应的Android应用,参考多份教程后,问题始终出现在设置远程描述的步骤,相关代码如下:

private void setRemoteDescription(Object[] arguments) {
    JSONObject message = (JSONObject) arguments[1];
    try {
        String sdp = message.getString("sdp");
        SessionDescription sessionDescription = new SessionDescription(OFFER, sdp);
        peerConnection.setRemoteDescription(new SimpleSdpObserver(), sessionDescription);
    } catch (JSONException e) {
        Log.e(TAG, "setRemoteDescription: failed to parse JSON", e);
    }
}

核心逻辑按教程实现:socket连接成功后会发送"watcher"事件,这一步Android端执行正常,之后服务端返回"offer"事件,客户端监听逻辑如下:

private void bindSocketEvents() {
    socket.on(EVENT_CONNECT, args -> {
        socket.emit("watcher");
    }).on("broadcaster", args -> {
        socket.emit("watcher");
    }).on("offer", args -> {
        setRemoteDescription(args);
        performAnswer();
    }).on("candidate", this::addIceCandidate);
}

收到"offer"事件后会传入JS返回的参数执行设置远程描述的逻辑,但是该操作一直失败。
触发流程时获取到的SDP示例如下:

v=0
o=- 7040957491050894781 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS l91G3Ekmme9tlvEso1ApTqS6djaxtsamgfLu
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:XEnc
a=ice-pwd:2PyQmLOm9YPPf1Pozvonticd
a=ice-options:trickle
a=fingerprint:sha-256 64:22:D7:93:FD:6C:A9:94:E3:65:76:B0:DB:4E:E9:8E:91:46:56:87:B1:E3:E9:B3:24:D0:CF:A5:3F:91:0A:FD
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 urn:3gpp:video-orientation
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:l91G3Ekmme9tlvEso1ApTqS6djaxtsamgfLu 7eb4296c-f3e4-4e95-9f6f-05aa386a3176
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 VP9/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 profile-id=2
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=1;profile-level-id=42001f
a=rtpmap:121 rtx/90000
a=fmtp:121 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=0;profile-level-id=42001f
a=rtpmap:120 rtx/90000
a=fmtp:120 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=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=125
a=rtpmap:108 H264/90000
a=rtcp-fb:108 goog-remb
a=rtcp-fb:108 transport-cc
a=rtcp-fb:108 ccm fir
a=rtcp-fb:108 nack
a=rtcp-fb:108 nack pli
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
a=rtpmap:109 rtx/90000
a=fmtp:109 apt=108
a=rtpmap:35 AV1X/90000
a=rtcp-fb:35 goog-remb
a=rtcp-fb:35 transport-cc
a=rtcp-fb:35 ccm fir
a=rtcp-fb:35 nack
a=rtcp-fb:35 nack pli
a=rtpmap:36 rtx/90000
a=fmtp:36 apt=35
a=rtpmap:124 red/90000
a=rtpmap:119 rtx/90000
a=fmtp:119 apt=124
a=rtpmap:123 ulpfec/90000
a=ssrc-group:FID 4173041010 2470630943
a=ssrc:4173041010 cname:VrEB0NYLt23UUzRD
a=ssrc:4173041010 msid:l91G3Ekmme9tlvEso1ApTqS6djaxtsamgfLu 7eb4296c-f3e4-4e95-9f6f-05aa386a3176
a=ssrc:4173041010 mslabel:l91G3Ekmme9tlvEso1ApTqS6djaxtsamgfLu
a=ssrc:4173041010 label:7eb4296c-f3e4-4e95-9f6f-05aa386a3176
a=ssrc:2470630943 cname:VrEB0NYLt23UUzRD
a=ssrc:2470630943 msid:l91G3Ekmme9tlvEso1ApTqS6djaxtsamgfLu 7eb4296c-f3e4-4e95-9f6f-05aa386a3176
a=ssrc:2470630943 mslabel:l91G3Ekmme9tlvEso1ApTqS6djaxtsamgfLu
a=ssrc:2470630943 label:7eb4296c-f3e4-4e95-9f6f-05aa386a3176
报错信息

设置远程描述时抛出如下错误,后续甚至无法执行peerConnection.createAnswer步骤:

2021-11-12 13:45:52.819 26795-27780/au.com.australiandroid.androidclient D/CustomPeerConnectionObs: onSignalingChange: new signaling state is HAVE_REMOTE_OFFER
2021-11-12 13:45:52.820 26795-27780/au.com.australiandroid.androidclient E/SimpleSdpObserver: onSetFailure: failed to set the remote description: Failed to set remote offer sdp: Failed to set remote video description send parameters for m-section with mid='0'.
2021-11-12 13:45:52.820 26795-27780/au.com.australiandroid.androidclient E/MainActivity: onCreateFailure: failed to create answer: Session error code: ERROR_CONTENT. Session error description: Failed to set remote video description send parameters for m-section with mid='0'..
解决方案

1. 修复异步时序错误

setRemoteDescription是WebRTC的异步操作,当前代码在调用该方法后立刻执行performAnswer(),此时远程描述还未完成设置,信令状态不合法,直接导致后续创建应答失败。
修改方式:把performAnswer()的调用逻辑移到SimpleSdpObserver的onSetSuccess回调中,等远程描述确认设置完成后再生成应答。

2. 修复媒体方向不匹配问题

拿到的广播端SDP里视频的媒体属性是a=sendrecv,也就是广播端同时要收和发视频流,但Android端是纯拉流的订阅端,初始化PeerConnection的时候没有添加本地视频轨道,会导致媒体参数协商失败。
有两种修改方案可选:

  • 调整广播端SDP,把视频的媒体方向从sendrecv改成sendonly,明确广播端只负责发流
  • 初始化Android端PeerConnection时,手动设置媒体协商方向为recvonly,或者临时添加一个空的本地视频轨道到PeerConnection中,满足协商的参数要求。

3. 排查编码兼容问题

如果使用的Android WebRTC SDK版本较低,可能不支持SDP里的AV1编码(也就是pt=35的AV1X格式),可以先在广播端禁用AV1编码,只保留VP8、H264这类兼容性更高的编码格式,排除编码支持导致的协商失败。

按上述三个方向依次调整,即可解决当前的setRemoteDescription报错问题。


内容的提问来源于stack exchange,提问作者Johan Jarvi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:27:03