feat: Implement host system volume control and update player service to use it
Some checks failed
Backend CI / lint (push) Failing after 10s
Backend CI / test (push) Has been cancelled

This commit is contained in:
JSC
2025-09-27 03:33:11 +02:00
parent 0806d541f2
commit 4b8496d025
6 changed files with 375 additions and 58 deletions

View File

@@ -70,12 +70,14 @@ class VLCPlayerService:
)
return "vlc"
async def play_sound(self, sound: Sound, volume: int | None = None) -> bool:
async def play_sound(self, sound: Sound) -> bool:
"""Play a sound using a new VLC subprocess instance.
VLC always plays at 100% volume. Host system volume is controlled separately
by the player service.
Args:
sound: The Sound object to play
volume: Volume level (0-100). If None, uses current player volume.
Returns:
bool: True if VLC process was launched successfully, False otherwise
@@ -88,19 +90,6 @@ class VLCPlayerService:
logger.error("Sound file not found: %s", sound_path)
return False
# Get volume from player service if not provided
if volume is None:
try:
from app.services.player import get_player_service # noqa: PLC0415
player = get_player_service()
volume = player.state.volume
except RuntimeError:
logger.warning("Could not get player volume, using default 80")
volume = 80
# Ensure volume is in valid range and is an integer
volume = max(0, min(100, int(volume))) if volume is not None else 80
# VLC command arguments for immediate playback
cmd = [
self.vlc_executable,
@@ -111,7 +100,7 @@ class VLCPlayerService:
"--no-video", # Audio only
"--no-repeat", # Don't repeat
"--no-loop", # Don't loop
f"--volume={volume}", # Set volume to match player
"--volume=100", # Always use 100% VLC volume
]
# Launch VLC process asynchronously without waiting
@@ -347,7 +336,10 @@ class VLCPlayerService:
"""
from fastapi import HTTPException, status # noqa: PLC0415, I001
from app.services.credit import CreditService, InsufficientCreditsError # noqa: PLC0415
from app.services.credit import (
CreditService,
InsufficientCreditsError,
) # noqa: PLC0415
if not self.db_session_factory:
raise HTTPException(
@@ -384,19 +376,8 @@ class VLCPlayerService:
),
) from e
# Get current player volume
try:
from app.services.player import get_player_service # noqa: PLC0415
player = get_player_service()
current_volume = player.state.volume
except RuntimeError:
logger.warning(
"Could not get player volume for credit play, using default 80",
)
current_volume = 80
# Play the sound using VLC with current player volume
success = await self.play_sound(sound, current_volume)
# Play the sound using VLC (always at 100% VLC volume)
success = await self.play_sound(sound)
# Deduct credits based on success
await credit_service.deduct_credits(
@@ -433,4 +414,3 @@ def get_vlc_player_service(
if vlc_player_service is None:
vlc_player_service = VLCPlayerService(db_session_factory)
return vlc_player_service
return vlc_player_service