mirror of
https://github.com/jech/galene.git
synced 2024-11-26 02:25:58 +01:00
Implement filters.
No user interface yet.
This commit is contained in:
parent
e7d7c2dd0a
commit
ca6020a27e
1 changed files with 85 additions and 2 deletions
|
@ -83,6 +83,7 @@ function getUserPass() {
|
||||||
* @property {boolean} [activityDetection]
|
* @property {boolean} [activityDetection]
|
||||||
* @property {Array.<number>} [resolution]
|
* @property {Array.<number>} [resolution]
|
||||||
* @property {boolean} [blackboardMode]
|
* @property {boolean} [blackboardMode]
|
||||||
|
* @property {string} [filter]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @type{settings} */
|
/** @type{settings} */
|
||||||
|
@ -777,6 +778,70 @@ async function setMaxVideoThroughput(c, bps) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function Filter(stream, f) {
|
||||||
|
/** @type {MediaStream} */
|
||||||
|
this.input = stream;
|
||||||
|
/** @type {(this: Filter, src: HTMLElement, dest: HTMLCanvasElement) => void} */
|
||||||
|
this.f = f;
|
||||||
|
/** @type {HTMLVideoElement} */
|
||||||
|
this.video = document.createElement('video');
|
||||||
|
/** @type {HTMLCanvasElement} */
|
||||||
|
this.canvas = document.createElement('canvas');
|
||||||
|
/** @type {MediaStream} */
|
||||||
|
this.captureStream = null;
|
||||||
|
/** @type {MediaStream} */
|
||||||
|
this.outputStream = null;
|
||||||
|
/** @type {number} */
|
||||||
|
this.timer = null;
|
||||||
|
|
||||||
|
/** @ts-ignore */
|
||||||
|
this.captureStream = this.canvas.captureStream(0);
|
||||||
|
|
||||||
|
this.outputStream = new MediaStream();
|
||||||
|
this.outputStream.addTrack(this.captureStream.getTracks()[0]);
|
||||||
|
this.input.getTracks().forEach(t => {
|
||||||
|
t.onended = e => this.stop();
|
||||||
|
if(t.kind != 'video')
|
||||||
|
this.outputStream.addTrack(t);
|
||||||
|
});
|
||||||
|
this.video.srcObject = stream;
|
||||||
|
this.video.muted = true;
|
||||||
|
this.video.play();
|
||||||
|
this.timer = setInterval(() => this.draw(), 1000 / 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter.prototype.draw = function() {
|
||||||
|
this.canvas.width = this.video.videoWidth;
|
||||||
|
this.canvas.height = this.video.videoHeight;
|
||||||
|
this.f(this.video, this.canvas);
|
||||||
|
/** @ts-ignore */
|
||||||
|
this.captureStream.getTracks()[0].requestFrame();
|
||||||
|
};
|
||||||
|
|
||||||
|
Filter.prototype.stop = function() {
|
||||||
|
if(!this.timer)
|
||||||
|
return;
|
||||||
|
this.captureStream.getTracks()[0].stop();
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
this.timer = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
let filters = {
|
||||||
|
'mirror-h': (video, canvas) => {
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
ctx.scale(-1, 1);
|
||||||
|
ctx.drawImage(video, -video.videoWidth, 0);
|
||||||
|
},
|
||||||
|
'mirror-v': (video, canvas) => {
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
ctx.scale(1, -1);
|
||||||
|
ctx.drawImage(video, 0, -video.videoHeight);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
function isSafari() {
|
function isSafari() {
|
||||||
let ua = navigator.userAgent.toLowerCase();
|
let ua = navigator.userAgent.toLowerCase();
|
||||||
return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0;
|
return ua.indexOf('safari') >= 0 && ua.indexOf('chrome') < 0;
|
||||||
|
@ -791,6 +856,14 @@ async function addLocalMedia(id) {
|
||||||
let audio = settings.audio ? {deviceId: settings.audio} : false;
|
let audio = settings.audio ? {deviceId: settings.audio} : false;
|
||||||
let video = settings.video ? {deviceId: settings.video} : false;
|
let video = settings.video ? {deviceId: settings.video} : false;
|
||||||
|
|
||||||
|
let filter = null;
|
||||||
|
if(settings.filter) {
|
||||||
|
filter = filters[settings.filter];
|
||||||
|
if(!filter) {
|
||||||
|
displayWarning(`Unknown filter ${filter}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(video) {
|
if(video) {
|
||||||
let resolution = settings.resolution;
|
let resolution = settings.resolution;
|
||||||
if(resolution) {
|
if(resolution) {
|
||||||
|
@ -830,9 +903,18 @@ async function addLocalMedia(id) {
|
||||||
let c = newUpStream(id);
|
let c = newUpStream(id);
|
||||||
|
|
||||||
c.kind = 'local';
|
c.kind = 'local';
|
||||||
c.stream = stream;
|
if(filter) {
|
||||||
|
let f = new Filter(stream, filter);
|
||||||
|
c.stream = f.outputStream;
|
||||||
|
c.onclose = function() {
|
||||||
|
f.stop();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.stream = stream;
|
||||||
|
}
|
||||||
|
|
||||||
let mute = getSettings().localMute;
|
let mute = getSettings().localMute;
|
||||||
stream.getTracks().forEach(t => {
|
c.stream.getTracks().forEach(t => {
|
||||||
c.labels[t.id] = t.kind;
|
c.labels[t.id] = t.kind;
|
||||||
if(t.kind == 'audio') {
|
if(t.kind == 'audio') {
|
||||||
if(mute)
|
if(mute)
|
||||||
|
@ -972,6 +1054,7 @@ function stopUpMedia(c) {
|
||||||
try {
|
try {
|
||||||
t.stop();
|
t.stop();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
console.warn(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue