aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client-web/public/assets/style/room.css14
-rw-r--r--client-web/source/preferences/decl.ts2
-rw-r--r--client-web/source/resource/track.ts35
3 files changed, 49 insertions, 2 deletions
diff --git a/client-web/public/assets/style/room.css b/client-web/public/assets/style/room.css
index 3f62685..928ab4e 100644
--- a/client-web/public/assets/style/room.css
+++ b/client-web/public/assets/style/room.css
@@ -23,9 +23,11 @@
.user .info .name {
font-weight: 400;
}
+
.user.local .info .name {
text-decoration: underline;
}
+
.user .info {
margin-bottom: 1em;
}
@@ -44,6 +46,7 @@
.local-controls {
display: inline;
}
+
.local-controls::before {
content: "|";
}
@@ -51,6 +54,7 @@
.transfer-status {
background-color: #00000040;
}
+
.progress-bar {
z-index: -1;
padding: 0px;
@@ -59,3 +63,13 @@
border-radius: 3px;
background-color: var(--ac-light);
}
+
+
+.resource-track>div {
+ border: 2px solid transparent;
+ border-radius: 4px;
+}
+
+.resource-track>div.audio-active {
+ border: 2px solid rgb(37, 228, 37);
+}
diff --git a/client-web/source/preferences/decl.ts b/client-web/source/preferences/decl.ts
index effd885..f3f8e84 100644
--- a/client-web/source/preferences/decl.ts
+++ b/client-web/source/preferences/decl.ts
@@ -32,6 +32,8 @@ export const PREF_DECLS = {
camera_facing_mode: { type: optional(string), possible_values: ["environment", "user"], description: "Prefer user-facing or env-facing camera" },
auto_gain_control: { type: bool, description: "Automatically adjust mic gain" },
echo_cancellation: { type: bool, description: "Cancel echo" },
+ audio_activity_threshold: { type: number, optional: true, default: 0.003, description: "Audio activity threshold" },
+
// TODO differenciate between mic, cam and screen
optional_audio_default_enable: { type: bool, default: true, description: "Enable audio tracks by default" },
optional_video_default_enable: { type: bool, default: false, description: "Enable video tracks by default" },
diff --git a/client-web/source/resource/track.ts b/client-web/source/resource/track.ts
index 7d53522..58157cf 100644
--- a/client-web/source/resource/track.ts
+++ b/client-web/source/resource/track.ts
@@ -62,24 +62,55 @@ export function new_local_track(info: ProvideInfo, track: TrackHandle): LocalRes
}
function create_track_display(track: TrackHandle): HTMLElement {
- const el = document.createElement("div")
const is_video = track.kind == "video"
- const media_el = is_video ? document.createElement("video") : document.createElement("audio")
+ const is_audio = track.kind == "audio"
+
const stream = new MediaStream([track.track])
+
+ const el = document.createElement("div")
+
+ const media_el = is_video
+ ? document.createElement("video")
+ : document.createElement("audio")
+
media_el.srcObject = stream
media_el.classList.add("media")
media_el.autoplay = true
media_el.controls = true
media_el.addEventListener("pause", () => media_el.play())
+
if (track.local) media_el.muted = true
el.append(media_el)
track.addEventListener("ended", () => {
media_el.srcObject = null // TODO // TODO figure out why i wrote todo here
el.remove()
})
+
+ if (is_audio && PREFS.audio_activity_threshold !== undefined) check_volume(stream, vol => {
+ const active = vol > PREFS.audio_activity_threshold
+ if (active != el.classList.contains("audio-active")) {
+ if (active) el.classList.add("audio-active")
+ else el.classList.remove("audio-active")
+ }
+ })
+
return el
}
+function check_volume(track: MediaStream, cb: (vol: number) => void) {
+ const ctx = new AudioContext();
+ const s = ctx.createMediaStreamSource(track)
+ const a = ctx.createAnalyser()
+ s.connect(a)
+ const samples = new Float32Array(a.fftSize);
+ setInterval(() => {
+ a.getFloatTimeDomainData(samples);
+ let sum = 0.0;
+ for (const amplitude of samples) { sum += amplitude * amplitude; }
+ cb(Math.sqrt(sum / samples.length))
+ }, 1000 / 15)
+}
+
export async function create_camera_res() {
log("media", "requesting user media (camera)")
const user_media = await window.navigator.mediaDevices.getUserMedia({