diff --git a/gum_test.html b/gum_test.html
index 290028c..5320481 100644
--- a/gum_test.html
+++ b/gum_test.html
@@ -92,14 +92,24 @@
getUserMedia is missing!
video.setAttribute("width", 640);
video.setAttribute("height", 480);
- const muted = document.createElement("input");
- muted.type = "checkbox";
- muted.checked = true;
- muted.onclick = () => { video.muted = muted.checked; };
+ const equalizer = document.createElement("canvas");
+ equalizer.setAttribute("width", 25);
+ equalizer.setAttribute("height", 480);
- const mute = document.createElement("label");
- mute.innerHTML = "Volume mute";
- mute.insertBefore(muted, mute.firstChild);
+ function createCheckbox(textContent, checked, type = "checkbox") {
+ const label = Object.assign(document.createElement("label"), {textContent});
+ const input = Object.assign(document.createElement("input"), {type});
+ label.insertBefore(input, label.firstChild);
+ return Object.assign(input, {checked});
+ }
+
+ const camOn = createCheckbox("📹", true);
+ const micOn = createCheckbox("🎙️", true);
+ const elementMuted = createCheckbox("🔇", true);
+ elementMuted.onclick = () => {
+ audio.muted = elementMuted.checked;
+ video.muted = elementMuted.checked;
+ };
const snapshots = [];
@@ -156,8 +166,8 @@ getUserMedia is missing!
}
video.srcObject = null;
content.removeChild(video);
- if (mute.parentNode) {
- controls.removeChild(mute);
+ if (equalizer.parentNode) {
+ content.removeChild(equalizer);
}
fps.innerHTML = "";
stopbuttons.removeChild(snapshot);
@@ -170,6 +180,12 @@ getUserMedia is missing!
}
audio.srcObject = null;
content.removeChild(audio);
+ content.removeChild(equalizer);
+ }
+ for (const muted of [elementMuted, camOn, micOn]) {
+ if (muted.parentNode.parentNode) {
+ controls.removeChild(muted.parentNode);
+ }
}
saved_stream = null;
stop.style.display = "none";
@@ -180,10 +196,8 @@ getUserMedia is missing!
function pauseMedia() {
if (saved_stream) {
if (saved_stream.getVideoTracks().length) {
- video.srcObject = saved_stream;
video.play();
} else {
- audio.srcObject = saved_stream;
audio.play();
}
saved_stream = null;
@@ -191,11 +205,9 @@ getUserMedia is missing!
if (video.srcObject) {
video.pause();
saved_stream = video.srcObject;
- video.srcObject = null;
} else if (audio.srcObject) {
audio.pause();
saved_stream = audio.srcObject;
- audio.srcObject = null;
}
}
}
@@ -212,12 +224,18 @@ getUserMedia is missing!
try {
const stream = await navigator.mediaDevices[gum](constraints);
message.innerHTML = "Success!
";
- if (stream.getVideoTracks().length) {
+ const [audioTrack] = stream.getAudioTracks();
+ const [videoTrack] = stream.getVideoTracks();
+ if (audioTrack) {
+ controls.appendChild(elementMuted.parentNode);
+ audio.muted = elementMuted.checked;
+ video.muted = elementMuted.checked;
+ }
+ if (videoTrack) {
content.appendChild(video);
- if (stream.getAudioTracks().length) {
- controls.appendChild(mute);
- video.muted = muted.checked;
- }
+ controls.appendChild(camOn.parentNode);
+ camOn.onclick = () => { videoTrack.enabled = camOn.checked; };
+ camOn.onclick();
video.srcObject = stream;
video.play();
frames.innerHTML = '';
@@ -231,6 +249,13 @@ getUserMedia is missing!
audio.srcObject = stream;
audio.play();
}
+ if (audioTrack) {
+ content.appendChild(equalizer);
+ startEqualizer(stream);
+ controls.appendChild(micOn.parentNode);
+ micOn.onclick = () => { audioTrack.enabled = micOn.checked; };
+ micOn.onclick();
+ }
running = true;
} catch (err) {
if (location.protocol != "https:") {
@@ -287,6 +312,38 @@ getUserMedia is missing!
setTimeout(captureImage, 2000);
}
}
+
+ function startEqualizer(stream) {
+ const audioCtx = new AudioContext();
+ const analyser = audioCtx.createAnalyser();
+ audioCtx.createMediaStreamSource(stream).connect(analyser);
+
+ const canvasCtx = equalizer.getContext("2d");
+ const data = new Uint8Array(equalizer.width);
+
+ let interval = setInterval(() => {
+ if (stream.getAudioTracks()[0].readyState != "live") {
+ clearInterval(interval);
+ return;
+ }
+ canvasCtx.fillStyle = "#ffffff";
+ canvasCtx.clearRect(0, 0, equalizer.width, equalizer.height);
+ analyser.getByteFrequencyData(data);
+ canvasCtx.lineWidth = 2;
+ let x = 0;
+ for (let y of data) {
+ y = equalizer.height - (y / 128) * equalizer.height / 4;
+ let c = Math.floor((x*255)/equalizer.width);
+ canvasCtx.fillStyle = "rgb("+c+",0,"+(255-x)+")";
+ canvasCtx.fillRect(x, y, 2, equalizer.height - y)
+ x++;
+ }
+ analyser.getByteTimeDomainData(data);
+ canvasCtx.lineWidth = 5;
+ canvasCtx.beginPath();
+ canvasCtx.stroke();
+ }, 1000 * equalizer.width / audioCtx.sampleRate);
+ }