Commit eb21c1ab authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Maintain stream information for oneself.

We used to maintain stream information for all users except oneself.
parent e303992e
...@@ -1049,7 +1049,7 @@ function removeFilter(c) { ...@@ -1049,7 +1049,7 @@ function removeFilter(c) {
if(!(old instanceof Filter)) if(!(old instanceof Filter))
throw new Error('userdata.filter is not a filter'); throw new Error('userdata.filter is not a filter');
c.stream = old.inputStream; c.setStream(old.inputStream);
old.stop(); old.stop();
c.userdata.filter = null; c.userdata.filter = null;
} }
...@@ -1066,7 +1066,7 @@ function setFilter(c) { ...@@ -1066,7 +1066,7 @@ function setFilter(c) {
return; return;
let filter = new Filter(c.stream, c.userdata.filterDefinition); let filter = new Filter(c.stream, c.userdata.filterDefinition);
c.stream = filter.outputStream; c.setStream(filter.outputStream);
c.userdata.filter = filter; c.userdata.filter = filter;
} }
...@@ -1162,7 +1162,7 @@ function setUpStream(c, stream) { ...@@ -1162,7 +1162,7 @@ function setUpStream(c, stream) {
if(c.stream != null) if(c.stream != null)
throw new Error("Setting nonempty stream"); throw new Error("Setting nonempty stream");
c.stream = stream; c.setStream(stream);
try { try {
setFilter(c); setFilter(c);
......
...@@ -66,7 +66,7 @@ function newLocalId() { ...@@ -66,7 +66,7 @@ function newLocalId() {
* @property {string} username * @property {string} username
* @property {Array<string>} permissions * @property {Array<string>} permissions
* @property {Object<string,any>} data * @property {Object<string,any>} data
* @property {Object<string,Object<string,boolean>>} down * @property {Object<string,Object<string,boolean>>} streams
*/ */
/** /**
...@@ -359,7 +359,7 @@ ServerConnection.prototype.connect = async function(url) { ...@@ -359,7 +359,7 @@ ServerConnection.prototype.connect = async function(url) {
username: m.username, username: m.username,
permissions: m.permissions || [], permissions: m.permissions || [],
data: m.data || {}, data: m.data || {},
down: {}, streams: {},
}; };
break; break;
case 'change': case 'change':
...@@ -369,7 +369,7 @@ ServerConnection.prototype.connect = async function(url) { ...@@ -369,7 +369,7 @@ ServerConnection.prototype.connect = async function(url) {
username: m.username, username: m.username,
permissions: m.permissions || [], permissions: m.permissions || [],
data: m.data || {}, data: m.data || {},
down: {}, streams: {},
}; };
} else { } else {
sc.users[m.id].username = m.username; sc.users[m.id].username = m.username;
...@@ -593,7 +593,6 @@ ServerConnection.prototype.newUpStream = function(localId) { ...@@ -593,7 +593,6 @@ ServerConnection.prototype.newUpStream = function(localId) {
}; };
pc.ontrack = console.error; pc.ontrack = console.error;
return c; return c;
}; };
...@@ -750,7 +749,7 @@ ServerConnection.prototype.gotOffer = async function(id, label, source, username ...@@ -750,7 +749,7 @@ ServerConnection.prototype.gotOffer = async function(id, label, source, username
return; return;
} }
c.stream = e.streams[0]; c.stream = e.streams[0];
let changed = recomputeUserStreams(sc, source, c); let changed = recomputeUserStreams(sc, source);
if(c.ondowntrack) { if(c.ondowntrack) {
c.ondowntrack.call( c.ondowntrack.call(
c, e.track, e.transceiver, e.streams[0], c, e.track, e.transceiver, e.streams[0],
...@@ -1061,6 +1060,19 @@ function Stream(sc, id, localId, pc, up) { ...@@ -1061,6 +1060,19 @@ function Stream(sc, id, localId, pc, up) {
this.onstats = null; this.onstats = null;
} }
/**
* setStream sets the stream of an upwards connection.
*
* @param {MediaStream} stream
*/
Stream.prototype.setStream = function(stream) {
let c = this;
c.stream = stream;
let changed = recomputeUserStreams(c.sc, c.sc.id);
if(changed && c.sc.onuser)
c.sc.onuser.call(c.sc, c.sc.id, "change");
}
/** /**
* close closes a stream. * close closes a stream.
* *
...@@ -1096,20 +1108,23 @@ Stream.prototype.close = function(replace) { ...@@ -1096,20 +1108,23 @@ Stream.prototype.close = function(replace) {
} }
} }
let userid;
if(c.up) { if(c.up) {
userid = c.sc.id;
if(c.sc.up[c.id] === c) if(c.sc.up[c.id] === c)
delete(c.sc.up[c.id]); delete(c.sc.up[c.id]);
else else
console.warn('Closing unknown stream'); console.warn('Closing unknown stream');
} else { } else {
userid = c.source;
if(c.sc.down[c.id] === c) if(c.sc.down[c.id] === c)
delete(c.sc.down[c.id]); delete(c.sc.down[c.id]);
else else
console.warn('Closing unknown stream'); console.warn('Closing unknown stream');
let changed = recomputeUserStreams(c.sc, c.source);
if(changed && c.sc.onuser)
c.sc.onuser.call(c.sc, c.source, "change");
} }
let changed = recomputeUserStreams(c.sc, userid);
if(changed && c.sc.onuser)
c.sc.onuser.call(c.sc, userid, "change");
c.sc = null; c.sc = null;
if(c.onclose) if(c.onclose)
...@@ -1117,53 +1132,35 @@ Stream.prototype.close = function(replace) { ...@@ -1117,53 +1132,35 @@ Stream.prototype.close = function(replace) {
}; };
/** /**
* recomputeUserStreams recomputes the user.down array for a given user. * recomputeUserStreams recomputes the user.streams array for a given user.
* It returns true if anything changed. * It returns true if anything changed.
* *
* @param {ServerConnection} sc * @param {ServerConnection} sc
* @param {string} id * @param {string} id
* @param {Stream} [c]
* @returns {boolean} * @returns {boolean}
*/ */
function recomputeUserStreams(sc, id, c) { function recomputeUserStreams(sc, id) {
let user = sc.users[id]; let user = sc.users[id];
if(!user) { if(!user) {
console.warn("recomputing streams for unknown user"); console.warn("recomputing streams for unknown user");
return false; return false;
} }
if(c) { let streams = id === sc.id ? sc.up : sc.down;
let changed = false; let old = user.streams;
if(!user.down[c.label]) user.streams = {};
user.down[c.label] = {}; for(id in streams) {
c.stream.getTracks().forEach(t => { let c = streams[id];
if(!user.down[c.label][t.kind]) {
user.down[c.label][t.kind] = true;
changed = true;
}
});
return changed;
}
if(!user.down || Object.keys(user.down).length === 0)
return false;
let old = user.down;
user.down = {};
for(id in sc.down) {
let c = sc.down[id];
if(!c.stream) if(!c.stream)
continue; continue;
if(!user.down[c.label]) if(!user.streams[c.label])
user.down[c.label] = {}; user.streams[c.label] = {};
c.stream.getTracks().forEach(t => { c.stream.getTracks().forEach(t => {
user.down[c.label][t.kind] = true; user.streams[c.label][t.kind] = true;
}); });
} }
// might lead to false positives. Oh, well. return JSON.stringify(old) != JSON.stringify(user.streams);
return JSON.stringify(old) != JSON.stringify(user.down);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment