WebRTC:收到数据包,但视频未显示

问题描述 投票:0回答:1

我有一个用 C++ 和

libdatachannel
构建的“媒体服务器”,用于通过 WebRTC 接收视频流。它提供简单的信令协议,客户端必须发送要约以接收视频,然后将获得通过对等连接发送的 VP9 数据包。 在我的 C++ 客户端中接收流工作正常,但我无法让它在浏览器(Chrome 和 Firefox)中工作。以下信息均基于Chrome。

当服务器在本地运行时,浏览器客户端似乎已连接,但根据

chrome://webrtc-internals/
,似乎没有实际收到任何数据包,至少在
Stats tables
部分中没有成功的候选对。

enter image description here enter image description here

当服务器远程运行时,浏览器客户端似乎已连接,并且我看到收到了字节:

enter image description here enter image description here

但是,在这两种情况下,都没有显示视频(

play()
返回的承诺永远不会解决),我无法弄清楚问题到底出在哪里。尝试连接的 JS 代码是这样的:

<!doctype html>
<title>test js browser client</title>
<section class="content">

    <title>WebRTC test with WebSocket signalling</title>
    <video id="video-element" muted height="200" width="300"></video>

    <p>Mediaserver IP</p>
    <input type="text" id="ip_input" name="input" required minlength="7" size="10" value="46.4.38.241"/>

    <p>Topic</p>
    <input type="text" id="topic_input" name="input" required minlength="1" size="10" value="foobar"/>

    <input type="button" id="button" value="Start stream" />
    <p>Status: <div id="errmsg"></div></p>

    <script>
        document.getElementById("button").onclick=function() {
            const topic = document.getElementById('topic_input').value;
            const mediaserver_ip = document.getElementById('ip_input').value;
            if (topic == "") {
                return
            }

            const videoElement = document.getElementById('video-element');

            // make a new peer connection
            const pc = new RTCPeerConnection({
                // Recommended for libdatachannel
                bundlePolicy: 'max-bundle',
            });

            pc.addTransceiver('video', { direction: 'recvonly' });
            if (!RTCRtpSender.getCapabilities) {
                console.log("RTCRtpSender has no capabilities")
                return
            };

            const { codecs } = RTCRtpSender.getCapabilities('video');
            const [ transceiver ] = pc.getTransceivers();

            const vp9_profile_2 = codecs.find(c => c.mimeType === 'video/VP9' );
            if (vp9_profile_2 && transceiver.setCodecPreferences) {
                transceiver.setCodecPreferences([ vp9_profile_2 ]);
            } else {
                console.log("No vp9 profile or cannot set preferences")
            }
            pc.createOffer({offerToReceiveVideo:1}).then((offer) => {
                console.log("Local offer: ", offer)
                pc.setLocalDescription(offer);

                var websock = new WebSocket("ws://" + mediaserver_ip + ":8080");

                window.onbeforeunload = function() {
                    pc.close();
                    websock.close();
                    return null;
                }

                websock.onopen = function(evt) {
                    websock.send(JSON.stringify({"sdp": pc.localDescription["sdp"], "topic": topic,
                        "direction": "receiver"}));
                }

                websock.onmessage = function(evt) {
                    reply = JSON.parse(evt.data)
                    console.log(`Server reply: ${evt.data}`)
                    const status = reply["ok"]
                    if (status != true) {
                        document.getElementById("topic_input").style.border = "1px solid #FF0000"
                        document.getElementById("errmsg").value = reply["error"]
                        return
                    } else
                    {
                        document.getElementById("topic_input").style.border = "1px solid #00FF00"
                    }
                    console.log("Setting remote response: ", reply["sdp"]);
                    reply.type = "answer"
                    pc.setRemoteDescription(new RTCSessionDescription(reply));
                };


            });

            pc.ontrack = (evt) => {
                const videoElement = document.getElementById('video-element');
                videoElement.srcObject = evt.streams[0];
                videoElement.play();
            };

        };
    </script>
</section>

举个例子,服务器收到的浏览器的SDP是

v=0
o=- 8335876533502472473 0 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=group:LS 0
a=msid-semantic:WMS *
a=ice-options:trickle
a=fingerprint:sha-256 7A:E0:F7:6B:15:A7:DE:EA:B6:35:3F:44:DA:F1:F4:7B:CD:D4:24:61:FB:81:4D:D4:4D:5A:CE:E2:AA:3B:C8:28
a=group:BUNDLE 0
a=group:LS 0
a=msid-semantic:WMS *
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS
m=video 9 UDP/TLS/RTP/SAVPF 98
c=IN IP4 0.0.0.0
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=recvonly
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-rsize
a=rtcp-mux
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=setup:actpass
a=ice-ufrag:iIYk
a=ice-pwd:MM67D85LOn4AGaJqrZoJHJlT
a=candidate:37153457 1 udp 2113937151 633dd8b6-dae3-487d-bec3-0e24144442f6.local 61230 typ host generation 0 network-cost 999
a=candidate:3216145886 1 udp 2113939711 bd134863-1992-4778-bd10-6562b4866557.local 49342 typ host generation 0 network-cost 999

服务器的响应是

v=0
o=rtc 391121705 0 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=group:LS 0
a=msid-semantic:WMS *
a=ice-options:ice2,trickle
a=fingerprint:sha-256 A2:73:8F:40:D0:64:77:8C:D2:56:61:4F:13:44:7A:3F:BC:79:0B:59:5F:72:06:89:E0:57:2D:B0:66:4B:A0:8F
m=video 7141 UDP/TLS/RTP/SAVPF 98
c=IN IP4 46.4.38.241
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=sendonly
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
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=setup:active
a=ice-ufrag:fDod
a=ice-pwd:k0MMaKc0pxVr9rF8lgbO0/
a=candidate:3 1 UDP 2130705919 2a01:4f8:221:3081::2 7141 typ host
a=candidate:1 1 UDP 2122317823 46.4.38.241 7141 typ host
a=candidate:2 1 UDP 2122317567 172.19.0.1 7141 typ host
a=end-of-candidates

我的问题是:

  • 为什么尽管有传入的 RTP 数据包,我在浏览器中却看不到显示的视频?这可能与传入 RTP 数据包的有效负载类型或 ssrc 有关吗?
  • 为什么当服务器在本地主机上运行时我收不到任何数据包,但当它在云中某处运行时却收到任何数据包?
javascript c++ google-chrome webrtc libdatachannel
1个回答
0
投票

至少对于这个特定情况,答案是我没有在这个特定代码路径的发送者(服务器)轨道上添加 SSRC。

据我所知,ssrc 应该由发送流数据的任何人添加到轨道中。

不确定如何从 SDP 或 chrome webrtc 日志记录中看出这一点。

© www.soinside.com 2019 - 2024. All rights reserved.