avstack / gst-meet

Connect GStreamer pipelines to Jitsi Meet conferences
Apache License 2.0
72 stars 25 forks source link

IQ did not successfully parse as Jingle: ParseError("Element transport must not have more than one web-socket child.") #87

Open rodarima opened 1 year ago

rodarima commented 1 year ago

As commented in #69, with the meet.jit.si instance it seems to be a problem when parsing the IQ message, as it contains two web-socket children. I'm using the last commit in master a42e069d282db43fc8ed088db79be1b3ec6a3557 and the issue seems to persist as of 2023-06-24:

% GST_DEBUG=2 gst-meet -v --nick=robot --web-socket-url=wss://meet.jit.si/xmpp-websocket --room-name=testing-gst  --send-pipeline="audiotestsrc wave=sine is-live=true ! audioconvert ! audioresample ! opusenc name=audio"
...
2023-06-24T09:00:31.782511Z DEBUG XMPP    <<< <iq xmlns='jabber:client' to='eff97c0b-100b-4812-ab88-d078db3af7a5@meet.jit.si/_ffC_eFYxhek' type='set' xml:lang='en' from='testing-gst@conference.meet.jit.si/focus' id='ZWZmOTdjMGItMTAwYi00ODEyLWFiODgtZDA3OGRiM2FmN2E1QG1lZXQuaml0LnNpL19mZkNfZUZZeGhlawBGTTdFWi0xOTgwNTg0MwC6iP94aQ/MVg=='><jingle sid='dq1s3ded0k27n' action='session-initiate' xmlns='urn:xmpp:jingle:1' initiator='focus@auth.meet.jit.si/focus'><content creator='initiator' senders='both' name='audio'><description xmlns='urn:xmpp:jingle:apps:rtp:1' media='audio' maxptime='60'><payload-type clockrate='48000' id='111' channels='2' name='opus'><parameter value='10' name='minptime'/><parameter value='1' name='useinbandfec'/><rtcp-fb type='transport-cc' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/></payload-type><payload-type id='126' clockrate='8000' name='telephone-event'/><rtp-hdrext xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0' uri='urn:ietf:params:rtp-hdrext:ssrc-audio-level' id='1'/><rtp-hdrext xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0' uri='http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01' id='5'/><rtcp-mux/><source xmlns='urn:xmpp:jingle:apps:rtp:ssma:0' ssrc='1414071450' name='jvb-a0'><ssrc-info owner='jvb' xmlns='http://jitsi.org/jitmeet'/><parameter xmlns='urn:xmpp:jingle:apps:rtp:1' value='mixedmslabel mixedlabelaudio0' name='msid'/></source></description><transport xmlns='urn:xmpp:jingle:transports:ice-udp:1' ufrag='egn7j1h3ma4bjf' pwd='5r0m6g5qnl5p075geg9og0gr42'><web-socket url='wss://meet.jit.si:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42' xmlns='http://jitsi.org/protocol/colibri'/><web-socket url='wss://meet-jit-si-jvb-42-126-24.jitsi.net:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42' xmlns='http://jitsi.org/protocol/colibri'/><rtcp-mux/><fingerprint required='false' hash='sha-256' setup='actpass' xmlns='urn:xmpp:jingle:apps:dtls:0'>96:94:D5:65:28:19:81:08:FC:C5:C4:59:2E:58:2D:CB:5B:E1:32:FD:EE:B6:D1:8C:0D:F9:49:D0:7D:4C:3C:7D</fingerprint><candidate ip='140.238.69.61' type='srflx' priority='1694498815' id='b413ff7f00adc50fffffffff7dc444d' port='10000' rel-port='9' generation='0' protocol='udp' network='0' foundation='2' component='1' rel-addr='0.0.0.0'/></transport></content><content creator='initiator' senders='both' name='video'><description media='video' xmlns='urn:xmpp:jingle:apps:rtp:1'><payload-type id='100' clockrate='90000' name='VP8'><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='ccm' subtype='fir'/><rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='pli'/><rtcp-fb type='transport-cc' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/></payload-type><payload-type id='107' clockrate='90000' name='H264'><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='ccm' subtype='fir'/><rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='pli'/><rtcp-fb type='transport-cc' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/><parameter value='42e01f;level-asymmetry-allowed=1;packetization-mode=1;' name='profile-level-id'/></payload-type><payload-type id='101' clockrate='90000' name='VP9'><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='ccm' subtype='fir'/><rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='pli'/><rtcp-fb type='transport-cc' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/></payload-type><payload-type id='96' clockrate='90000' name='rtx'><parameter value='100' name='apt'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='ccm' subtype='fir'/><rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='pli'/></payload-type><payload-type id='97' clockrate='90000' name='rtx'><parameter value='101' name='apt'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='ccm' subtype='fir'/><rtcp-fb type='nack' xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0'/><rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='pli'/></payload-type><payload-type id='99' clockrate='90000' name='rtx'><parameter value='107' name='apt'/></payload-type><rtp-hdrext xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0' uri='http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time' id='3'/><rtp-hdrext xmlns='urn:xmpp:jingle:apps:rtp:rtp-hdrext:0' uri='http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01' id='5'/><rtcp-mux/><source xmlns='urn:xmpp:jingle:apps:rtp:ssma:0' ssrc='3249223227' name='jvb-v0'><ssrc-info owner='jvb' xmlns='http://jitsi.org/jitmeet'/><parameter xmlns='urn:xmpp:jingle:apps:rtp:1' value='mixedmslabel mixedlabelvideo0' name='msid'/></source></description><transport xmlns='urn:xmpp:jingle:transports:ice-udp:1' ufrag='egn7j1h3ma4bjf' pwd='5r0m6g5qnl5p075geg9og0gr42'><web-socket url='wss://meet.jit.si:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42' xmlns='http://jitsi.org/protocol/colibri'/><web-socket url='wss://meet-jit-si-jvb-42-126-24.jitsi.net:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42' xmlns='http://jitsi.org/protocol/colibri'/><rtcp-mux/><fingerprint required='false' hash='sha-256' setup='actpass' xmlns='urn:xmpp:jingle:apps:dtls:0'>96:94:D5:65:28:19:81:08:FC:C5:C4:59:2E:58:2D:CB:5B:E1:32:FD:EE:B6:D1:8C:0D:F9:49:D0:7D:4C:3C:7D</fingerprint><candidate ip='140.238.69.61' type='srflx' priority='1694498815' id='b413ff7f00adc50fffffffff7dc444d' port='10000' rel-port='9' generation='0' protocol='udp' network='0' foundation='2' component='1' rel-addr='0.0.0.0'/></transport></content><group xmlns='urn:xmpp:jingle:apps:grouping:0' semantics='BUNDLE'><content name='audio'/><content name='video'/></group><bridge-session xmlns='http://jitsi.org/protocol/focus' region='eu-west-2' id='9283052d-ebda-41c3-98ea-b33eff12429f'/></jingle></iq>
2023-06-24T09:00:31.813099Z DEBUG IQ did not successfully parse as Jingle: ParseError("Element transport must not have more than one web-socket child.")

