Skip to content

Commit

Permalink
feat: wip whip connection established
Browse files Browse the repository at this point in the history
  • Loading branch information
birme committed Jun 28, 2024
1 parent c9b7f0a commit 38356a0
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 118 deletions.
82 changes: 22 additions & 60 deletions src/api_productions_core_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,73 +110,35 @@ export class CoreFunctions {
endpointId
);

const parsedOffer = parse(offer);
const answer: SessionDescription = connection.createAnswer(offer);
const sdpAnswer: string = write(answer);

if (sdpAnswer) {
const answerMediaDescription = answer.media[0];
if (!answerMediaDescription) {
throw new Error(
'Missing audio media description when handling SDP answer from offer'
);
}
if (answer.media[1].ssrcs) {
let parsedSsrcs = answer.media[1].ssrcs[0].id;
if (typeof parsedSsrcs === 'string') {
parsedSsrcs = parseInt(parsedSsrcs, 10);
for (const media of parsedOffer.media) {
if (media.type === 'audio') {
endpointDescription.audio.ssrcs = [];
media.ssrcs &&
media.ssrcs
.filter((ssrcs) => ssrcs.attribute === 'msid')
.forEach((ssrcs) =>
endpointDescription.audio.ssrcs.push(parseInt(`${ssrcs.id}`))
);
}
endpointDescription.audio.ssrcs.push(parsedSsrcs);
}
if (endpointDescription.audio.ssrcs.length === 0) {
throw new Error(
'Missing audio ssrcs when handling SDP answer from offer'
);
}
const transport = endpointDescription['bundle-transport'];
if (!transport) {
throw new Error(
'Missing endpointDescription when handling SDP answer from offer'
);
}
if (!transport.dtls) {
throw new Error('Missing dtls when handling SDP answer from offer');
}
if (!transport.ice) {
throw new Error('Missing ice when handling SDP answer from offer');
}
const answerFingerprint = answer.fingerprint
? answer.fingerprint
: answerMediaDescription.fingerprint;
if (!answerFingerprint) {
throw new Error(
'Missing answerFingerprint when handling sdp answer from endpoint'
);
for (const media of answer.media) {
if (media.type === 'audio') {
endpointDescription.audio['payload-type'].id = media.rtp[0].payload;
endpointDescription.audio['rtp-hdrexts'] = [];
media.ext &&
media.ext.forEach((ext: any) =>

Check warning on line 134 in src/api_productions_core_functions.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
endpointDescription.audio['rtp-hdrexts'].push({
id: ext.value,
uri: ext.uri
})
);
}
}
transport.dtls.type = answerFingerprint.type;
transport.dtls.hash = answerFingerprint.hash;
transport.dtls.setup = answerMediaDescription.setup || '';
transport.ice.ufrag = this.toStringIfNumber(
answerMediaDescription.iceUfrag
);
transport.ice.pwd = answerMediaDescription.icePwd || '';
transport.ice.candidates = !answerMediaDescription.candidates
? []
: answerMediaDescription.candidates.flatMap((element) => {
return {
generation: element.generation ? element.generation : 0,
component: element.component,
protocol: element.transport.toLowerCase(),
port: element.port,
ip: element.ip,
relPort: element.rport,
relAddr: element.raddr,
foundation: element.foundation.toString(),
priority: parseInt(element.priority.toString(), 10),
type: element.type,
network: element['network-id']
};
});

// Configure endpoint
await smb.configureEndpoint(
smbServerUrl,
Expand Down
1 change: 1 addition & 0 deletions src/api_whip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const apiWhip: FastifyPluginCallback<ApiWhipOptions> = (
});
reply.code(201).send(sdpAnswer);
} catch (err) {
console.error(err);
reply.code(500).send({ message: 'Unhandled error: ' + err });
}
}
Expand Down
100 changes: 42 additions & 58 deletions src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ 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'];

Expand All @@ -116,16 +113,14 @@ export class Connection {
}

const parsedSDP = parse(offer);
parsedSDP.origin && parsedSDP.origin.sessionVersion++;
console.log('Offer received: ', inspect(parsedSDP, { depth: null }));

// We are only interested in audio now
parsedSDP.media = parsedSDP.media.filter((media) => media.type == 'audio');
parsedSDP.origin && parsedSDP.origin.sessionVersion++;

let mediaStreamIdx = 0;
let bundleGroupMids = '';
let candidatesAdded = false;

for (const media of parsedSDP.media) {
const mediaStreamSsrc = this.mediaStreams.audio.ssrcs[mediaStreamIdx];
bundleGroupMids =
bundleGroupMids === ''
? `${media.mid}`
Expand All @@ -139,7 +134,6 @@ export class Connection {
};
media.setup = media.setup === 'actpass' ? 'active' : 'actpass';
media.ssrcGroups = [];
media.ssrcs = [];
media.msid = undefined;
media.port = 9;
media.rtcp = {
Expand All @@ -148,60 +142,50 @@ 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,
component: element.component,
transport: element.protocol,
priority: element.priority,
ip: element.ip,
port: element.port,
type: element.type,
raddr: element['rel-addr'],
rport: element['rel-port'],
generation: element.generation,
'network-id': element.network
};
});
media.ssrcs = [];
if (!candidatesAdded) {
media.candidates = transport.ice.candidates.map((element) => {
return {
foundation: element.foundation,
component: element.component,
transport: element.protocol,
priority: element.priority,
ip: element.ip,
port: element.port,
type: element.type,
raddr: element['rel-addr'],
rport: element['rel-port'],
generation: element.generation,
'network-id': element.network
};
});
candidatesAdded = true;
}
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++;
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.ext =
media.ext &&
media.ext.filter(
(ext) =>
ext.uri === 'urn:ietf:params:rtp-hdrext:ssrc-audio-level' ||
ext.uri ===
'http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time'
);
}
}
parsedSDP.groups = [
{
Expand Down

0 comments on commit 38356a0

Please sign in to comment.