Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Multi-streamer QOL improvements #88

Merged
merged 8 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ node_modules/
**/platform_scripts/bash/*/
node.zip
SignallingWebServer/Public/
SignallingWebServer/certificates
.vscode
21 changes: 9 additions & 12 deletions Frontend/library/src/Config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,18 +463,6 @@ export class Config {
this.numericParameters.get(NumericParameters.AFKTimeoutSecs)
);

const preferredCodecOption = this.optionParameters.get(
OptionParameters.PreferredCodec
);
this.addSettingOption(psSettingsSection, preferredCodecOption);
if (
[...preferredCodecOption.selector.options]
.map((o) => o.value)
.includes('Only available on Chrome')
) {
preferredCodecOption.disable();
}

/* Setup all view/ui related settings under this section */
const viewSettingsSection = this.buildSectionWithHeading(
settingsElem,
Expand Down Expand Up @@ -512,6 +500,15 @@ export class Config {
this.numericParameters.get(NumericParameters.MaxQP)
);

const preferredCodecOption = this.optionParameters.get(OptionParameters.PreferredCodec);
this.addSettingOption(
encoderSettingsSection,
preferredCodecOption
);
if([...preferredCodecOption.selector.options].map(o => o.value).includes("Only available on Chrome")) {
preferredCodecOption.disable();
}

/* Setup all webrtc related settings under this section */
const webrtcSettingsSection = this.buildSectionWithHeading(
settingsElem,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ export class PeerConnectionController {
preferredCodec: string
) {
this.config = config;
this.createPeerConnection(options, preferredCodec);
}

createPeerConnection(options: RTCConfiguration, preferredCodec: string) {
// Set the ICE transport to relay if TURN enabled
if (config.isFlagEnabled(Flags.ForceTURN)) {
if (this.config.isFlagEnabled(Flags.ForceTURN)) {
options.iceTransportPolicy = 'relay';
Logger.Log(
Logger.GetStackTrace(),
Expand Down Expand Up @@ -176,12 +179,8 @@ export class PeerConnectionController {
this.onVideoStats(this.aggregatedStats);

// Update the preferred codec selection based on what was actually negotiated
if (this.updateCodecSelection) {
this.config.getSettingOption(
OptionParameters.PreferredCodec
).selected = this.aggregatedStats.codecs.get(
this.aggregatedStats.inboundVideoStats.codecId
);
if(this.updateCodecSelection) {
this.config.setOptionSettingValue(OptionParameters.PreferredCodec, this.aggregatedStats.codecs.get(this.aggregatedStats.inboundVideoStats.codecId))
}
});
}
Expand Down
60 changes: 32 additions & 28 deletions Frontend/library/src/WebRtcPlayer/WebRtcPlayerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class WebRtcPlayerController {
statsTimerHandle: number;
file: FileTemplate;
preferredCodec: string;
peerConfig: RTCConfiguration

// if you override the disconnection message by calling the interface method setDisconnectMessageOverride
// it will use this property to store the override message string
Expand Down Expand Up @@ -179,14 +180,7 @@ export class WebRtcPlayerController {
}`
);
this.webSocketController.onOpen.addEventListener('open', () => {
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has(OptionParameters.StreamerId)) {
this.webSocketController.sendSubscribe(
urlParams.get(OptionParameters.StreamerId)
);
} else {
this.webSocketController.requestStreamerList();
}
this.webSocketController.requestStreamerList();
});
this.webSocketController.onClose.addEventListener('close', () => {
this.afkController.stopAfkWarningTimer();
Expand Down Expand Up @@ -228,9 +222,10 @@ export class WebRtcPlayerController {
this.isQualityController = false;
this.preferredCodec = '';

this.config.addOnOptionSettingChangedListener(
OptionParameters.StreamerId,
(streamerid) => {
this.config.addOnOptionSettingChangedListener(OptionParameters.StreamerId, (streamerid) => {
// close the current peer connection and create a new one
this.peerConnectionController.peerConnection.close();
this.peerConnectionController.createPeerConnection(this.peerConfig, this.preferredCodec);
this.webSocketController.sendSubscribe(streamerid);
}
);
Expand Down Expand Up @@ -705,7 +700,7 @@ export class WebRtcPlayerController {
Logger.Error(
Logger.GetStackTrace(),
`ToStreamer->${messageType} protocol definition was malformed as it didn't contain at least an id and a byteLength\n
Definition was: ${JSON.stringify(message, null, 2)}`
Definition was: ${JSON.stringify(message, null, 2)}`
);
// return in a forEach is equivalent to a continue in a normal for loop
return;
Expand Down Expand Up @@ -751,7 +746,7 @@ export class WebRtcPlayerController {
Logger.Error(
Logger.GetStackTrace(),
`FromStreamer->${messageType} protocol definition was malformed as it didn't contain at least an id\n
Definition was: ${JSON.stringify(message, null, 2)}`
Definition was: ${JSON.stringify(message, null, 2)}`
);
// return in a forEach is equivalent to a continue in a normal for loop
return;
Expand Down Expand Up @@ -1045,18 +1040,15 @@ export class WebRtcPlayerController {
);

// If we are connecting to the SFU add a special url parameter to the url
if (this.config.isFlagEnabled(Flags.PreferSFU)) {
signallingServerUrl += '?' + Flags.PreferSFU + '=true';
}

// If we are sending the offer add a special url parameter to the url, making sure we append correctly
if (this.config.isFlagEnabled(Flags.BrowserSendOffer)) {
signallingServerUrl +=
(signallingServerUrl.includes('?') ? '&' : '?') +
Flags.BrowserSendOffer +
'=true';
signallingServerUrl += '?' + Flags.BrowserSendOffer + '=true';
}

// This code is no longer needed, but is a good example for how subsequent config flags can be appended
// if (this.config.isFlagEnabled(Flags.BrowserSendOffer)) {
// signallingServerUrl += (signallingServerUrl.includes('?') ? '&' : '?') + Flags.BrowserSendOffer + '=true';
// }

return signallingServerUrl;
}

Expand All @@ -1074,6 +1066,7 @@ export class WebRtcPlayerController {
* @remark RTC Peer Connection on Ice Candidate event have it handled by handle Send Ice Candidate
*/
startSession(peerConfig: RTCConfiguration) {
this.peerConfig = peerConfig;
// check for forcing turn
if (this.config.isFlagEnabled(Flags.ForceTURN)) {
// check for a turn server
Expand All @@ -1095,7 +1088,7 @@ export class WebRtcPlayerController {

// set up the peer connection controller
this.peerConnectionController = new PeerConnectionController(
peerConfig,
this.peerConfig,
this.config,
this.preferredCodec
);
Expand Down Expand Up @@ -1218,11 +1211,22 @@ export class WebRtcPlayerController {
`Got streamer list ${messageStreamerList.ids}`,
6
);
messageStreamerList.ids.unshift(''); // add an empty option at the top
this.config.setOptionSettingOptions(
OptionParameters.StreamerId,
messageStreamerList.ids
);

const settingOptions = [...messageStreamerList.ids] // copy the original messageStreamerList.ids
settingOptions.unshift('') // add an empty option at the top
this.config.setOptionSettingOptions(OptionParameters.StreamerId, settingOptions);

const urlParams = new URLSearchParams(window.location.search);
if(messageStreamerList.ids.length == 1) {
// If there's only a single streamer, subscribe to it regardless of what is in the URL
this.config.setOptionSettingValue(OptionParameters.StreamerId, messageStreamerList.ids[0]);
} else if (this.config.isFlagEnabled(Flags.PreferSFU) && messageStreamerList.ids.includes("SFU")) {
// If the SFU toggle is on and there's an SFU connected, subscribe to it regardless of what is in the URL
this.config.setOptionSettingValue(OptionParameters.StreamerId, "SFU");
} else if (urlParams.has(OptionParameters.StreamerId) && messageStreamerList.ids.includes(urlParams.get(OptionParameters.StreamerId))) {
// If there's a streamer ID in the URL and a streamer with this ID is connected, set it as the selected streamer
this.config.setOptionSettingValue(OptionParameters.StreamerId, urlParams.get(OptionParameters.StreamerId));
}
}

/**
Expand Down
37 changes: 0 additions & 37 deletions SignallingWebServer/Public/login.html

This file was deleted.

42 changes: 0 additions & 42 deletions SignallingWebServer/Public/stresstest.html

This file was deleted.

18 changes: 6 additions & 12 deletions SignallingWebServer/cirrus.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,11 @@ let nextPlayerId = 1;
const PlayerType = { Regular: 0, SFU: 1 };

class Player {
constructor(id, ws, type) {
constructor(id, ws, type, browserSendOffer) {
this.id = id;
this.ws = ws;
this.type = type;
this.browserSendOffer = browserSendOffer;
}

subscribe(streamerId) {
Expand All @@ -287,7 +288,7 @@ class Player {
return;
}
this.streamerId = streamerId;
const msg = { type: 'playerConnected', playerId: this.id, dataChannel: true, sfu: this.type == PlayerType.SFU };
const msg = { type: 'playerConnected', playerId: this.id, dataChannel: true, sfu: this.type == PlayerType.SFU, sendOffer: !this.browserSendOffer };
logOutgoing(this.streamerId, msg);
this.sendFrom(msg);
}
Expand Down Expand Up @@ -596,7 +597,7 @@ sfuServer.on('connection', function (ws, req) {
}
});

let sfuPlayer = new Player(SFUPlayerId, ws, PlayerType.SFU);
let sfuPlayer = new Player(SFUPlayerId, ws, PlayerType.SFU, false);
players.set(SFUPlayerId, sfuPlayer);
console.logColor(logging.Green, `SFU (${req.connection.remoteAddress}) connected `);

Expand Down Expand Up @@ -678,6 +679,7 @@ playerServer.on('connection', function (ws, req) {
var url = require('url');
const parsedUrl = url.parse(req.url);
const urlParams = new URLSearchParams(parsedUrl.search);
const browserSendOffer = urlParams.has('OfferToReceive') && urlParams.get('OfferToReceive') !== 'false';
lukehb marked this conversation as resolved.
Show resolved Hide resolved

if (playerCount + 1 > maxPlayerCount && maxPlayerCount !== -1)
{
Expand All @@ -689,7 +691,7 @@ playerServer.on('connection', function (ws, req) {
++playerCount;
let playerId = sanitizePlayerId(nextPlayerId++);
console.logColor(logging.Green, `player ${playerId} (${req.connection.remoteAddress}) connected`);
let player = new Player(playerId, ws, PlayerType.Regular);
let player = new Player(playerId, ws, PlayerType.Regular, browserSendOffer);
players.set(playerId, player);

ws.on('message', (msgRaw) =>{
Expand Down Expand Up @@ -739,14 +741,6 @@ playerServer.on('connection', function (ws, req) {
sendPlayerConnectedToMatchmaker();
player.ws.send(JSON.stringify(clientConfig));
sendPlayersCount();

// if we only have one streamer just subscribe this player to that one
if (streamers.size == 1) {
for (let [streamerId, streamer] of streamers) {
player.subscribe(streamerId);
break;
}
}
});

function disconnectAllPlayers(streamerId) {
Expand Down