Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 018e8cf

Browse files
authored
Add support for single peer connection (#418)
* Associate track with media stream when publishing in conference * Add MID based processing in SDP utils * Add dependency to support async/await and update package.json * Initial version for single PC only client * Remove unnecessary dependency * Add close for channel and ended event for publication/subscription * Fix undefined error when subscription ended * Fire channel ended event and clear media stream when stopped * Fix publication/subscription events handling * Add new interface for client SDK * Revert "Add new interface for client SDK" This reverts commit 4acba72. * Fix some dispatching events and address comments * Fix eslinet errors and warnings * Fix ci failures * Fix eslint errors * Avoid cleaning when pc is closed * Fix events and subscription codecs * Hide track ID for subscribing simulcast stream * Change transport in signaling * Refine sdp promises
1 parent eefa940 commit 018e8cf

File tree

8 files changed

+1183
-512
lines changed

8 files changed

+1183
-512
lines changed

package-lock.json

Lines changed: 455 additions & 164 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
],
1919
"devDependencies": {
2020
"@babel/core": "^7.11.6",
21+
"@babel/plugin-transform-runtime": "^7.12.1",
2122
"@babel/preset-env": "^7.11.5",
23+
"@babel/runtime": "^7.12.1",
2224
"babelify": "^10.0.0",
2325
"chai": "^4.2.0",
2426
"chai-as-promised": "^7.1.1",

scripts/Gruntfile.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ window.L = L;\n\
5151
debug: false
5252
},
5353
transform: [
54-
["babelify", { "presets": ["@babel/preset-env"] }]
54+
["babelify", { "presets": ["@babel/preset-env"], "plugins": [["@babel/plugin-transform-runtime"]] }]
5555
]
5656
},
5757
},
@@ -64,7 +64,7 @@ window.L = L;\n\
6464
debug: true
6565
},
6666
transform: [
67-
["babelify", { "presets": ["@babel/preset-env"] }]
67+
["babelify", { "presets": ["@babel/preset-env"], "plugins": [["@babel/plugin-transform-runtime"]] }]
6868
],
6969
watch: true
7070
},

src/sdk/base/publication.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export class AudioPublicationSettings {
3333
*/
3434
export class VideoPublicationSettings {
3535
// eslint-disable-next-line require-jsdoc
36-
constructor(codec, resolution, frameRate, bitrate, keyFrameInterval, rid) {
36+
constructor(codec, resolution, frameRate,
37+
bitrate, keyFrameInterval, rid) {
3738
/**
3839
* @member {?Owt.Base.VideoCodecParameters} codec
3940
* @instance

src/sdk/base/sdputils.js

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,20 @@ function maybePreferCodec(sdp, type, dir, codec) {
353353
}
354354

355355
// Set fmtp param to specific codec in SDP. If param does not exists, add it.
356-
function setCodecParam(sdp, codec, param, value) {
356+
function setCodecParam(sdp, codec, param, value, mid) {
357357
let sdpLines = sdp.split('\r\n');
358+
let headLines = null;
359+
let tailLines = null;
360+
if (typeof mid === 'string') {
361+
const midRange = findMLineRangeWithMID(sdpLines, mid);
362+
if (midRange) {
363+
const { start, end } = midRange;
364+
headLines = sdpLines.slice(0, start);
365+
tailLines = sdpLines.slice(end);
366+
sdpLines = sdpLines.slice(start, end);
367+
}
368+
}
369+
358370
// SDPs sent from MCU use \n as line break.
359371
if (sdpLines.length <= 1) {
360372
sdpLines = sdp.split('\n');
@@ -379,6 +391,9 @@ function setCodecParam(sdp, codec, param, value) {
379391
sdpLines[fmtpLineIndex] = writeFmtpLine(fmtpObj);
380392
}
381393

394+
if (headLines) {
395+
sdpLines = headLines.concat(sdpLines).concat(tailLines);
396+
}
382397
sdp = sdpLines.join('\r\n');
383398
return sdp;
384399
}
@@ -553,10 +568,40 @@ function removeCodecFramALine(sdpLines, payload) {
553568
return sdpLines;
554569
}
555570

571+
// Find m-line and next m-line with give mid, return { start, end }.
572+
function findMLineRangeWithMID(sdpLines, mid) {
573+
const midLine = 'a=mid:' + mid;
574+
let midIndex = findLine(sdpLines, midLine);
575+
// Compare the whole line since findLine only compares prefix
576+
while (midIndex >= 0 && sdpLines[midIndex] !== midLine) {
577+
midIndex = findLineInRange(sdpLines, midIndex, -1, midLine);
578+
}
579+
if (midIndex >= 0) {
580+
// Found matched a=mid line
581+
const nextMLineIndex = (findLineInRange(sdpLines, midIndex, -1, 'm=')
582+
|| -1);
583+
let mLineIndex = -1;
584+
for (let i = midIndex; i >= 0; i--) {
585+
if (sdpLines[i].indexOf('m=') >= 0) {
586+
mLineIndex = i;
587+
break;
588+
}
589+
}
590+
if (mLineIndex >= 0) {
591+
return {
592+
start: mLineIndex,
593+
end: nextMLineIndex
594+
};
595+
}
596+
}
597+
return null;
598+
}
599+
556600
// Reorder codecs in m-line according the order of |codecs|. Remove codecs from
557601
// m-line if it is not present in |codecs|
602+
// Applied on specific m-line if mid is presented
558603
// The format of |codec| is 'NAME/RATE', e.g. 'opus/48000'.
559-
export function reorderCodecs(sdp, type, codecs) {
604+
export function reorderCodecs(sdp, type, codecs, mid) {
560605
if (!codecs || codecs.length === 0) {
561606
return sdp;
562607
}
@@ -565,6 +610,17 @@ export function reorderCodecs(sdp, type, codecs) {
565610
videoCodecAllowList);
566611

567612
let sdpLines = sdp.split('\r\n');
613+
let headLines = null;
614+
let tailLines = null;
615+
if (typeof mid === 'string') {
616+
const midRange = findMLineRangeWithMID(sdpLines, mid);
617+
if (midRange) {
618+
const { start, end } = midRange;
619+
headLines = sdpLines.slice(0, start);
620+
tailLines = sdpLines.slice(end);
621+
sdpLines = sdpLines.slice(start, end);
622+
}
623+
}
568624

569625
// Search for m line.
570626
const mLineIndex = findLine(sdpLines, 'm=', type);
@@ -599,17 +655,32 @@ export function reorderCodecs(sdp, type, codecs) {
599655
}
600656
}
601657

658+
if (headLines) {
659+
sdpLines = headLines.concat(sdpLines).concat(tailLines);
660+
}
602661
sdp = sdpLines.join('\r\n');
603662
return sdp;
604663
}
605664

606665
// Add legacy simulcast.
607-
export function addLegacySimulcast(sdp, type, numStreams) {
666+
export function addLegacySimulcast(sdp, type, numStreams, mid) {
608667
if (!numStreams || !(numStreams > 1)) {
609668
return sdp;
610669
}
611670

612671
let sdpLines = sdp.split('\r\n');
672+
let headLines = null;
673+
let tailLines = null;
674+
if (typeof mid === 'string') {
675+
const midRange = findMLineRangeWithMID(sdpLines, mid);
676+
if (midRange) {
677+
const { start, end } = midRange;
678+
headLines = sdpLines.slice(0, start);
679+
tailLines = sdpLines.slice(end);
680+
sdpLines = sdpLines.slice(start, end);
681+
}
682+
}
683+
613684
// Search for m line.
614685
const mLineStart = findLine(sdpLines, 'm=', type);
615686
if (mLineStart === null) {
@@ -681,16 +752,19 @@ export function addLegacySimulcast(sdp, type, numStreams) {
681752
sdpLines.splice(insertPos, 0, ...simLines);
682753
sdpLines = sdpLines.filter(line => !removes.has(line));
683754

755+
if (headLines) {
756+
sdpLines = headLines.concat(sdpLines).concat(tailLines);
757+
}
684758
sdp = sdpLines.join('\r\n');
685759
return sdp;
686760
}
687761

688-
export function setMaxBitrate(sdp, encodingParametersList) {
762+
export function setMaxBitrate(sdp, encodingParametersList, mid) {
689763
for (const encodingParameters of encodingParametersList) {
690764
if (encodingParameters.maxBitrate) {
691765
sdp = setCodecParam(
692766
sdp, encodingParameters.codec.name, 'x-google-max-bitrate',
693-
(encodingParameters.maxBitrate).toString());
767+
(encodingParameters.maxBitrate).toString(), mid);
694768
}
695769
}
696770
return sdp;

0 commit comments

Comments
 (0)