Here is the message indented with xmllint --format:

<?xml version="1.0"?>
<iq xmlns="jabber:client" to="eff97c0b-100b-4812-ab88-d078db3af7a5@meet.jit.si/_ffC_eFYxhek" type="set" xml:lang="en" from="testing-gst@conference.meet.jit.si/focus" id="ZWZmOTdjMGItMTAwYi00ODEyLWFiODgtZDA3OGRiM2FmN2E1QG1lZXQuaml0LnNpL19mZkNfZUZZeGhlawBGTTdFWi0xOTgwNTg0MwC6iP94aQ/MVg==">
  <jingle xmlns="urn:xmpp:jingle:1" sid="dq1s3ded0k27n" action="session-initiate" initiator="focus@auth.meet.jit.si/focus">
    <content creator="initiator" senders="both" name="audio">
      <description xmlns="urn:xmpp:jingle:apps:rtp:1" media="audio" maxptime="60">
        <payload-type clockrate="48000" id="111" channels="2" name="opus">
          <parameter value="10" name="minptime"/>
          <parameter value="1" name="useinbandfec"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="transport-cc"/>
        </payload-type>
        <payload-type id="126" clockrate="8000" name="telephone-event"/>
        <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" uri="urn:ietf:params:rtp-hdrext:ssrc-audio-level" id="1"/>
        <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" uri="http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01" id="5"/>
        <rtcp-mux/>
        <source xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" ssrc="1414071450" name="jvb-a0">
          <ssrc-info xmlns="http://jitsi.org/jitmeet" owner="jvb"/>
          <parameter xmlns="urn:xmpp:jingle:apps:rtp:1" value="mixedmslabel mixedlabelaudio0" name="msid"/>
        </source>
      </description>
      <transport xmlns="urn:xmpp:jingle:transports:ice-udp:1" ufrag="egn7j1h3ma4bjf" pwd="5r0m6g5qnl5p075geg9og0gr42">
        <web-socket xmlns="http://jitsi.org/protocol/colibri" url="wss://meet.jit.si:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42"/>
        <web-socket xmlns="http://jitsi.org/protocol/colibri" url="wss://meet-jit-si-jvb-42-126-24.jitsi.net:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42"/>
        <rtcp-mux/>
        <fingerprint xmlns="urn:xmpp:jingle:apps:dtls:0" required="false" hash="sha-256" setup="actpass">96:94:D5:65:28:19:81:08:FC:C5:C4:59:2E:58:2D:CB:5B:E1:32:FD:EE:B6:D1:8C:0D:F9:49:D0:7D:4C:3C:7D</fingerprint>
        <candidate ip="140.238.69.61" type="srflx" priority="1694498815" id="b413ff7f00adc50fffffffff7dc444d" port="10000" rel-port="9" generation="0" protocol="udp" network="0" foundation="2" component="1" rel-addr="0.0.0.0"/>
      </transport>
    </content>
    <content creator="initiator" senders="both" name="video">
      <description xmlns="urn:xmpp:jingle:apps:rtp:1" media="video">
        <payload-type id="100" clockrate="90000" name="VP8">
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="ccm" subtype="fir"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack" subtype="pli"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="transport-cc"/>
        </payload-type>
        <payload-type id="107" clockrate="90000" name="H264">
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="ccm" subtype="fir"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack" subtype="pli"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="transport-cc"/>
          <parameter value="42e01f;level-asymmetry-allowed=1;packetization-mode=1;" name="profile-level-id"/>
        </payload-type>
        <payload-type id="101" clockrate="90000" name="VP9">
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="ccm" subtype="fir"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack" subtype="pli"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="transport-cc"/>
        </payload-type>
        <payload-type id="96" clockrate="90000" name="rtx">
          <parameter value="100" name="apt"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="ccm" subtype="fir"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack" subtype="pli"/>
        </payload-type>
        <payload-type id="97" clockrate="90000" name="rtx">
          <parameter value="101" name="apt"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="ccm" subtype="fir"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack"/>
          <rtcp-fb xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0" type="nack" subtype="pli"/>
        </payload-type>
        <payload-type id="99" clockrate="90000" name="rtx">
          <parameter value="107" name="apt"/>
        </payload-type>
        <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" uri="http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time" id="3"/>
        <rtp-hdrext xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0" uri="http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01" id="5"/>
        <rtcp-mux/>
        <source xmlns="urn:xmpp:jingle:apps:rtp:ssma:0" ssrc="3249223227" name="jvb-v0">
          <ssrc-info xmlns="http://jitsi.org/jitmeet" owner="jvb"/>
          <parameter xmlns="urn:xmpp:jingle:apps:rtp:1" value="mixedmslabel mixedlabelvideo0" name="msid"/>
        </source>
      </description>
      <transport xmlns="urn:xmpp:jingle:transports:ice-udp:1" ufrag="egn7j1h3ma4bjf" pwd="5r0m6g5qnl5p075geg9og0gr42">
        <web-socket xmlns="http://jitsi.org/protocol/colibri" url="wss://meet.jit.si:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42"/>
        <web-socket xmlns="http://jitsi.org/protocol/colibri" url="wss://meet-jit-si-jvb-42-126-24.jitsi.net:443/colibri-ws/jvb-42-126-24/9f94e557105628db/eff97c0b?pwd=5r0m6g5qnl5p075geg9og0gr42"/>
        <rtcp-mux/>
        <fingerprint xmlns="urn:xmpp:jingle:apps:dtls:0" required="false" hash="sha-256" setup="actpass">96:94:D5:65:28:19:81:08:FC:C5:C4:59:2E:58:2D:CB:5B:E1:32:FD:EE:B6:D1:8C:0D:F9:49:D0:7D:4C:3C:7D</fingerprint>
        <candidate ip="140.238.69.61" type="srflx" priority="1694498815" id="b413ff7f00adc50fffffffff7dc444d" port="10000" rel-port="9" generation="0" protocol="udp" network="0" foundation="2" component="1" rel-addr="0.0.0.0"/>
      </transport>
    </content>
    <group xmlns="urn:xmpp:jingle:apps:grouping:0" semantics="BUNDLE">
      <content name="audio"/>
      <content name="video"/>
    </group>
    <bridge-session xmlns="http://jitsi.org/protocol/focus" region="eu-west-2" id="9283052d-ebda-41c3-98ea-b33eff12429f"/>
  </jingle>
