Commit f78030c4 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Initial implementation of mike and camera selection.

We're closing and reopening the connection each time, we should be
renegotiating instead.
parent 175b08bb
......@@ -49,6 +49,22 @@ h1 {
display: none;
}
#optionsdiv {
margin-bottom: 4px;
}
#videoselect {
width: 8em;
text-align-last: center;
margin-right: 0.4em;
}
#audioselect {
width: 8em;
text-align-last: center;
margin-right: 0.4em;
}
#main {
display: flex;
}
......@@ -111,6 +127,7 @@ h1 {
}
#input {
margin-left: 0.5em;
width: 100%;
border: none;
resize: none;
......
......@@ -31,8 +31,22 @@
<div id="optionsdiv">
<label for="presenterbox">Present:</label>
<input id="presenterbox" type="checkbox"/ disabled>
<label for="videoselect">Camera:</label>
<select id="videoselect">
<option>default</option>
<option>off</option>
</select>
<label for="audioselect">Microphone:</label>
<select id="audioselect">
<option>default</option>
<option>off</option>
</select>
<label for="sharebox">Share screen:</label>
<input id="sharebox" type="checkbox"/ disabled>
</div>
</div>
......
......@@ -126,6 +126,16 @@ document.getElementById('presenterbox').onchange = function(e) {
setLocalMedia(this.checked);
}
document.getElementById('audioselect').onchange = function(e) {
e.preventDefault();
setLocalMedia(document.getElementById('presenterbox').checked);
}
document.getElementById('videoselect').onchange = function(e) {
e.preventDefault();
setLocalMedia(document.getElementById('presenterbox').checked);
}
document.getElementById('sharebox').onchange = function(e) {
e.preventDefault();
setShareMedia(this.checked);
......@@ -193,6 +203,71 @@ function displayStats(id) {
setLabel(id);
}
function mapMediaOption(value) {
console.assert(typeof(value) === 'string');
switch(value) {
case 'default':
return true;
case 'off':
return false;
default:
return value;
}
}
function addSelectOption(select, label, value) {
if(!value)
value = label;
for(let i = 0; i < select.children.length; i++) {
if(select.children[i].value === value) {
return;
}
}
let option = document.createElement('option');
option.value = value;
option.textContent = label;
select.appendChild(option);
}
// media names might not be available before we call getDisplayMedia. So
// we call this lazily.
let mediaChoicesDone = false;
async function setMediaChoices() {
if(mediaChoicesDone)
return;
let devices = [];
try {
devices = await navigator.mediaDevices.enumerateDevices();
} catch(e) {
console.error(e);
return;
}
let cn = 1, mn = 1;
devices.forEach(d => {
let label = d.label;
if(d.kind === 'videoinput') {
if(!label)
label = `Camera ${cn}`;
addSelectOption(document.getElementById('videoselect'),
label, d.deviceId);
cn++;
} else if(d.kind === 'audioinput') {
if(!label)
label = `Microphone ${mn}`;
addSelectOption(document.getElementById('audioselect'),
label, d.deviceId);
mn++;
}
});
mediaChoicesDone = true;
}
let localMediaId = null;
async function setLocalMedia(setup) {
......@@ -209,32 +284,39 @@ async function setLocalMedia(setup) {
return;
}
if(!localMediaId) {
let constraints = {audio: true, video: true};
let stream = null;
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
} catch(e) {
console.error(e);
document.getElementById('presenterbox').checked = false;
await setLocalMedia(false);
return;
}
localMediaId = await newUpStream();
let audio = mapMediaOption(document.getElementById('audioselect').value);
let video = mapMediaOption(document.getElementById('videoselect').value);
let c = up[localMediaId];
c.stream = stream;
stream.getTracks().forEach(t => {
let sender = c.pc.addTrack(t, stream);
c.setInterval(() => {
updateStats(c, sender);
}, 2000);
});
c.setInterval(() => {
displayStats(localMediaId);
}, 2500);
await setMedia(localMediaId);
setLocalMedia(false);
if(!audio && !video)
return;
let constraints = {audio: audio, video: video};
let stream = null;
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
} catch(e) {
console.error(e);
document.getElementById('presenterbox').checked = false;
await setLocalMedia(false);
return;
}
setMediaChoices();
localMediaId = await newUpStream();
let c = up[localMediaId];
c.stream = stream;
stream.getTracks().forEach(t => {
let sender = c.pc.addTrack(t, stream);
c.setInterval(() => {
updateStats(c, sender);
}, 2000);
});
c.setInterval(() => {
displayStats(localMediaId);
}, 2500);
await setMedia(localMediaId);
}
let shareMediaId = null;
......
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