feat: persist and restore demo stream configuration

- Added persistence of demo stream type and count to maintain user preferences across sessions
- Enhanced demo stream selection to automatically restore previously selected configuration
- Added fallback logic to match saved sampling rate and stream count when exact demo type not found
- Updated secondary stream initialization to track total demo streams across primary/secondary configs
- Modified settings storage to include demo_stream_type and demo
This commit is contained in:
2025-11-03 16:00:09 +01:00
parent f91f177b9a
commit 230db3a96b
2 changed files with 48 additions and 2 deletions
+20 -2
View File
@@ -170,11 +170,29 @@ if audio_mode == "Demo":
"6 × 16kHz": {"quality": "Fair (16kHz)", "streams": 6},
}
demo_options = list(demo_stream_map.keys())
default_demo = demo_options[0]
default_index = 0
saved_type = saved_settings.get('demo_stream_type')
if isinstance(saved_type, str) and saved_type in demo_options:
default_index = demo_options.index(saved_type)
else:
saved_rate = saved_settings.get('auracast_sampling_rate_hz')
saved_total = saved_settings.get('demo_total_streams')
if saved_total is None and saved_settings.get('audio_mode') == 'Demo':
saved_total = len(saved_settings.get('channel_names') or [])
try:
if saved_rate and saved_total:
for i, label in enumerate(demo_options):
cfg = demo_stream_map[label]
rate_for_label = QUALITY_MAP[cfg['quality']]['rate']
if cfg['streams'] == int(saved_total) and int(saved_rate) == rate_for_label:
default_index = i
break
except Exception:
default_index = 0
demo_selected = st.selectbox(
"Demo Stream Type",
demo_options,
index=0,
index=default_index,
help="Select the demo stream configuration."
)
# Stream password and flags (same as USB/AES67)
+28
View File
@@ -219,6 +219,14 @@ class StreamerWorker: # TODO: is wraping in this Worker stricly nececcarry ?
auto_started = True
# Return proposed settings to persist on API side
demo_count = sum(1 for big in conf.bigs if isinstance(big.audio_source, str) and big.audio_source.startswith('file:'))
demo_rate = int(conf.auracast_sampling_rate_hz or 0)
demo_type = None
if demo_count > 0 and demo_rate > 0:
if demo_rate in (48000, 24000, 16000):
demo_type = f"{demo_count} × {demo_rate//1000}kHz"
else:
demo_type = f"{demo_count} × {demo_rate}Hz"
return {
'channel_names': [big.name for big in conf.bigs],
'languages': [big.language for big in conf.bigs],
@@ -233,6 +241,8 @@ class StreamerWorker: # TODO: is wraping in this Worker stricly nececcarry ?
'immediate_rendering': getattr(conf, 'immediate_rendering', False),
'assisted_listening_stream': getattr(conf, 'assisted_listening_stream', False),
'stream_password': (conf.bigs[0].code if conf.bigs and getattr(conf.bigs[0], 'code', None) else None),
'demo_total_streams': demo_count,
'demo_stream_type': demo_type,
'is_streaming': auto_started,
}
@@ -345,6 +355,24 @@ async def initialize2(conf: auracast_config.AuracastConfigGroup):
try:
log.info('Initializing multicaster2 with config:\n %s', conf.model_dump_json(indent=2))
await streamer.call(streamer._w_init_secondary, conf)
try:
is_demo = any(isinstance(big.audio_source, str) and big.audio_source.startswith('file:') for big in conf.bigs)
if is_demo:
settings = load_stream_settings() or {}
primary_count = int(settings.get('demo_total_streams') or len(settings.get('channel_names') or []))
secondary_count = len(conf.bigs or [])
total = primary_count + secondary_count
settings['demo_total_streams'] = total
demo_rate = int(conf.auracast_sampling_rate_hz or 0)
if demo_rate > 0:
if demo_rate in (48000, 24000, 16000):
settings['demo_stream_type'] = f"{total} × {demo_rate//1000}kHz"
else:
settings['demo_stream_type'] = f"{total} × {demo_rate}Hz"
settings['timestamp'] = datetime.utcnow().isoformat()
save_stream_settings(settings)
except Exception:
log.warning("Failed to persist demo_total_streams in /init2", exc_info=True)
except Exception as e:
log.error("Exception in /init2: %s", traceback.format_exc())
raise HTTPException(status_code=500, detail=str(e))