aboutsummaryrefslogtreecommitdiff
path: root/client-web/source/resource
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-01-17 22:34:25 +0100
committermetamuffin <metamuffin@disroot.org>2023-01-17 22:34:25 +0100
commit2fc81eee903efa1f6da77b9f58fd2179356dad9f (patch)
tree6c047c05c636f366220ca34f3312ccc7fb91e85c /client-web/source/resource
parentf85d40d8c6cc2f3b58d1e0ea7f0382db88fffd4e (diff)
parent67694f908f7fc76f78566e6f02d89db2d7a19c1d (diff)
downloadkeks-meet-2fc81eee903efa1f6da77b9f58fd2179356dad9f.tar
keks-meet-2fc81eee903efa1f6da77b9f58fd2179356dad9f.tar.bz2
keks-meet-2fc81eee903efa1f6da77b9f58fd2179356dad9f.tar.zst
merge
Diffstat (limited to 'client-web/source/resource')
-rw-r--r--client-web/source/resource/track.ts55
1 files changed, 49 insertions, 6 deletions
diff --git a/client-web/source/resource/track.ts b/client-web/source/resource/track.ts
index 7d53522..22af16f 100644
--- a/client-web/source/resource/track.ts
+++ b/client-web/source/resource/track.ts
@@ -5,7 +5,7 @@
*/
/// <reference lib="dom" />
import { ProvideInfo } from "../../../common/packets.d.ts";
-import { ebutton, ediv } from "../helper.ts";
+import { ebutton, ediv, elabel } from "../helper.ts";
import { log } from "../logger.ts";
import { on_pref_changed, PREFS } from "../preferences/mod.ts";
import { get_rnnoise_node } from "../rnnoise.ts";
@@ -48,11 +48,12 @@ export const resource_track: ResourceHandlerDecl = {
}
}
-export function new_local_track(info: ProvideInfo, track: TrackHandle): LocalResource {
+export function new_local_track(info: ProvideInfo, track: TrackHandle, ...extra_controls: HTMLElement[]): LocalResource {
return {
info,
el: ediv({},
- create_track_display(track)
+ create_track_display(track),
+ ...extra_controls
),
destroy() { track.end() },
on_request(_user, _create_channel) {
@@ -62,24 +63,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({
@@ -141,5 +173,16 @@ export async function create_mic_res() {
clear_gain_cb()
destination.disconnect()
})
- return new_local_track({ id: t.id, kind: "track", track_kind: "audio", label: "Microphone" }, t)
+
+ const mute = document.createElement("input")
+ mute.type = "checkbox"
+ mute.onchange = () => {
+ log("media", mute.checked ? "muted" : "unmuted")
+ if (mute.checked) gain.gain.value = Number.MIN_VALUE
+ else gain.gain.value = PREFS.microphone_gain
+ }
+ const mute_label = elabel("Mute", { class: "check-button" })
+ mute_label.prepend(mute)
+
+ return new_local_track({ id: t.id, kind: "track", track_kind: "audio", label: "Microphone" }, t, mute_label)
}