</iq>

I assume this is a problem related with the xmpp-rs parser. As a workaround I was trying to remove one of the web-socket children (similar to a42e069d282db43fc8ed088db79be1b3ec6a3557), but I'm not familiar with the xmpp API and I'm not very fluent in rust.

rodarima commented 1 year ago

I was able to work around it by using these two patches:

First it seems there is a missing argument in gstmeet_connection_new():

From f775b23102f50bb9a776e9001c3c103d02447f32 Mon Sep 17 00:00:00 2001
From: Rodrigo Arias Mallo <rodarima@gmail.com>
Date: Sat, 24 Jun 2023 11:34:37 +0200
Subject: [PATCH 1/2] Add room name argument in gstmeet_connection_new()

---
 lib-gst-meet-c/src/lib.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib-gst-meet-c/src/lib.rs b/lib-gst-meet-c/src/lib.rs
index 9d4be2d..2eb4f65 100644
--- a/lib-gst-meet-c/src/lib.rs
+++ b/lib-gst-meet-c/src/lib.rs
@@ -80,16 +80,19 @@ pub unsafe extern "C" fn gstmeet_connection_new(
   context: *mut Context,
   websocket_url: *const c_char,
   xmpp_domain: *const c_char,
+  room_name: *const c_char,
   tls_insecure: bool,
 ) -> *mut Connection {
   let websocket_url = CStr::from_ptr(websocket_url);
   let xmpp_domain = CStr::from_ptr(xmpp_domain);
+  let room_name = CStr::from_ptr(room_name);
   (*context)
     .runtime
     .block_on(Connection::new(
       &websocket_url.to_string_lossy(),
       &xmpp_domain.to_string_lossy(),
       Authentication::Anonymous,
+      &room_name.to_string_lossy(),
       tls_insecure,
     ))
     .map(|(connection, background)| {
-- 
2.41.0

And here I just parse it as a vector and then take the first element.

From fe38d5f87173595848f1a5e1f442bb0822093f59 Mon Sep 17 00:00:00 2001
From: Rodrigo Arias Mallo <rodarima@gmail.com>
Date: Sat, 24 Jun 2023 11:33:18 +0200
Subject: [PATCH 2/2] Parse web-socket as a list

For now only the first element is considered.
---
 jitsi-xmpp-parsers/src/jingle_ice_udp.rs | 2 +-
 lib-gst-meet/src/jingle.rs               | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/jitsi-xmpp-parsers/src/jingle_ice_udp.rs b/jitsi-xmpp-parsers/src/jingle_ice_udp.rs
index 39fc660..fb1a48a 100644
--- a/jitsi-xmpp-parsers/src/jingle_ice_udp.rs
+++ b/jitsi-xmpp-parsers/src/jingle_ice_udp.rs
@@ -24,7 +24,7 @@ generate_element!(
     fingerprint: Option<Fingerprint> = ("fingerprint", JINGLE_DTLS) => Fingerprint,

     /// Details of the Colibri WebSocket
-    web_socket: Option<WebSocket> = ("web-socket", JITSI_COLIBRI) => WebSocket
+    web_socket: Vec<WebSocket> = ("web-socket", JITSI_COLIBRI) => WebSocket
   ]
 );

diff --git a/lib-gst-meet/src/jingle.rs b/lib-gst-meet/src/jingle.rs
index 27479ca..0b94982 100644
--- a/lib-gst-meet/src/jingle.rs
+++ b/lib-gst-meet/src/jingle.rs
@@ -1466,7 +1466,7 @@ impl JingleSession {
       remote_ssrc_map,
       _ice_agent: ice_agent,
       accept_iq_id: Some(accept_iq_id),
-      colibri_url: ice_transport.web_socket.clone().map(|ws| ws.url),
+      colibri_url: ice_transport.web_socket.first().map(|ws| ws.url.clone()),
       colibri_channel: None,
       stats_handler_task: None,
       pipeline_state_null_rx,
-- 
2.41.0

However I don't listen anything from the browser, although at least the "robot" participant appears unmuted and with the opus codec for audio. Maybe I'm messing something up with the gst pipeline. I attached the whole log with:

% GST_DEBUG=2 target/debug/gst-meet -v --nick=robot --web-socket-url=wss://meet.jit.si/xmpp-websocket --room-name=testing-gst  --send-pipeline="audiotestsrc wave=sine is-live=true ! audioconvert ! audioresample ! opusenc name=audio" >log.txt 2>&1

log.txt

rodarima commented 1 year ago

Nevermind, the audio was a problem of Firefox. In Chromium and on my phone is working fine with the above patches!

jbg commented 6 months ago

Thanks for the patches. I noticed that lib-jitsi-meet has some special handling for the fact that JaaS returns more than one web-socket, but instead of taking the first they are filtering them out based on the domain. I'm going to copy that behaviour here to improve compatibility with JaaS.

daimoc commented 5 months ago

Hi @jbg , do you have any update on this patch integration ? The last gst-met still have this error when I test it with meet.jit.si.