Microfoon-doorvoer tijdens presenteren (live monitoring) #2158

Closed
opened 2026-09-22 15:01:05 +00:00 by brenno · 0 comments
Owner

Gebruikersscenario

Ik sluit een Bluetooth-microfoon aan op mijn computer. Tijdens een presentatie wil ik in de instellingen van de presentatie kunnen kiezen dat de inkomende audio meteen ook als uitvoer wordt gebruikt — de laptop + aangesloten speakers/beamer werken dan als een kleine versterker voor mijn stem. In beeld zoiets als een microfoon-icoon dat je aanklikt.

Gewenst gedrag

  • Een microfoon-schakelaar in de presenter-cockpit: een Icons.mic/Icons.mic_off-knop in de bedieningsbalk (_buildPresenterControls in lib/widgets/presentation/parts/presenter_overlays.dart), naast de bestaande knoppen (navigatie, overzicht, schermwissel). Tooltip, toetsenbordbereikbaar (commandopalet/sneltoets, bijv. M), en de toestand is altijd zichtbaar — een lopende doorvoer mag nooit stil aan staan.
  • De doorvoer geldt alleen voor de duur dat hij aan staat: bij uitschakelen, bij afsluiten van de presentatie én bij een crash wordt de audiostream volledig afgebroken en de mic vrijgegeven (mic-indicator van het OS uit).
  • Standaard uit, vindbaar aan (zelfde patroon als allowRemoteMedia): de eerste keer aanzetten vraagt de OS-microfoontoestemming; daarna is het één klik.
  • De microfoon die het OS als invoer toont werkt zonder koppelstap in OciDeck — apparaatkeuze doet de gebruiker in het OS; een eigen apparaatkiezer is buiten scope voor de eerste versie.
  • Foutpaden krijgen een melding mét uitweg: geen invoerapparaat, toestemming geweigerd, of de Bluetooth-verbinding valt midden in de presentatie.

Instelling

De vraag noemt "bij de instellingen van de presentatie". Kleinste eerlijke vorm: een schakelaar "Microfoon-doorvoer" in de cockpit én — als gewenst — een bewaarde voorkeur, zodat wie altijd met mic presenteert die niet per sessie hoeft aan te klikken. Waar die voorkeur woont is een ontwerpkeuze: AppSettings (app-breed, naast allowRemoteMedia) past beter dan de deck-eigenschappen (PresentationInfoDialog), want dit is hardwaregedrag van de presentator, geen eigenschap van het deck — een deck dat iemand anders opent hoort niet stil zijn mic aan te zetten.

