Add audio streaming via USB microphone

- Neuer Endpunkt GET /audio: ffmpeg liest von plughw:2,0 (USB-Soundkarte CM108)
  und streamt Ogg/Opus mit 16kHz Mono 24kbps
- live.html: Ton-Button (🔇/🔊) startet/stoppt Audio-Stream on demand
- setup.sh: ffmpeg installieren, pi zur audio-Gruppe hinzufügen
- pi zur audio-Gruppe hinzugefügt (war nötig für /dev/snd Zugriff)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Julian Vollmer 2026-05-18 18:15:21 +02:00
parent 73faa66535
commit a53eceb83a
3 changed files with 65 additions and 1 deletions

View File

@ -104,6 +104,47 @@ def stream():
) )
# ---------------------------------------------------------------------------
# Audio-Stream (Ogg/Opus via ffmpeg)
# ---------------------------------------------------------------------------
AUDIO_DEVICE = "plughw:2,0"
AUDIO_SAMPLERATE = 16000
def generate_audio():
cmd = [
"ffmpeg",
"-f", "alsa",
"-i", AUDIO_DEVICE,
"-ar", str(AUDIO_SAMPLERATE),
"-ac", "1",
"-c:a", "libopus",
"-b:a", "24k",
"-f", "ogg",
"-",
]
process = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL
)
try:
while True:
chunk = process.stdout.read(4096)
if not chunk:
break
yield chunk
finally:
process.kill()
@app.route("/audio")
def audio():
return Response(
generate_audio(),
mimetype="audio/ogg; codecs=opus",
)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# WLAN-Verwaltung # WLAN-Verwaltung
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@ -163,9 +163,12 @@
<div id="bottom-bar"> <div id="bottom-bar">
<div id="clock"></div> <div id="clock"></div>
<button class="btn" id="audio-btn" onclick="toggleAudio()">🔇 Ton an</button>
<a class="btn" href="/">⚙ Einstellungen</a> <a class="btn" href="/">⚙ Einstellungen</a>
</div> </div>
<audio id="audio-stream" src="/audio" preload="none"></audio>
<script> <script>
// UI bei Tap/Klick kurz einblenden // UI bei Tap/Klick kurz einblenden
let hideTimer; let hideTimer;
@ -190,6 +193,24 @@
updateClock(); updateClock();
setInterval(updateClock, 1000); setInterval(updateClock, 1000);
// Audio
let audioOn = false;
function toggleAudio() {
const a = document.getElementById("audio-stream");
const btn = document.getElementById("audio-btn");
if (audioOn) {
a.pause();
a.src = "";
btn.textContent = "🔇 Ton an";
audioOn = false;
} else {
a.src = "/audio";
a.play();
btn.textContent = "🔊 Ton aus";
audioOn = true;
}
}
// Fullscreen // Fullscreen
function toggleFullscreen() { function toggleFullscreen() {
if (!document.fullscreenElement) { if (!document.fullscreenElement) {

View File

@ -30,7 +30,8 @@ apt-get install -y \
rpicam-apps \ rpicam-apps \
avahi-daemon \ avahi-daemon \
network-manager \ network-manager \
iptables iptables \
ffmpeg
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# 2. Kamera-Interface aktivieren # 2. Kamera-Interface aktivieren
@ -50,6 +51,7 @@ info "Verzeichnisse anlegen..."
mkdir -p /var/lib/babycam mkdir -p /var/lib/babycam
chown pi:pi /var/lib/babycam chown pi:pi /var/lib/babycam
usermod -aG video pi usermod -aG video pi
usermod -aG audio pi
info "Projektdateien nach $INSTALL_DIR kopieren..." info "Projektdateien nach $INSTALL_DIR kopieren..."
mkdir -p "$INSTALL_DIR" mkdir -p "$INSTALL_DIR"