splinter-keep/tools/run_ambience.py
2026-06-30 20:03:53 +02:00

98 lines
2.5 KiB
Python

import os
import random
from run_utils import AMBIENCE_PATH, AMBIENCE_OPTIONS_PATH, AUDIO_DIR, parse_ambience_options
try:
import miniaudio
HAS_AUDIO = True
except ImportError:
HAS_AUDIO = False
class AmbiencePlayer:
def __init__(self):
self.current_ambience = 'silence'
self._last_mtime = 0
self._options = {}
self._device = None
self._stream = None
self._muted = False
self.load_options()
@property
def available(self):
return HAS_AUDIO
@property
def ambience_name(self):
return self.current_ambience
@property
def is_muted(self):
return self._muted
def toggle_mute(self):
self._muted = not self._muted
if self._muted:
self._stop()
else:
self._load_current()
def load_options(self):
self._options = parse_ambience_options()
def _stop(self):
if self._device:
try:
self._device.close()
except Exception:
pass
self._device = None
self._stream = None
def poll(self):
if not HAS_AUDIO:
return
try:
mtime = os.path.getmtime(AMBIENCE_PATH)
except OSError:
return
if mtime == self._last_mtime:
return
self._last_mtime = mtime
try:
name = AMBIENCE_PATH.read_text().strip().lower()
except OSError:
return
self.current_ambience = name
self._stop()
if not self._muted and name != 'silence' and name in self._options:
self._play_current()
def _switch_to(self, name):
if name == self.current_ambience:
return
self.current_ambience = name
self._stop()
if self._muted or name == 'silence' or name not in self._options:
return
self._play_current()
def _play_current(self):
tracks = self._options.get(self.current_ambience, [])
valid = [t for t in tracks if t.exists()]
if not valid:
return
track = random.choice(valid)
try:
self._stream = miniaudio.stream_file(str(track))
self._device = miniaudio.PlaybackDevice()
self._device.start(self._stream)
except Exception:
self.current_ambience = None
self._stop()
def _load_current(self):
if self.current_ambience and self.current_ambience != 'silence':
self._play_current()