Files
sdb-back/app/routes/soundboard.py
JSC 7455811860 feat: Add VLC service for sound playback and management
- Implemented VLCService to handle sound playback using VLC.
- Added routes for soundboard management including play, stop, and status.
- Introduced admin routes for sound normalization and scanning.
- Updated user model and services to accommodate new functionalities.
- Enhanced error handling and logging throughout the application.
- Updated dependencies to include python-vlc for sound playback capabilities.
2025-07-03 21:25:50 +02:00

122 lines
3.6 KiB
Python

"""Soundboard routes."""
from flask import Blueprint, jsonify, request
from app.models.sound import Sound, SoundType
from app.services.vlc_service import vlc_service
from app.services.decorators import require_auth
bp = Blueprint("soundboard", __name__, url_prefix="/api/soundboard")
@bp.route("/sounds", methods=["GET"])
@require_auth
def get_sounds():
"""Get all soundboard sounds."""
try:
# Get filter parameters
sound_type = request.args.get("type", "SDB")
# Validate sound type
if sound_type not in [t.value for t in SoundType]:
return jsonify({"error": "Invalid sound type"}), 400
# Get sounds from database
sounds = Sound.find_by_type(sound_type)
# Convert to dict format
sounds_data = [sound.to_dict() for sound in sounds]
return jsonify(
{
"sounds": sounds_data,
"total": len(sounds_data),
"type": sound_type,
}
)
except Exception as e:
return jsonify({"error": str(e)}), 500
@bp.route("/sounds/<int:sound_id>/play", methods=["POST"])
@require_auth
def play_sound(sound_id: int):
"""Play a specific sound."""
try:
success = vlc_service.play_sound(sound_id)
if success:
return jsonify({"message": "Sound playing", "sound_id": sound_id})
else:
return jsonify(
{"error": "Sound not found or cannot be played"}
), 404
except Exception as e:
return jsonify({"error": str(e)}), 500
@bp.route("/stop-all", methods=["POST"])
@require_auth
def stop_all_sounds():
"""Stop all currently playing sounds."""
try:
# Try normal stop first
vlc_service.stop_all()
# Wait a moment and check if any are still playing
import time
time.sleep(0.2)
# If there are still instances, force stop them
if vlc_service.get_playing_count() > 0:
stopped_count = vlc_service.force_stop_all()
return jsonify({
"message": f"Force stopped {stopped_count} sounds",
"forced": True
})
return jsonify({"message": "All sounds stopped"})
except Exception as e:
return jsonify({"error": str(e)}), 500
@bp.route("/force-stop", methods=["POST"])
@require_auth
def force_stop_all_sounds():
"""Force stop all sounds with aggressive cleanup."""
try:
stopped_count = vlc_service.force_stop_all()
return jsonify({
"message": f"Force stopped {stopped_count} sound instances",
"stopped_count": stopped_count
})
except Exception as e:
return jsonify({"error": str(e)}), 500
@bp.route("/status", methods=["GET"])
@require_auth
def get_status():
"""Get current playback status."""
try:
playing_count = vlc_service.get_playing_count()
# Get detailed instance information
with vlc_service.lock:
instances = []
for instance_id, instance_data in vlc_service.instances.items():
instances.append({
"id": instance_id,
"sound_id": instance_data.get("sound_id"),
"created_at": instance_data.get("created_at"),
})
return jsonify(
{
"playing_count": playing_count,
"is_playing": playing_count > 0,
"instances": instances,
}
)
except Exception as e:
return jsonify({"error": str(e)}), 500