Technische aanknopingspunten

  • Er zit nu geen audio-capture dependency in pubspec.yaml. flutter_webrtc is er al wel (voor WebrtcMediaCore in lib/meetings/): getUserMedia kan de mic pakken, maar lokale monitoring (mic → eigen speakers) is met WebRTC niet triviaal — dat vraagt een loopback-peer of een andere route. Alternatieven om af te wegen: flutter_sound (full-duplex stream), een dunne platform channel (AVAudioEngine / WASAPI / PulseAudio doen dit in een paar regels), of op web WebAudio (MediaStreamSource → destination, triviaal via de al aanwezige web-dep). Kies de lichtste route die desktop dekt.
  • macOS: NSMicrophoneUsageDescription ontbreekt in macos/Runner/Info.plist — zonder die key crasht de app bij mic-toegang, ook al staat de sandbox uit (Release.entitlements: app-sandbox = false). Toevoegen met een tekst die eerlijk zegt wat er gebeurt.
  • Rondzingen/echo: mic → speakers in dezelfde ruimte kan feedback geven. Verzachten waar het kan: capture met echoCancellation/noiseSuppression aan, en bij het aanzetten op luidspreker-uitvoer een hint tonen ("tip: koptelefoon of losse speaker voorkomt rondzingen"). Geen bevestigingsdialoog — een hint volstaat, de actie is met één klik terug te draaien.
  • Niet op de publieksbalk (AudienceControlsBar): die is bewust kaal (#864/#607). De knop hoort in de privé-cockpit.
  • Privacy: dit is pure lokale doorvoer — geen opname, geen opslag, geen netwerk. Past binnen de productwaarden; het enige consent-moment is de OS-toestemming.
  • Testbaarheid: de native mediastack is niet unit-testbaar (zie WebrtcMediaCore, dat in uncoveredBaseline staat). Zelfde patroon: een dunne seam-interface (MicMonitor oid) met de echte binding in de baseline, alle logica (toestand, foutpaden, gating) erachter en getest met een fake.

Acceptatiecriteria

  • Mic-knop in de presenter-cockpit schakelt doorvoer aan/uit; toestand is zichtbaar.
  • Bluetooth- en ingebouwde mics werken via de standaard OS-invoer.
  • Afsluiten van de presentatie stopt de doorvoer en geeft de mic vrij.
  • NSMicrophoneUsageDescription staat in de macOS Info.plist; Windows/Linux vereisen geen manifest.
  • Geen permissie/geen apparaat → melding met wat de gebruiker kan doen.
  • Standaard uit; geen doorvoer zonder expliciete actie van de presentator.
  • Scope: desktop eerst (macOS/Windows/Linux); web en apparaatkiezer apart te beslissen.

Buiten scope

  • Opname van de presentatie of de stem.
  • Volumemixer/gain-regeling in de UI.
  • Apparaatkiezer in OciDeck (OS-invoer volgen volstaat).
  • Mengen met slide-audio (video's op dia's spelen al via video_player).
## Gebruikersscenario Ik sluit een Bluetooth-microfoon aan op mijn computer. Tijdens een presentatie wil ik in de instellingen van de presentatie kunnen kiezen dat de inkomende audio meteen ook als uitvoer wordt gebruikt — de laptop + aangesloten speakers/beamer werken dan als een kleine versterker voor mijn stem. In beeld zoiets als een microfoon-icoon dat je aanklikt. ## Gewenst gedrag - Een **microfoon-schakelaar in de presenter-cockpit**: een `Icons.mic`/`Icons.mic_off`-knop in de bedieningsbalk (`_buildPresenterControls` in `lib/widgets/presentation/parts/presenter_overlays.dart`), naast de bestaande knoppen (navigatie, overzicht, schermwissel). Tooltip, toetsenbordbereikbaar (commandopalet/sneltoets, bijv. `M`), en de **toestand is altijd zichtbaar** — een lopende doorvoer mag nooit stil aan staan. - De doorvoer geldt **alleen voor de duur dat hij aan staat**: bij uitschakelen, bij afsluiten van de presentatie én bij een crash wordt de audiostream volledig afgebroken en de mic vrijgegeven (mic-indicator van het OS uit). - **Standaard uit, vindbaar aan** (zelfde patroon als `allowRemoteMedia`): de eerste keer aanzetten vraagt de OS-microfoontoestemming; daarna is het één klik. - De microfoon die het OS als invoer toont werkt zonder koppelstap in OciDeck — apparaatkeuze doet de gebruiker in het OS; een eigen apparaatkiezer is **buiten scope** voor de eerste versie. - Foutpaden krijgen een melding mét uitweg: geen invoerapparaat, toestemming geweigerd, of de Bluetooth-verbinding valt midden in de presentatie. ## Instelling De vraag noemt "bij de instellingen van de presentatie". Kleinste eerlijke vorm: een schakelaar "Microfoon-doorvoer" in de cockpit én — als gewenst — een bewaarde voorkeur, zodat wie altijd met mic presenteert die niet per sessie hoeft aan te klikken. Waar die voorkeur woont is een ontwerpkeuze: `AppSettings` (app-breed, naast `allowRemoteMedia`) past beter dan de deck-eigenschappen (`PresentationInfoDialog`), want dit is hardwaregedrag van de presentator, geen eigenschap van het deck — een deck dat iemand anders opent hoort niet stil zijn mic aan te zetten. ## Technische aanknopingspunten - Er zit nu **geen audio-capture dependency** in `pubspec.yaml`. `flutter_webrtc` is er al wel (voor `WebrtcMediaCore` in `lib/meetings/`): `getUserMedia` kan de mic pakken, maar lokale monitoring (mic → eigen speakers) is met WebRTC niet triviaal — dat vraagt een loopback-peer of een andere route. Alternatieven om af te wegen: `flutter_sound` (full-duplex stream), een dunne platform channel (AVAudioEngine / WASAPI / PulseAudio doen dit in een paar regels), of op web WebAudio (`MediaStreamSource → destination`, triviaal via de al aanwezige `web`-dep). Kies de lichtste route die desktop dekt. - **macOS**: `NSMicrophoneUsageDescription` ontbreekt in `macos/Runner/Info.plist` — zonder die key crasht de app bij mic-toegang, ook al staat de sandbox uit (`Release.entitlements`: `app-sandbox = false`). Toevoegen met een tekst die eerlijk zegt wat er gebeurt. - **Rondzingen/echo**: mic → speakers in dezelfde ruimte kan feedback geven. Verzachten waar het kan: capture met `echoCancellation`/`noiseSuppression` aan, en bij het aanzetten op luidspreker-uitvoer een hint tonen ("tip: koptelefoon of losse speaker voorkomt rondzingen"). Geen bevestigingsdialoog — een hint volstaat, de actie is met één klik terug te draaien. - **Niet op de publieksbalk** (`AudienceControlsBar`): die is bewust kaal (#864/#607). De knop hoort in de privé-cockpit. - **Privacy**: dit is pure lokale doorvoer — geen opname, geen opslag, geen netwerk. Past binnen de productwaarden; het enige consent-moment is de OS-toestemming. - **Testbaarheid**: de native mediastack is niet unit-testbaar (zie `WebrtcMediaCore`, dat in `uncoveredBaseline` staat). Zelfde patroon: een dunne seam-interface (`MicMonitor` oid) met de echte binding in de baseline, alle logica (toestand, foutpaden, gating) erachter en getest met een fake. ## Acceptatiecriteria - [ ] Mic-knop in de presenter-cockpit schakelt doorvoer aan/uit; toestand is zichtbaar. - [ ] Bluetooth- en ingebouwde mics werken via de standaard OS-invoer. - [ ] Afsluiten van de presentatie stopt de doorvoer en geeft de mic vrij. - [ ] `NSMicrophoneUsageDescription` staat in de macOS Info.plist; Windows/Linux vereisen geen manifest. - [ ] Geen permissie/geen apparaat → melding met wat de gebruiker kan doen. - [ ] Standaard uit; geen doorvoer zonder expliciete actie van de presentator. - [ ] Scope: desktop eerst (macOS/Windows/Linux); web en apparaatkiezer apart te beslissen. ## Buiten scope - Opname van de presentatie of de stem. - Volumemixer/gain-regeling in de UI. - Apparaatkiezer in OciDeck (OS-invoer volgen volstaat). - Mengen met slide-audio (video's op dia's spelen al via `video_player`).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#2158
No description provided.