diff options
author | Maxim Devaev <[email protected]> | 2025-01-18 21:57:48 +0200 |
---|---|---|
committer | Maxim Devaev <[email protected]> | 2025-01-18 21:57:48 +0200 |
commit | 78557b0c47f1b2bd7fac30d319ce957892aa34e9 (patch) | |
tree | 68eecc23ca71e44bc33662b24133041d47c19239 | |
parent | e1e360563008b1e1742e4c6bfbe85869320b7881 (diff) | |
parent | f042ed38e0926557f475f58e8b904ccb1a8beade (diff) |
Merge branch 'mic'
-rw-r--r-- | kvmd/apps/__init__.py | 5 | ||||
-rw-r--r-- | kvmd/apps/otg/__init__.py | 16 | ||||
-rw-r--r-- | web/kvm/index.html | 9 | ||||
-rw-r--r-- | web/kvm/navbar-system.pug | 4 | ||||
-rw-r--r-- | web/share/js/kvm/stream.js | 13 | ||||
-rw-r--r-- | web/share/js/kvm/stream_janus.js | 24 |
6 files changed, 64 insertions, 7 deletions
diff --git a/kvmd/apps/__init__.py b/kvmd/apps/__init__.py index 091319ca..5ad38d90 100644 --- a/kvmd/apps/__init__.py +++ b/kvmd/apps/__init__.py @@ -611,6 +611,11 @@ def _get_config_scheme() -> dict: "kvm_mac": Option("", type=valid_mac, if_empty=""), }, + "audio": { + "enabled": Option(False, type=valid_bool), + "start": Option(True, type=valid_bool), + }, + "drives": { "enabled": Option(False, type=valid_bool), "start": Option(True, type=valid_bool), diff --git a/kvmd/apps/otg/__init__.py b/kvmd/apps/otg/__init__.py index f21fdf4e..c50626c0 100644 --- a/kvmd/apps/otg/__init__.py +++ b/kvmd/apps/otg/__init__.py @@ -112,6 +112,18 @@ class _GadgetConfig: self.__msd_instance = 0 _mkdir(meta_path) + def add_audio_capture(self, start: bool) -> None: + eps = 2 + func = "uac2.usb0" + func_path = self.__create_function(func) + _write(join(func_path, "c_chmask"), 0) + _write(join(func_path, "p_chmask"), 0b11) + _write(join(func_path, "p_srate"), 48000) + _write(join(func_path, "p_ssize"), 2) + if start: + self.__start_function(func, eps) + self.__create_meta(func, "Audio Capture", eps) + def add_serial(self, start: bool) -> None: eps = 3 func = "acm.usb0" @@ -295,6 +307,10 @@ def _cmd_start(config: Section) -> None: # pylint: disable=too-many-statements, logger.info("===== Serial =====") gc.add_serial(cod.serial.start) + if cod.audio.enabled: + logger.info("===== Audio Capture =====") + gc.add_audio_capture(cod.audio.start) + logger.info("===== Preparing complete =====") logger.info("Enabling the gadget ...") diff --git a/web/kvm/index.html b/web/kvm/index.html index 713e1c84..9427e3f8 100644 --- a/web/kvm/index.html +++ b/web/kvm/index.html @@ -262,6 +262,15 @@ </td> <td class="value-number" id="stream-audio-volume-value"></td> </tr> + <tr class="feature-disabled" id="stream-mic"> + <td>Microphone:</td> + <td align="right"> + <div class="switch-box"> + <input disabled type="checkbox" id="stream-mic-switch"> + <label for="stream-mic-switch"><span class="switch-inner"></span><span class="switch"></span></label> + </div> + </td> + </tr> </table> <hr> <div class="buttons buttons-row"> diff --git a/web/kvm/navbar-system.pug b/web/kvm/navbar-system.pug index 55d70757..5c675601 100644 --- a/web/kvm/navbar-system.pug +++ b/web/kvm/navbar-system.pug @@ -67,10 +67,12 @@ li(id="system-dropdown" class="right") label(for="stream-orient-radio-180") 180° input(type="radio" id="stream-orient-radio-270" name="stream-orient-radio" value="270") label(for="stream-orient-radio-270") 270° - tr(id="stream-audio", class="feature-disabled") + tr(id="stream-audio" class="feature-disabled") td Audio volume: td(class="value-slider") #[input(type="range" id="stream-audio-volume-slider" class="slider")] td(id="stream-audio-volume-value" class="value-number") + tr(id="stream-mic" class="feature-disabled") + +menu_switch_notable("stream-mic-switch", "Microphone", false, false) hr div(class="buttons buttons-row") button(data-force-hide-menu data-show-window="stream-window" class="row33") • Show stream diff --git a/web/share/js/kvm/stream.js b/web/share/js/kvm/stream.js index 7d947736..2de3d469 100644 --- a/web/share/js/kvm/stream.js +++ b/web/share/js/kvm/stream.js @@ -94,6 +94,15 @@ export function Streamer() { __resetStream(); } } + tools.el.setEnabled($("stream-mic-switch"), !!value); + }); + + tools.storage.bindSimpleSwitch($("stream-mic-switch"), "stream.mic", false, function(allow_mic) { + if (__streamer.getMode() === "janus") { + if (__streamer.isMicAllowed() !== allow_mic) { + __resetStream(); + } + } }); tools.el.setOnClick($("stream-screenshot-button"), __clickScreenshotButton); @@ -206,6 +215,7 @@ export function Streamer() { tools.feature.setEnabled($("stream-mode"), f.h264); if (!f.h264) { tools.feature.setEnabled($("stream-audio"), false); + tools.feature.setEnabled($("stream-mic"), false); } let mode = tools.storage.get("stream.mode", "janus"); @@ -291,7 +301,7 @@ export function Streamer() { __streamer.stopStream(); if (mode === "janus") { __streamer = new JanusStreamer(__setActive, __setInactive, __setInfo, - tools.storage.getInt("stream.orient", 0), !$("stream-video").muted); + tools.storage.getInt("stream.orient", 0), !$("stream-video").muted, $("stream-mic-switch").checked); // Firefox doesn't support RTP orientation: // - https://bugzilla.mozilla.org/show_bug.cgi?id=1316448 tools.feature.setEnabled($("stream-orient"), !tools.browser.is_firefox); @@ -303,6 +313,7 @@ export function Streamer() { } tools.feature.setEnabled($("stream-orient"), false); tools.feature.setEnabled($("stream-audio"), false); // Enabling in stream_janus.js + tools.feature.setEnabled($("stream-mic"), false); // Ditto } if (wm.isWindowVisible($("stream-window"))) { __streamer.ensureStream((__state && __state.streamer !== undefined) ? __state.streamer : null); diff --git a/web/share/js/kvm/stream_janus.js b/web/share/js/kvm/stream_janus.js index 09ee75da..449450b7 100644 --- a/web/share/js/kvm/stream_janus.js +++ b/web/share/js/kvm/stream_janus.js @@ -29,11 +29,13 @@ import {tools, $} from "../tools.js"; var _Janus = null; -export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, __allow_audio) { +export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, __allow_audio, __allow_mic) { var self = this; /************************************************************************/ + __allow_mic = (__allow_audio && __allow_mic); // XXX: Mic only with audio + var __stop = false; var __ensuring = false; @@ -51,8 +53,18 @@ export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, _ self.getOrientation = () => __orient; self.isAudioAllowed = () => __allow_audio; - - self.getName = () => (__allow_audio ? "WebRTC H.264 + Audio" : "WebRTC H.264"); + self.isMicAllowed = () => __allow_mic; + + self.getName = function() { + let name = "WebRTC H.264"; + if (__allow_audio) { + name += " + Audio"; + if (__allow_mic) { + name += " + Mic"; + } + } + return name; + }; self.getMode = () => "janus"; self.getResolution = function() { @@ -229,6 +241,7 @@ export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, _ __setInfo(false, false, ""); } else if (msg.result.status === "features") { tools.feature.setEnabled($("stream-audio"), msg.result.features.audio); + tools.feature.setEnabled($("stream-mic"), msg.result.features.mic); } } else if (msg.error_code || msg.error) { __logError("Got uStreamer error message:", msg.error_code, "-", msg.error); @@ -251,7 +264,7 @@ export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, _ __logInfo("Handling SDP:", jsep); let tracks = [{"type": "video", "capture": false, "recv": true, "add": true}]; if (__allow_audio) { - tracks.push({"type": "audio", "capture": false, "recv": true, "add": true}); + tracks.push({"type": "audio", "capture": __allow_mic, "recv": true, "add": true}); } __handle.createAnswer({ "jsep": jsep, @@ -354,11 +367,12 @@ export function JanusStreamer(__setActive, __setInactive, __setInfo, __orient, _ var __sendWatch = function() { if (__handle) { - __logInfo(`Sending WATCH(orient=${__orient}, audio=${__allow_audio}) + FEATURES ...`); + __logInfo(`Sending WATCH(orient=${__orient}, audio=${__allow_audio}, mic=${__allow_mic}) + FEATURES ...`); __handle.send({"message": {"request": "features"}}); __handle.send({"message": {"request": "watch", "params": { "orientation": __orient, "audio": __allow_audio, + "mic": __allow_mic, }}}); } }; |