# HG changeset patch # User Goffi # Date 1696339552 -7200 # Node ID b2709504586aa6a50fae2ca19c1dacacf94db71d # Parent 832a7bdb3aeaa6babec4f55627dcf18c88ba1aab plugin XEP-0167: mapping adjustments: - use `9` as port placeholder - add `a=ice-options:trickle` to indicate that ICE candidates may be sent after SDP - moved senders mapping at media level - fix `rtpmap` channel setting - don't overwrite existing `fingerprint` data rel 424 diff -r 832a7bdb3aea -r b2709504586a libervia/backend/plugins/plugin_xep_0167/mapping.py --- a/libervia/backend/plugins/plugin_xep_0167/mapping.py Tue Oct 03 15:20:00 2023 +0200 +++ b/libervia/backend/plugins/plugin_xep_0167/mapping.py Tue Oct 03 15:25:52 2023 +0200 @@ -44,7 +44,7 @@ def generate_sdp_from_session( - session: dict, local: bool = False, port: int = 9999 + session: dict, local: bool = False, port: int = 9 ) -> str: """Generate an SDP string from session data. @@ -78,6 +78,7 @@ @return: The generated SDP string. """ + contents = session["contents"] sdp_lines = ["v=0"] # Add originator (o=) line after the version (v=) line @@ -101,10 +102,9 @@ all_senders = {c["senders"] for c in session["contents"].values()} # if we don't have a common senders for all contents, we set them at media level senders = all_senders.pop() if len(all_senders) == 1 else None - if senders is not None: - sdp_lines.append(senders_to_sdp(senders, session)) sdp_lines.append("a=msid-semantic:WMS *") + sdp_lines.append("a=ice-options:trickle") host.trigger.point( "XEP-0167_generate_sdp_session", @@ -114,7 +114,6 @@ triggers_no_cancel=True ) - contents = session["contents"] for content_name, content_data in contents.items(): app_data_key = "local_data" if local else "peer_data" application_data = content_data["application_data"] @@ -131,16 +130,25 @@ sdp_lines.append(f"c={network_type} {address_type} {connection_address}") sdp_lines.append(f"a=mid:{content_name}") + if senders is not None: + sdp_lines.append(senders_to_sdp(senders, session)) # stream direction if senders is None: sdp_lines.append(senders_to_sdp(content_data["senders"], session)) + # Generate a= lines for rtpmap and fmtp for pt_id, pt in payload_types.items(): name = pt["name"] clockrate = pt.get("clockrate", "") - sdp_lines.append(f"a=rtpmap:{pt_id} {name}/{clockrate}") + + # Check if "channels" is in pt and append it to the line + channels = pt.get("channels") + if channels: + sdp_lines.append(f"a=rtpmap:{pt_id} {name}/{clockrate}/{channels}") + else: + sdp_lines.append(f"a=rtpmap:{pt_id} {name}/{clockrate}") if "ptime" in pt: sdp_lines.append(f"a=ptime:{pt['ptime']}") @@ -383,7 +391,9 @@ algorithm, fingerprint = parts[0], parts[1] fingerprint_data = {"hash": algorithm, "fingerprint": fingerprint} if transport_data is not None: - transport_data["fingerprint"] = fingerprint_data + transport_data.setdefault("fingerprint", {}).update( + fingerprint_data + ) elif attribute == "setup": assert transport_data is not None setup = parts[0] @@ -429,6 +439,7 @@ log.debug(f"cleaning remaining private data {key!r}") del call_data[key] + # FIXME: is this really useful? # ICE candidates may only be specified for the first media, this # duplicate the candidate for the other in this case all_media = {k:v for k,v in call_data.items() if k in ("audio", "video")}