mirror of
https://github.com/jech/galene.git
synced 2024-12-25 08:45:48 +01:00
WIP
This commit is contained in:
parent
5722270cc7
commit
300d6e2e9d
2 changed files with 97 additions and 97 deletions
|
@ -214,16 +214,19 @@
|
|||
<option value="lowest">lowest</option>
|
||||
<option value="low">low</option>
|
||||
<option value="normal" selected>normal</option>
|
||||
<option value="unlimited">unlimited</option>
|
||||
<option value="high">high</option>
|
||||
<option value="highest">highest</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<form id="simulcastform">
|
||||
<label for="simulcastselect" class="sidenav-label-first">Simulcast:</label>
|
||||
<select id="simulcastselect" class="select select-inline">
|
||||
<form id="scalabilityform">
|
||||
<label for="scalabilityselect" class="sidenav-label-first">Scalability mode:</label>
|
||||
<select id="scalabilityselect" class="select select-inline">
|
||||
<option value="off">off</option>
|
||||
<option value="auto" selected>auto</option>
|
||||
<option value="on">on</option>
|
||||
<option value="svc">SVC</option>
|
||||
<option value="simulcast">simulcast</option>
|
||||
<option value="both">both</option>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
|
|
181
static/galene.js
181
static/galene.js
|
@ -40,7 +40,7 @@ let connectingAgain = false;
|
|||
* @property {boolean} [localMute]
|
||||
* @property {string} [video]
|
||||
* @property {string} [audio]
|
||||
* @property {string} [simulcast]
|
||||
* @property {string} [scalability]
|
||||
* @property {string} [send]
|
||||
* @property {string} [request]
|
||||
* @property {boolean} [activityDetection]
|
||||
|
@ -195,10 +195,10 @@ function reflectSettings() {
|
|||
store = true;
|
||||
}
|
||||
|
||||
if(settings.hasOwnProperty('simulcast')) {
|
||||
getSelectElement('simulcastselect').value = settings.simulcast
|
||||
if(settings.hasOwnProperty('scalability')) {
|
||||
getSelectElement('scalabilityselect').value = settings.scalability;
|
||||
} else {
|
||||
settings.simulcast = getSelectElement('simulcastselect').value;
|
||||
settings.scalability = getSelectElement('scalabilityselect').value;
|
||||
store = true;
|
||||
}
|
||||
|
||||
|
@ -280,11 +280,6 @@ function isSafari() {
|
|||
return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0;
|
||||
}
|
||||
|
||||
function isFirefox() {
|
||||
let ua = navigator.userAgent.toLowerCase();
|
||||
return ua.indexOf('firefox') >= 0;
|
||||
}
|
||||
|
||||
/** @type {MediaStream} */
|
||||
let safariStream = null;
|
||||
|
||||
|
@ -496,7 +491,7 @@ function setButtonsVisibility() {
|
|||
|
||||
setVisibility('mediaoptions', present);
|
||||
setVisibility('sendform', present);
|
||||
setVisibility('simulcastform', present);
|
||||
setVisibility('scalabilityform', present);
|
||||
|
||||
setVisibility('collapse-video', mediacount && mobilelayout);
|
||||
}
|
||||
|
@ -598,24 +593,6 @@ getSelectElement('filterselect').onchange = async function(e) {
|
|||
}
|
||||
};
|
||||
|
||||
/** @returns {number} */
|
||||
function getMaxVideoThroughput() {
|
||||
let v = getSettings().send;
|
||||
switch(v) {
|
||||
case 'lowest':
|
||||
return 150000;
|
||||
case 'low':
|
||||
return 300000;
|
||||
case 'normal':
|
||||
return 700000;
|
||||
case 'unlimited':
|
||||
return null;
|
||||
default:
|
||||
console.error('Unknown video quality', v);
|
||||
return 700000;
|
||||
}
|
||||
}
|
||||
|
||||
getSelectElement('sendselect').onchange = async function(e) {
|
||||
if(!(this instanceof HTMLSelectElement))
|
||||
throw new Error('Unexpected type for this');
|
||||
|
@ -623,10 +600,10 @@ getSelectElement('sendselect').onchange = async function(e) {
|
|||
await reconsiderSendParameters();
|
||||
};
|
||||
|
||||
getSelectElement('simulcastselect').onchange = async function(e) {
|
||||
getSelectElement('scalabilityselect').onchange = async function(e) {
|
||||
if(!(this instanceof HTMLSelectElement))
|
||||
throw new Error('Unexpected type for this');
|
||||
updateSettings({simulcast: this.value});
|
||||
updateSettings({scalability: this.value});
|
||||
await reconsiderSendParameters();
|
||||
};
|
||||
|
||||
|
@ -908,14 +885,78 @@ function newUpStream(localId) {
|
|||
return c;
|
||||
}
|
||||
|
||||
const simulcastRate = 100000;
|
||||
const hqAudioRate = 128000;
|
||||
const videoRates = {
|
||||
lowest: 150000,
|
||||
low: 300000,
|
||||
normal: 700000,
|
||||
high: 1500000,
|
||||
highest: 3000000,
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets an up stream's video throughput and simulcast parameters.
|
||||
* @typedef {Object} sendParameters
|
||||
* @property {number} maxBitrate
|
||||
* @property {string} scalabilityMode
|
||||
* @property {boolean} simulcast
|
||||
*/
|
||||
|
||||
/**
|
||||
* @returns {sendParameters}
|
||||
*/
|
||||
function getSendParameters() {
|
||||
let bps = videoRates[getSettings().send];
|
||||
if(!bps) {
|
||||
console.error('Unknown video quality');
|
||||
bps = 700000;
|
||||
}
|
||||
|
||||
/** @type{sendParameters} */
|
||||
let parms = {
|
||||
maxBitrate: bps,
|
||||
scalabilityMode: 'L1T1',
|
||||
simulcast: false,
|
||||
}
|
||||
|
||||
switch(getSettings().scalability) {
|
||||
case 'off':
|
||||
return parms;
|
||||
case 'svc':
|
||||
parms.scalabilityMode = 'L3T3';
|
||||
return parms;
|
||||
case 'simulcast':
|
||||
parms.simulcast = true;
|
||||
return parms;
|
||||
case 'both':
|
||||
parms.scalabilityMode = 'L1T3';
|
||||
parms.simulcast = true;
|
||||
return parms;
|
||||
default:
|
||||
let count = 0;
|
||||
for(let n in serverConnection.users) {
|
||||
if(!serverConnection.users[n].permissions["system"]) {
|
||||
count++;
|
||||
if(count > 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(count <= 2)
|
||||
return parms;
|
||||
if(!bps || bps < 2 * simulcastRate)
|
||||
return parms;
|
||||
parms.scalabilityMode = 'L3T3';
|
||||
return parms;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an up stream's video throughput and scalability parameters.
|
||||
*
|
||||
* @param {Stream} c
|
||||
* @param {number} bps
|
||||
* @param {boolean} simulcast
|
||||
* @param {sendParameters} parms
|
||||
*/
|
||||
async function setSendParameters(c, bps, simulcast) {
|
||||
async function setSendParameters(c, parms) {
|
||||
if(!c.up)
|
||||
throw new Error('Setting throughput of down stream');
|
||||
let senders = c.pc.getSenders();
|
||||
|
@ -925,14 +966,15 @@ async function setSendParameters(c, bps, simulcast) {
|
|||
continue;
|
||||
let p = s.getParameters();
|
||||
if((!p.encodings ||
|
||||
!simulcast && p.encodings.length != 1) ||
|
||||
(simulcast && p.encodings.length != 2)) {
|
||||
!parms.simulcast && p.encodings.length != 1) ||
|
||||
(parms.simulcast && p.encodings.length < 2)) {
|
||||
await replaceUpStream(c);
|
||||
return;
|
||||
}
|
||||
p.encodings.forEach(e => {
|
||||
if(!e.rid || e.rid === 'h')
|
||||
e.maxBitrate = bps || unlimitedRate;
|
||||
e.maxBitrate = parms.maxBitrate;
|
||||
e.scalabilityMode = parms.scalabilityMode;
|
||||
});
|
||||
await s.setParameters(p);
|
||||
}
|
||||
|
@ -945,12 +987,11 @@ let reconsiderParametersTimer = null;
|
|||
*/
|
||||
async function reconsiderSendParameters() {
|
||||
cancelReconsiderParameters();
|
||||
let t = getMaxVideoThroughput();
|
||||
let s = doSimulcast();
|
||||
let parms = getSendParameters();
|
||||
let promises = [];
|
||||
for(let id in serverConnection.up) {
|
||||
let c = serverConnection.up[id];
|
||||
promises.push(setSendParameters(c, t, s));
|
||||
promises.push(setSendParameters(c, parms));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
@ -1167,37 +1208,6 @@ function addFilters() {
|
|||
}
|
||||
}
|
||||
|
||||
const unlimitedRate = 1000000000;
|
||||
const simulcastRate = 100000;
|
||||
const hqAudioRate = 128000;
|
||||
|
||||
/**
|
||||
* Decide whether we want to send simulcast.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function doSimulcast() {
|
||||
switch(getSettings().simulcast) {
|
||||
case 'on':
|
||||
return true;
|
||||
case 'off':
|
||||
return false;
|
||||
default:
|
||||
let count = 0;
|
||||
for(let n in serverConnection.users) {
|
||||
if(!serverConnection.users[n].permissions["system"]) {
|
||||
count++;
|
||||
if(count > 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(count <= 2)
|
||||
return false;
|
||||
let bps = getMaxVideoThroughput();
|
||||
return bps <= 0 || bps >= 2 * simulcastRate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up c to send the given stream. Some extra parameters are stored
|
||||
* in c.userdata.
|
||||
|
@ -1250,24 +1260,26 @@ function setUpStream(c, stream) {
|
|||
};
|
||||
|
||||
let encodings = [];
|
||||
let simulcast = doSimulcast();
|
||||
let parms = getSendParameters();
|
||||
if(t.kind === 'video') {
|
||||
let bps = getMaxVideoThroughput();
|
||||
// Firefox doesn't like us setting the RID if we're not
|
||||
// simulcasting.
|
||||
if(simulcast && c.label !== 'screenshare') {
|
||||
if(parms.simulcast) {
|
||||
encodings.push({
|
||||
rid: 'h',
|
||||
maxBitrate: bps || unlimitedRate,
|
||||
maxBitrate: parms.maxBitrate,
|
||||
scalabilityMode: parms.scalabilityMode,
|
||||
});
|
||||
encodings.push({
|
||||
rid: 'l',
|
||||
scaleResolutionDownBy: 2,
|
||||
maxBitrate: simulcastRate,
|
||||
scalabilityMode: parms.scalabilityMode,
|
||||
});
|
||||
} else {
|
||||
encodings.push({
|
||||
maxBitrate: bps || unlimitedRate,
|
||||
maxBitrate: parms.maxBitrate,
|
||||
scalabilityMode: parms.scalabilityMode,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
@ -1277,22 +1289,11 @@ function setUpStream(c, stream) {
|
|||
});
|
||||
}
|
||||
}
|
||||
let tr = c.pc.addTransceiver(t, {
|
||||
c.pc.addTransceiver(t, {
|
||||
direction: 'sendonly',
|
||||
streams: [stream],
|
||||
sendEncodings: encodings,
|
||||
});
|
||||
|
||||
// Firefox before 110 does not implement sendEncodings, and
|
||||
// requires this hack, which throws an exception on Chromium.
|
||||
try {
|
||||
let p = tr.sender.getParameters();
|
||||
if(!p.encodings) {
|
||||
p.encodings = encodings;
|
||||
tr.sender.setParameters(p);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// c.stream might be different from stream if there's a filter
|
||||
|
@ -3923,10 +3924,6 @@ async function start() {
|
|||
);
|
||||
}
|
||||
|
||||
// Disable simulcast on Firefox by default, it's buggy.
|
||||
if(isFirefox())
|
||||
getSelectElement('simulcastselect').value = 'off';
|
||||
|
||||
let parms = new URLSearchParams(window.location.search);
|
||||
if(window.location.search)
|
||||
window.history.replaceState(null, '', window.location.pathname);
|
||||
|
|
Loading…
Reference in a new issue