fix demo autostart
This commit is contained in:
@@ -263,6 +263,7 @@ async def init_radio(transport: str, conf: auracast_config.AuracastConfigGroup,
|
||||
'demo_total_streams': demo_count,
|
||||
'demo_stream_type': demo_type,
|
||||
'is_streaming': auto_started,
|
||||
'demo_sources': [str(b.audio_source) for b in conf.bigs if isinstance(b.audio_source, str) and b.audio_source.startswith('file:')],
|
||||
}
|
||||
return mc, persisted
|
||||
except HTTPException:
|
||||
@@ -332,6 +333,8 @@ async def _autostart_from_settings():
|
||||
settings1 = load_stream_settings() or {}
|
||||
settings2 = load_stream_settings2() or {}
|
||||
|
||||
log.info("[AUTOSTART] Starting autostart check: primary_ts=%s secondary_ts=%s", settings1.get('timestamp'), settings2.get('timestamp'))
|
||||
|
||||
async def do_primary():
|
||||
global multicaster1, global_config_group
|
||||
settings = settings1
|
||||
@@ -350,14 +353,96 @@ async def _autostart_from_settings():
|
||||
original_ts = settings.get('timestamp')
|
||||
previously_streaming = bool(settings.get('is_streaming'))
|
||||
|
||||
if not previously_streaming or not input_device_name or rate is None or octets is None:
|
||||
log.info(
|
||||
"[AUTOSTART][PRIMARY] loaded settings: previously_streaming=%s audio_mode=%s rate=%s octets=%s pres_delay=%s rtn=%s immediate_rendering=%s assisted_listening_stream=%s demo_sources=%s",
|
||||
previously_streaming,
|
||||
audio_mode,
|
||||
rate,
|
||||
octets,
|
||||
pres_delay,
|
||||
saved_rtn,
|
||||
immediate_rendering,
|
||||
assisted_listening_stream,
|
||||
(settings.get('demo_sources') or []),
|
||||
)
|
||||
|
||||
if not previously_streaming:
|
||||
log.info("[AUTOSTART][PRIMARY] Skipping autostart: is_streaming flag was False in persisted settings")
|
||||
return
|
||||
if audio_mode == 'Demo':
|
||||
demo_sources = settings.get('demo_sources') or []
|
||||
if not demo_sources or rate is None or octets is None:
|
||||
log.warning(
|
||||
"[AUTOSTART][PRIMARY] Demo autostart aborted: demo_sources_present=%s rate=%s octets=%s",
|
||||
bool(demo_sources),
|
||||
rate,
|
||||
octets,
|
||||
)
|
||||
return
|
||||
bigs = []
|
||||
for i, src in enumerate(demo_sources):
|
||||
name = channel_names[i] if i < len(channel_names) else f"Broadcast{i}"
|
||||
pinfo = program_info[i] if isinstance(program_info, list) and i < len(program_info) else (program_info[0] if isinstance(program_info, list) and program_info else program_info)
|
||||
lang = languages[i] if i < len(languages) else (languages[0] if languages else "deu")
|
||||
bigs.append(
|
||||
auracast_config.AuracastBigConfig(
|
||||
code=stream_password,
|
||||
name=name,
|
||||
program_info=pinfo,
|
||||
language=lang,
|
||||
audio_source=src,
|
||||
iso_que_len=1,
|
||||
sampling_frequency=rate,
|
||||
octets_per_frame=octets,
|
||||
)
|
||||
)
|
||||
log.info(
|
||||
"[AUTOSTART][PRIMARY] Building demo config for %d streams, rate=%s, octets=%s",
|
||||
len(bigs),
|
||||
rate,
|
||||
octets,
|
||||
)
|
||||
|
||||
conf = auracast_config.AuracastConfigGroup(
|
||||
auracast_sampling_rate_hz=rate,
|
||||
octets_per_frame=octets,
|
||||
transport=TRANSPORT1,
|
||||
immediate_rendering=immediate_rendering,
|
||||
assisted_listening_stream=assisted_listening_stream,
|
||||
presentation_delay_us=pres_delay if pres_delay is not None else 40000,
|
||||
bigs=bigs,
|
||||
)
|
||||
conf.qos_config = auracast_config.AuracastQoSConfig(
|
||||
iso_int_multiple_10ms=1,
|
||||
number_of_retransmissions=int(saved_rtn) if saved_rtn is not None else 1,
|
||||
max_transport_latency_ms=(int(saved_rtn) * 10 + 3) if saved_rtn is not None else 13,
|
||||
)
|
||||
log.info("[AUTOSTART][PRIMARY] Scheduling demo init_radio in 2s")
|
||||
await asyncio.sleep(2)
|
||||
async with _stream_lock:
|
||||
log.info("[AUTOSTART][PRIMARY] Calling init_radio for demo autostart")
|
||||
mc, persisted = await init_radio(TRANSPORT1, conf, multicaster1)
|
||||
multicaster1 = mc
|
||||
global_config_group = conf
|
||||
save_settings(persisted, secondary=False)
|
||||
log.info("[AUTOSTART][PRIMARY] Demo autostart completed; settings persisted with is_streaming=%s", persisted.get('is_streaming'))
|
||||
return
|
||||
if not input_device_name or rate is None or octets is None:
|
||||
log.info(
|
||||
"[AUTOSTART][PRIMARY] Skipping device-based autostart: input_device=%s rate=%s octets=%s",
|
||||
input_device_name,
|
||||
rate,
|
||||
octets,
|
||||
)
|
||||
return
|
||||
current = await _status_primary()
|
||||
if current.get('is_streaming'):
|
||||
log.info("[AUTOSTART][PRIMARY] Skipping device-based autostart: stream already running")
|
||||
return
|
||||
while True:
|
||||
current = await _status_primary()
|
||||
if current.get('is_streaming'):
|
||||
log.info("[AUTOSTART][PRIMARY] Aborting wait loop: stream started externally")
|
||||
return
|
||||
current_settings = load_stream_settings() or {}
|
||||
if current_settings.get('timestamp') != original_ts:
|
||||
@@ -365,11 +450,13 @@ async def _autostart_from_settings():
|
||||
current_settings.get('input_device') != input_device_name or
|
||||
current_settings.get('audio_mode') != audio_mode
|
||||
):
|
||||
log.info("[AUTOSTART][PRIMARY] Aborting wait loop: settings changed (audio_mode/input_device)")
|
||||
return
|
||||
usb = [d for _, d in get_alsa_usb_inputs()]
|
||||
net = [d for _, d in get_network_pw_inputs()]
|
||||
names = {d.get('name') for d in usb} | {d.get('name') for d in net}
|
||||
if input_device_name in names:
|
||||
log.info("[AUTOSTART][PRIMARY] Device '%s' detected, starting autostart", input_device_name)
|
||||
bigs = [
|
||||
auracast_config.AuracastBigConfig(
|
||||
code=stream_password,
|
||||
@@ -396,12 +483,15 @@ async def _autostart_from_settings():
|
||||
number_of_retransmissions=int(saved_rtn),
|
||||
max_transport_latency_ms=int(saved_rtn) * 10 + 3,
|
||||
)
|
||||
log.info("[AUTOSTART][PRIMARY] Scheduling device init_radio in 2s")
|
||||
await asyncio.sleep(2)
|
||||
async with _stream_lock:
|
||||
log.info("[AUTOSTART][PRIMARY] Calling init_radio for device autostart")
|
||||
mc, persisted = await init_radio(TRANSPORT1, conf, multicaster1)
|
||||
multicaster1 = mc
|
||||
global_config_group = conf
|
||||
save_settings(persisted, secondary=False)
|
||||
log.info("[AUTOSTART][PRIMARY] Device autostart completed; settings persisted with is_streaming=%s", persisted.get('is_streaming'))
|
||||
return
|
||||
await asyncio.sleep(2)
|
||||
|
||||
@@ -422,12 +512,83 @@ async def _autostart_from_settings():
|
||||
stream_password = settings.get('stream_password')
|
||||
original_ts = settings.get('timestamp')
|
||||
previously_streaming = bool(settings.get('is_streaming'))
|
||||
|
||||
if not previously_streaming or not input_device_name or rate is None or octets is None:
|
||||
log.info(
|
||||
"[AUTOSTART][SECONDARY] loaded settings: previously_streaming=%s audio_mode=%s rate=%s octets=%s pres_delay=%s rtn=%s immediate_rendering=%s assisted_listening_stream=%s demo_sources=%s",
|
||||
previously_streaming,
|
||||
audio_mode,
|
||||
rate,
|
||||
octets,
|
||||
pres_delay,
|
||||
saved_rtn,
|
||||
immediate_rendering,
|
||||
assisted_listening_stream,
|
||||
(settings.get('demo_sources') or []),
|
||||
)
|
||||
if not previously_streaming:
|
||||
log.info("[AUTOSTART][SECONDARY] Skipping autostart: is_streaming flag was False in persisted settings")
|
||||
return
|
||||
if audio_mode == 'Demo':
|
||||
demo_sources = settings.get('demo_sources') or []
|
||||
if not demo_sources or rate is None or octets is None:
|
||||
log.warning(
|
||||
"[AUTOSTART][SECONDARY] Demo autostart aborted: demo_sources_present=%s rate=%s octets=%s",
|
||||
bool(demo_sources),
|
||||
rate,
|
||||
octets,
|
||||
)
|
||||
return
|
||||
bigs = []
|
||||
for i, src in enumerate(demo_sources):
|
||||
name = channel_names[i] if i < len(channel_names) else f"Broadcast{i}"
|
||||
pinfo = program_info[i] if isinstance(program_info, list) and i < len(program_info) else (program_info[0] if isinstance(program_info, list) and program_info else program_info)
|
||||
lang = languages[i] if i < len(languages) else (languages[0] if languages else "deu")
|
||||
bigs.append(
|
||||
auracast_config.AuracastBigConfig(
|
||||
code=stream_password,
|
||||
name=name,
|
||||
program_info=pinfo,
|
||||
language=lang,
|
||||
audio_source=src,
|
||||
iso_que_len=1,
|
||||
sampling_frequency=rate,
|
||||
octets_per_frame=octets,
|
||||
)
|
||||
)
|
||||
conf = auracast_config.AuracastConfigGroup(
|
||||
auracast_sampling_rate_hz=rate,
|
||||
octets_per_frame=octets,
|
||||
transport=TRANSPORT2,
|
||||
immediate_rendering=immediate_rendering,
|
||||
assisted_listening_stream=assisted_listening_stream,
|
||||
presentation_delay_us=pres_delay if pres_delay is not None else 40000,
|
||||
bigs=bigs,
|
||||
)
|
||||
conf.qos_config = auracast_config.AuracastQoSConfig(
|
||||
iso_int_multiple_10ms=1,
|
||||
number_of_retransmissions=int(saved_rtn) if saved_rtn is not None else 1,
|
||||
max_transport_latency_ms=(int(saved_rtn) * 10 + 3) if saved_rtn is not None else 13,
|
||||
)
|
||||
log.info("[AUTOSTART][SECONDARY] Scheduling demo init_radio in 2s")
|
||||
await asyncio.sleep(2)
|
||||
async with _stream_lock:
|
||||
log.info("[AUTOSTART][SECONDARY] Calling init_radio for demo autostart")
|
||||
mc, persisted = await init_radio(TRANSPORT2, conf, multicaster2)
|
||||
multicaster2 = mc
|
||||
save_settings(persisted, secondary=True)
|
||||
log.info("[AUTOSTART][SECONDARY] Demo autostart completed; settings persisted with is_streaming=%s", persisted.get('is_streaming'))
|
||||
return
|
||||
if not input_device_name or rate is None or octets is None:
|
||||
log.info(
|
||||
"[AUTOSTART][SECONDARY] Skipping device-based autostart: input_device=%s rate=%s octets=%s",
|
||||
input_device_name,
|
||||
rate,
|
||||
octets,
|
||||
)
|
||||
return
|
||||
if multicaster2 is not None:
|
||||
try:
|
||||
if multicaster2.get_status().get('is_streaming'):
|
||||
log.info("[AUTOSTART][SECONDARY] Skipping device-based autostart: stream already running")
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
@@ -435,6 +596,7 @@ async def _autostart_from_settings():
|
||||
if multicaster2 is not None:
|
||||
try:
|
||||
if multicaster2.get_status().get('is_streaming'):
|
||||
log.info("[AUTOSTART][SECONDARY] Aborting wait loop: stream started externally")
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
@@ -475,11 +637,14 @@ async def _autostart_from_settings():
|
||||
number_of_retransmissions=int(saved_rtn),
|
||||
max_transport_latency_ms=int(saved_rtn) * 10 + 3,
|
||||
)
|
||||
log.info("[AUTOSTART][SECONDARY] Scheduling device init_radio in 2s")
|
||||
await asyncio.sleep(2)
|
||||
async with _stream_lock:
|
||||
log.info("[AUTOSTART][SECONDARY] Calling init_radio for device autostart")
|
||||
mc, persisted = await init_radio(TRANSPORT2, conf, multicaster2)
|
||||
multicaster2 = mc
|
||||
save_settings(persisted, secondary=True)
|
||||
log.info("[AUTOSTART][SECONDARY] Device autostart completed; settings persisted with is_streaming=%s", persisted.get('is_streaming'))
|
||||
return
|
||||
await asyncio.sleep(2)
|
||||
|
||||
@@ -489,11 +654,12 @@ async def _autostart_from_settings():
|
||||
@app.on_event("startup")
|
||||
async def _startup_autostart_event():
|
||||
# Spawn the autostart task without blocking startup
|
||||
log.info("Refreshing PipeWire device cache.")
|
||||
log.info("[STARTUP] Auracast multicast server startup: initializing settings cache, I2C, and PipeWire cache")
|
||||
# Hydrate settings cache once to avoid disk I/O during /status
|
||||
_init_settings_cache_from_disk()
|
||||
await _init_i2c_on_startup()
|
||||
refresh_pw_cache()
|
||||
log.info("[STARTUP] Scheduling autostart task")
|
||||
asyncio.create_task(_autostart_from_settings())
|
||||
|
||||
@app.get("/audio_inputs_pw_usb")
|
||||
|
||||
Reference in New Issue
Block a user