• webrtc入门:12.Kurento下的RtpEndpoint和WebrtcEndpoint


    在前面的一个章节,做kms的集群时,引入了RtpEndpoint,这个是一个新的类,我们之前使用的都是WebrtcEndpoint,这两个类有什么区别呢?如果直接用WebrtcEndpoint,能不能实现集群的连通呢。

    我们来看看,文档中的关于几个重要的Endpoint,继承图如下:

    在这里插入图片描述
    但是从详细的文档上来看,RtpEndpointWebrtcEndpoint都是继承BaseRtpEndpoint的。

    从文档上来看,RtpEndpointWebrtcEndpoint应该区别不大,因为他有一个共同的基类BaseRtpEndpoint

    在对比下两者文档的区别:

    RtpEndpoint在这里插入图片描述
    WebRtcEndpoint

    在这里插入图片描述
    从文档上来看,RtpEndpointWebrtcEndpoint 的区别在于 RtpEndpoint可以直接通过SDP就能完成相互的连接,WebrtcEndpoint 要实现连接,不仅仅需要SDP还需要ICE

    也就是RtpEndpoint在设计的时候,就可以通过SDP建立连接,那么在SDP中必将包含着 IP和端口的信息了。

    在源代码kms_sdp_agent_create_offer_impl中可以看到生成的SDP,存在在相应的 IP和端口信息。

    v=0
    o=- 3864705878 3864705878 IN IP4 192.168.100.130
    s=Kurento Media Server
    c=IN IP4 192.168.100.130
    t=0 0
    m=audio 5198 RTP/AVPF 96 0 97
    a=setup:actpass
    a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
    a=rtpmap:96 opus/48000/2
    a=rtpmap:97 AMR/8000
    a=rtcp:5199
    a=sendrecv
    a=mid:audio0
    a=ssrc:1665516295 cname:user345388121@host-4c885f6d
    m=video 1420 RTP/AVPF 102 103
    a=setup:actpass
    a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
    a=rtpmap:102 VP8/90000
    a=rtpmap:103 H264/90000
    a=fmtp:103 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
    a=rtcp:1421
    a=sendrecv
    a=mid:video0
    a=rtcp-fb:102 nack
    a=rtcp-fb:102 nack pli
    a=rtcp-fb:102 goog-remb
    a=rtcp-fb:102 ccm fir
    a=rtcp-fb:103 nack
    a=rtcp-fb:103 nack pli
    a=rtcp-fb:103 ccm fir
    a=ssrc:2557383214 cname:user345388121@host-4c885f6d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    这样两个 RtpEndpoint 就能够协商连接上。

    WebrtcEndpoint 中生成的SDP,并没有包含IP和端口信息,这一点可以继续的跟进kms_sdp_agent_create_offer_impl,看看到底是为什么。这样的协议,是个浏览器的webrtc一样样的。

    那如果使用 WebrtcEndpoint 能否实现集群呢?应该是可以的,但是比起RtpEndpoint自然会复杂一点,因为他涉及到 ICE的步骤了。

    如果也需要,可以用下面的代码进行实现。

      private synchronized void presenter(final WebSocketSession session, JsonObject jsonMessage)
          throws IOException {
        if (presenterUserSession == null) {
          presenterUserSession = new UserSession(session);
    
          pipeline = kurento.createMediaPipeline();
          presenterUserSession.setWebRtcEndpoint(new WebRtcEndpoint.Builder(pipeline).build());
    
          WebRtcEndpoint presenterWebRtc = presenterUserSession.getWebRtcEndpoint();
          
          pipeline_B = kurento.createMediaPipeline();
    
          presenterUserSession.setWebRtcEndpoint_A(new WebRtcEndpoint.Builder(pipeline).build());
          WebRtcEndpoint presenterWebRtc_A = presenterUserSession.getWebRtcEndpoint_A();
          
          presenterUserSession.setWebRtcEndpoint_B(new WebRtcEndpoint.Builder(pipeline_B).build());
          WebRtcEndpoint presenterWebRtc_B = presenterUserSession.getWebRtcEndpoint_B();
    
          presenterUserSession.getWebRtcEndpoint().connect(presenterWebRtc_A);
    
          String offerString = presenterWebRtc_A.generateOffer();
          String sdpAnswerViewer = presenterWebRtc_B.processOffer(offerString);
          presenterWebRtc_A.processAnswer(sdpAnswerViewer);
          log.info(offerString); 
    
          presenterWebRtc_A.addIceCandidateFoundListener(new EventListener<IceCandidateFoundEvent>() {
            @Override
            public void onEvent(IceCandidateFoundEvent event) {
    		log.info("presenterWebRtc_A.addIceCandidateFoundListener");
    		presenterWebRtc_B.addIceCandidate(event.getCandidate());
              }
          });
    
          presenterWebRtc_B.addIceCandidateFoundListener(new EventListener<IceCandidateFoundEvent>() {
            @Override
            public void onEvent(IceCandidateFoundEvent event) {
    		log.info("presenterWebRtc_B.addIceCandidateFoundListener");
    		//presenterWebRtc_A.addIceCandidate(event.getCandidate());
              }
          });
    
          presenterWebRtc.addIceCandidateFoundListener(new EventListener<IceCandidateFoundEvent>() {
    
            @Override
            public void onEvent(IceCandidateFoundEvent event) {
              JsonObject response = new JsonObject();
              response.addProperty("id", "iceCandidate");
              response.add("candidate", JsonUtils.toJsonObject(event.getCandidate()));
              try {
                synchronized (session) {
                  session.sendMessage(new TextMessage(response.toString()));
                }
              } catch (IOException e) {
                log.debug(e.getMessage());
              }
            }
          });
    
          String sdpOffer = jsonMessage.getAsJsonPrimitive("sdpOffer").getAsString();
          String sdpAnswer = presenterWebRtc.processOffer(sdpOffer);
    
          JsonObject response = new JsonObject();
          response.addProperty("id", "presenterResponse");
          response.addProperty("response", "accepted");
          response.addProperty("sdpAnswer", sdpAnswer);
    
          synchronized (session) {
            presenterUserSession.sendMessage(response);
          }
          presenterWebRtc.gatherCandidates();
          presenterWebRtc_A.gatherCandidates();
          presenterWebRtc_B.gatherCandidates();
    
    
        } else {
          JsonObject response = new JsonObject();
          response.addProperty("id", "presenterResponse");
          response.addProperty("response", "rejected");
          response.addProperty("message",
              "Another user is currently acting as sender. Try again later ...");
          session.sendMessage(new TextMessage(response.toString()));
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
  • 相关阅读:
    python中的函数(全)
    CISCO设备信息泄漏漏洞案例
    离子液体1-丁基-3-甲基咪唑六氟磷酸盐(BMI)改性氧化石墨烯(GO)文献摘要
    Kubernetes 控制平面故障期间会发生什么?
    SSE、Webworker 、webSocket、Http、Socket 服务器推送技术
    Flink基础实操-计算单词出现次数
    [UE虚幻引擎插件介绍] DTSQLite 插件说明 :蓝图操作SQLite3文件,执行SQL语句。
    windows安装Oracle19c安装
    【Stable Diffusion】入门-04:不同模型分类+代表作品+常用下载网站+使用技巧
    应用案例|基于三维机器视觉的机器人货品拣选系统应用解决方案
  • 原文地址:https://blog.csdn.net/weixin_40425640/article/details/125444018