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

Fixes for Streamers changing IDs when connecting & Updates to SFU behaviour relating to multi streamer changes. #411

Merged
merged 10 commits into from
Oct 31, 2023
Merged
4 changes: 2 additions & 2 deletions Frontend/implementations/typescript/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 0 additions & 12 deletions Frontend/library/src/Config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export class Flags {
static FakeMouseWithTouches = 'FakeMouseWithTouches' as const;
static IsQualityController = 'ControlsQuality' as const;
static MatchViewportResolution = 'MatchViewportRes' as const;
static PreferSFU = 'preferSFU' as const;
static StartVideoMuted = 'StartVideoMuted' as const;
static SuppressBrowserKeys = 'SuppressBrowserKeys' as const;
static UseMic = 'UseMic' as const;
Expand Down Expand Up @@ -315,17 +314,6 @@ export class Config {
)
);

this.flags.set(
Flags.PreferSFU,
new SettingFlag(
Flags.PreferSFU,
'Prefer SFU',
'Try to connect to the SFU instead of P2P.',
false,
useUrlParams
)
);
lukehb marked this conversation as resolved.
Show resolved Hide resolved

this.flags.set(
Flags.IsQualityController,
new SettingFlag(
Expand Down
11 changes: 3 additions & 8 deletions Frontend/library/src/WebRtcPlayer/WebRtcPlayerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1384,12 +1384,6 @@ export class WebRtcPlayerController {
if (messageStreamerList.ids.length == 1) {
// If there's only a single streamer, subscribe to it regardless of what is in the URL
autoSelectedStreamerId = 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
autoSelectedStreamerId = 'SFU';
} else if (
urlParams.has(OptionParameters.StreamerId) &&
messageStreamerList.ids.includes(
Expand All @@ -1406,8 +1400,9 @@ export class WebRtcPlayerController {
);
} else {
// no auto selected streamer
if (this.config.isFlagEnabled(Flags.WaitForStreamer)) {
this.startAutoJoinTimer()
if (messageStreamerList.ids.length == 0 && this.config.isFlagEnabled(Flags.WaitForStreamer)) {
this.closeSignalingServer();
this.startAutoJoinTimer();
}
}
this.pixelStreaming.dispatchEvent(
Expand Down
4 changes: 0 additions & 4 deletions Frontend/ui-library/src/Config/ConfigUI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,6 @@ export class ConfigUI {
psSettingsSection,
this.flagsUi.get(Flags.StartVideoMuted)
);
this.addSettingFlag(
psSettingsSection,
this.flagsUi.get(Flags.PreferSFU)
);
lukehb marked this conversation as resolved.
Show resolved Hide resolved
this.addSettingFlag(
psSettingsSection,
this.flagsUi.get(Flags.IsQualityController)
Expand Down
10 changes: 10 additions & 0 deletions SFU/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,18 @@ for(let arg of process.argv){
}

const config = {
// The URL of the signalling server to connect to
signallingURL: "ws://localhost:8889",

// The ID for this SFU to use. This will show up as a streamer ID on the signalling server
SFUId: "SFU",

// The ID of the streamer to subscribe to. If you leave this blank it will subscribe to the first streamer it sees.
subscribeStreamerId: "DefaultStreamer",

// Delay between list requests when looking for a specifc streamer.
retrySubscribeDelaySecs: 10,

mediasoup: {
worker: {
rtcMinPort: 40000,
Expand Down
56 changes: 54 additions & 2 deletions SFU/sfu_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ const WebSocket = require('ws');
const mediasoup = require('mediasoup_prebuilt');
const mediasoupSdp = require('mediasoup-sdp-bridge');

if (!config.retrySubscribeDelaySecs) {
config.retrySubscribeDelaySecs = 10;
}

let signalServer = null;
let mediasoupRouter;
let streamer = null;
Expand All @@ -24,6 +28,35 @@ function connectSignalling(server) {
});
}

async function onStreamerList(msg) {
let success = false;

// subscribe to either the configured streamer, or if not configured, just grab the first id
if (msg.ids.length > 0) {
if (!!config.subscribeStreamerId && config.subscribeStreamerId.length != 0) {
if (msg.ids.includes(config.subscribeStreamerId)) {
signalServer.send(JSON.stringify({type: 'subscribe', streamerId: config.subscribeStreamerId}));
success = true;
}
} else {
signalServer.send(JSON.stringify({type: 'subscribe', streamerId: msg.ids[0]}));
success = true;
}
}

if (!success) {
// did not subscribe to anything
setTimeout(function() {
signalServer.send(JSON.stringify({type: 'listStreamers'}));
}, config.retrySubscribeDelaySecs * 1000);
}
}

async function onIdentify(msg) {
signalServer.send(JSON.stringify({type: 'endpointId', id: config.SFUId}));
signalServer.send(JSON.stringify({type: 'listStreamers'}));
}

async function onStreamerOffer(sdp) {
console.log("Got offer from streamer");

Expand Down Expand Up @@ -57,6 +90,11 @@ function onStreamerDisconnected() {
}
streamer.transport.close();
streamer = null;
signalServer.send(JSON.stringify({type: 'stopStreaming'}));

setTimeout(function() {
signalServer.send(JSON.stringify({type: 'listStreamers'}));
}, config.retrySubscribeDelaySecs * 1000);
}
}

Expand Down Expand Up @@ -228,7 +266,7 @@ function onLayerPreference(msg) {
}

async function onSignallingMessage(message) {
//console.log(`Got MSG: ${message}`);
//console.log(`Got MSG: ${message}`);
const msg = JSON.parse(message);

if (msg.type == 'offer') {
Expand All @@ -255,6 +293,12 @@ async function onSignallingMessage(message) {
else if (msg.type == 'layerPreference') {
onLayerPreference(msg);
}
else if (msg.type == 'streamerList') {
onStreamerList(msg);
}
else if (msg.type == 'identify') {
onIdentify(msg);
}
}

async function startMediasoup() {
Expand All @@ -276,6 +320,14 @@ async function startMediasoup() {
return mediasoupRouter;
}

async function onICEStateChange(identifier, iceState) {
console.log("%s ICE state changed to %s", identifier, iceState);

if (identifier == 'Streamer' && iceState == 'completed') {
signalServer.send(JSON.stringify({type: 'startStreaming'}));
}
}

async function createWebRtcTransport(identifier) {
const {
listenIps,
Expand All @@ -291,7 +343,7 @@ async function createWebRtcTransport(identifier) {
initialAvailableOutgoingBitrate: initialAvailableOutgoingBitrate
});

transport.on("icestatechange", (iceState) => { console.log("%s ICE state changed to %s", identifier, iceState); });
transport.on("icestatechange", (iceState) => onICEStateChange(identifier, iceState));
transport.on("iceselectedtuplechange", (iceTuple) => { console.log("%s ICE selected tuple %s", identifier, JSON.stringify(iceTuple)); });
transport.on("sctpstatechange", (sctpState) => { console.log("%s SCTP state changed to %s", identifier, sctpState); });

Expand Down
Loading