fixxed alsa sound problems

This commit is contained in:
2026-10-05 11:33:37 +02:00
parent f7654fa8ea
commit 2e311119b0
10 changed files with 42 additions and 29 deletions
Binary file not shown.
Binary file not shown.
+3 -2
View File
@@ -4,5 +4,6 @@ from app import create_app
app = create_app() app = create_app()
if __name__ == '__main__': if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True) # Der Werkzeug-ReLoader startet zwei Prozesse. Beide würden versuchen,
# exklusiv auf dasselbe ALSA-Gerät zuzugreifen.
app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=False)
+22 -13
View File
@@ -4,14 +4,10 @@ import logging
import threading import threading
import time import time
import os import os
import pygame
from flask import Flask from flask import Flask
from .utils.logging import setup_logging, cleanup_old_log_dirs from .utils.logging import setup_logging, cleanup_old_log_dirs
from .routes.main import main_bp
from .routes.admin import admin_bp
from .routes.api import api_bp
from .bluetooth.manager import init_bluetooth from .bluetooth.manager import init_bluetooth
logger = logging.getLogger(__name__) # ← Logger für diese Datei logger = logging.getLogger(__name__) # ← Logger für diese Datei
@@ -30,16 +26,29 @@ def create_app():
# Bluetooth initialisieren (Monitor-Thread startet automatisch) # Bluetooth initialisieren (Monitor-Thread startet automatisch)
init_bluetooth() init_bluetooth()
# pygame initialisieren (einmalig) # pygame initialisieren (einmalig). Ein Audiofehler darf die Hub-Steuerung
# nicht am Start hindern; die API versucht die Initialisierung später erneut.
from config import Config from config import Config
pygame.mixer.pre_init(frequency=Config.AUDIO_FREQ, if Config.AUDIO_DEVICE:
size=Config.AUDIO_SIZE, os.environ['AUDIODEV'] = Config.AUDIO_DEVICE
channels=Config.AUDIO_CHANNELS, import pygame
buffer=Config.AUDIO_BUFFER) try:
pygame.mixer.init() init_args = {
pygame.mixer.set_num_channels(Config.AUDIO_NUM_CHANNELS) # genug parallele Kanäle für BG + Effekte 'frequency': Config.AUDIO_FREQ,
pygame.mixer.music.set_volume(0.8) # Standard-Lautstärke (für Legacy-Fälle) 'size': Config.AUDIO_SIZE,
app.logger.info("pygame initialisiert") 'channels': Config.AUDIO_CHANNELS,
'buffer': Config.AUDIO_BUFFER,
}
if Config.AUDIO_DEVICE:
init_args['devicename'] = Config.AUDIO_DEVICE
pygame.mixer.init(**init_args)
pygame.mixer.set_num_channels(Config.AUDIO_NUM_CHANNELS)
pygame.mixer.music.set_volume(0.8)
app.logger.info(f"pygame initialisiert (Gerät: {Config.AUDIO_DEVICE or 'SDL-Standard'})")
except pygame.error as e:
app.logger.error(f"Audio konnte nicht initialisiert werden: {e}")
if Config.AUDIO_REQUIRED:
raise
# Blueprints registrieren # Blueprints registrieren
from .routes.main import main_bp from .routes.main import main_bp
Binary file not shown.
Binary file not shown.
+9 -6
View File
@@ -29,13 +29,16 @@ DEFAULT_MAX_PER_HOUR = 2
DEFAULT_WINDOW_SECONDS = 3600 DEFAULT_WINDOW_SECONDS = 3600
def _ensure_mixer(): def _ensure_mixer():
from config import Config
if not pygame.mixer.get_init(): if not pygame.mixer.get_init():
pygame.mixer.pre_init(frequency=Config.AUDIO_FREQ, init_args = {
size=Config.AUDIO_SIZE, 'frequency': Config.AUDIO_FREQ,
channels=Config.AUDIO_CHANNELS, 'size': Config.AUDIO_SIZE,
buffer=Config.AUDIO_BUFFER) 'channels': Config.AUDIO_CHANNELS,
pygame.mixer.init() 'buffer': Config.AUDIO_BUFFER,
}
if Config.AUDIO_DEVICE:
init_args['devicename'] = Config.AUDIO_DEVICE
pygame.mixer.init(**init_args)
pygame.mixer.set_num_channels(Config.AUDIO_NUM_CHANNELS) pygame.mixer.set_num_channels(Config.AUDIO_NUM_CHANNELS)
def _load_sound(file_path): def _load_sound(file_path):
+7 -3
View File
@@ -21,11 +21,15 @@ class Config:
AUDIO_CHANNELS = 2 AUDIO_CHANNELS = 2
AUDIO_BUFFER = 2048 # größerer Buffer reduziert Knacksen AUDIO_BUFFER = 2048 # größerer Buffer reduziert Knacksen
AUDIO_NUM_CHANNELS = 16 AUDIO_NUM_CHANNELS = 16
# ALSA/SDL-Gerät, z. B. "default", "plughw:CARD=PCM5102,DEV=0"
# oder ein in /etc/asound.conf definiertes Gerät. Leer = SDL-Standard.
AUDIO_DEVICE = os.environ.get('MKCONTROL_AUDIO_DEVICE') or None
AUDIO_REQUIRED = os.environ.get('MKCONTROL_AUDIO_REQUIRED', 'false').lower() in ('1', 'true', 'yes')
# Optional: absolute Pfade, falls du später Docker o.ä. nutzt # Optional: absolute Pfade, falls du später Docker o.ä. nutzt
# CONFIG_DIR = os.path.join(os.path.dirname(__file__), 'configs') # CONFIG_DIR = os.path.join(os.path.dirname(__file__), 'configs')
APP_NAME = "MK Sound & Control" APP_NAME = "Mini-World Control Center"
APP_NAME_SHORT = "MKSC" # für Tab-Titel, wenns kurz sein soll APP_NAME_SHORT = "MWCC" # für Tab-Titel, wenns kurz sein soll
APP_VERSION = "0.9.β" APP_VERSION = "0.9.β"
APP_DESCRIPTION = "Websteuerung für MouldKing MK4/MK6-Hubs mit Soundboard" APP_DESCRIPTION = "Websteuerung für MouldKing MK4/MK6-Hubs mit Soundboard und Aktorensteuerung"
BIN
View File
Binary file not shown.
+1 -5
View File
@@ -31,6 +31,7 @@
{% block head_extra %}{% endblock %} {% block head_extra %}{% endblock %}
</head> </head>
<body class="d-flex flex-column min-vh-100"> <body class="d-flex flex-column min-vh-100">
<!-- Navbar --> <!-- Navbar -->
@@ -70,11 +71,6 @@
</nav> </nav>
<!-- Hauptinhalt --> <!-- Hauptinhalt -->
<header>
<h1>{{ config.APP_NAME }}</h1>
<!-- oder als Logo + Slogan -->
</header>
<main class="flex-grow-1 py-4"> <main class="flex-grow-1 py-4">
<div class="container"> <div class="container">
{% with messages = get_flashed_messages(with_categories=true) %} {% with messages = get_flashed_messages(with_categories=true) %}