From c9b7f0ab8ff9803ef57254812a133655321dcea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Birm=C3=A9?= Date: Fri, 28 Jun 2024 20:11:23 +0200 Subject: [PATCH] feat: wip whip answer neg --- src/api_productions_core_functions.ts | 1 - src/connection.ts | 66 +++++++++++++++++++++------ src/smb.ts | 6 +-- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/api_productions_core_functions.ts b/src/api_productions_core_functions.ts index 3fd30ec..44bcac1 100644 --- a/src/api_productions_core_functions.ts +++ b/src/api_productions_core_functions.ts @@ -199,7 +199,6 @@ export class CoreFunctions { ); } - console.log(sdpAnswer); return sdpAnswer; } diff --git a/src/connection.ts b/src/connection.ts index 7d5c9a3..217af94 100644 --- a/src/connection.ts +++ b/src/connection.ts @@ -1,4 +1,5 @@ import { SessionDescription, parse } from 'sdp-transform'; +import { inspect } from 'util'; import { AudioSmbPayloadParameters, @@ -90,6 +91,7 @@ export class Connection { } ]; + console.log('Offer created: ', inspect(offer, { depth: null })); return offer; } @@ -100,6 +102,9 @@ export class Connection { if (!this.endpointDescription['bundle-transport']) { throw new Error('Missing bundle-transport in endpointDescription'); } + if (!this.mediaStreams) { + throw new Error('Missing endpointDescription audio'); + } const transport = this.endpointDescription['bundle-transport']; @@ -113,9 +118,14 @@ export class Connection { const parsedSDP = parse(offer); parsedSDP.origin && parsedSDP.origin.sessionVersion++; + // We are only interested in audio now + parsedSDP.media = parsedSDP.media.filter((media) => media.type == 'audio'); + + let mediaStreamIdx = 0; let bundleGroupMids = ''; for (const media of parsedSDP.media) { + const mediaStreamSsrc = this.mediaStreams.audio.ssrcs[mediaStreamIdx]; bundleGroupMids = bundleGroupMids === '' ? `${media.mid}` @@ -128,8 +138,8 @@ export class Connection { hash: transport.dtls.hash }; media.setup = media.setup === 'actpass' ? 'active' : 'actpass'; - media.ssrcGroups = undefined; - media.ssrcs = undefined; + media.ssrcGroups = []; + media.ssrcs = []; media.msid = undefined; media.port = 9; media.rtcp = { @@ -138,6 +148,26 @@ export class Connection { ipVer: 4, address: '0.0.0.0' }; + media.ssrcs.push({ + id: mediaStreamSsrc.ssrc, + attribute: 'cname', + value: mediaStreamSsrc.cname + }); + media.ssrcs.push({ + id: mediaStreamSsrc.ssrc, + attribute: 'label', + value: mediaStreamSsrc.label + }); + media.ssrcs.push({ + id: mediaStreamSsrc.ssrc, + attribute: 'mslabel', + value: mediaStreamSsrc.mslabel + }); + media.ssrcs.push({ + id: mediaStreamSsrc.ssrc, + attribute: 'msid', + value: `${mediaStreamSsrc.mslabel} ${mediaStreamSsrc.label}` + }); media.candidates = transport.ice.candidates.map((element) => { return { foundation: element.foundation, @@ -153,18 +183,25 @@ export class Connection { 'network-id': element.network }; }); - if (media.type === 'audio') { - media.rtp = media.rtp.filter( - (rtp) => rtp.codec.toLowerCase() === 'opus' - ); - const opusPayloadType = media.rtp.at(0)?.payload; - media.fmtp = media.fmtp.filter( - (fmtp) => fmtp.payload === opusPayloadType - ); - media.payloads = `${opusPayloadType}`; - media.direction = 'recvonly'; - media.rtcpFb = undefined; - } + media.connection = { + version: 4, + ip: '0.0.0.0' + }; + + media.rtp = media.rtp.filter((rtp) => rtp.codec.toLowerCase() === 'opus'); + const opusPayloadType = media.rtp.at(0)?.payload; + media.fmtp = media.fmtp.filter( + (fmtp) => fmtp.payload === opusPayloadType + ); + media.payloads = `${opusPayloadType}`; + media.direction = 'recvonly'; + media.rtcpFb = undefined; + media.ext = this.endpointDescription.audio['rtp-hdrexts'].flatMap( + (element) => { + return { value: element.id, uri: element.uri }; + } + ); + mediaStreamIdx++; } parsedSDP.groups = [ { @@ -173,6 +210,7 @@ export class Connection { } ]; + console.log('Answer negotiated: ', inspect(parsedSDP, { depth: null })); return parsedSDP; } diff --git a/src/smb.ts b/src/smb.ts index 405df35..c516393 100644 --- a/src/smb.ts +++ b/src/smb.ts @@ -20,6 +20,7 @@ interface BaseAllocationRequest { export class SmbProtocol { async allocateConference(smbUrl: string, smbKey: string): Promise { + console.log('Allocate conference', smbUrl); const allocateResponse = await fetch(smbUrl, { method: 'POST', headers: { @@ -70,10 +71,9 @@ export class SmbProtocol { if (idleTimeout) { request['idleTimeout'] = idleTimeout; } - Log().debug(request); const url = smbUrl + conferenceId + '/' + endpointId; - Log().debug(url); + Log().debug('Allocate endpoint', url, request); const response = await fetch(url, { method: 'POST', headers: { @@ -114,7 +114,7 @@ export class SmbProtocol { }, body: JSON.stringify(request) }); - Log().debug(request); + Log().debug('Configure endpoint', url, request); if (!response.ok) { Log().debug(JSON.stringify(request));