fix start restart bugs
This commit is contained in:
@@ -336,10 +336,7 @@ class Streamer():
|
||||
self.is_streaming = False
|
||||
if self.task is not None:
|
||||
self.task.cancel()
|
||||
try:
|
||||
await self.task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
self.task = None
|
||||
|
||||
# Close audio inputs (await to ensure ALSA devices are released)
|
||||
|
||||
@@ -51,7 +51,7 @@ if audio_mode in ["Webapp", "USB"]:
|
||||
# Input device selection for USB mode
|
||||
if audio_mode == "USB":
|
||||
try:
|
||||
resp = requests.get(f"{BACKEND_URL}/audio_inputs", timeout=1)
|
||||
resp = requests.get(f"{BACKEND_URL}/audio_inputs")
|
||||
if resp.status_code == 200:
|
||||
input_options = [f"{d['id']}:{d['name']}" for d in resp.json().get('inputs', [])]
|
||||
else:
|
||||
@@ -71,6 +71,10 @@ if audio_mode in ["Webapp", "USB"]:
|
||||
selected_option = st.selectbox("Input Device", input_options, index=input_options.index(default_input))
|
||||
with col2:
|
||||
if st.button("Refresh"):
|
||||
try:
|
||||
requests.post(f"{BACKEND_URL}/refresh_audio_inputs", timeout=3)
|
||||
except Exception as e:
|
||||
st.error(f"Failed to refresh devices: {e}")
|
||||
st.rerun()
|
||||
# We send only the numeric/card identifier (before :) or 'default'
|
||||
input_device = selected_option.split(":", 1)[0] if ":" in selected_option else selected_option
|
||||
|
||||
@@ -15,12 +15,13 @@ from aiortc import RTCPeerConnection, RTCSessionDescription, MediaStreamTrack
|
||||
import av
|
||||
import av.audio.layout
|
||||
import sounddevice as sd # type: ignore
|
||||
from typing import Set
|
||||
from typing import Set, List, Dict, Any
|
||||
import traceback
|
||||
|
||||
|
||||
PTIME = 40 # TODO: seems to have no effect at all
|
||||
pcs: Set[RTCPeerConnection] = set() # keep refs so they don’t GC early
|
||||
AUDIO_INPUT_DEVICES_CACHE: List[Dict[str, Any]] = []
|
||||
|
||||
class Offer(BaseModel):
|
||||
sdp: str
|
||||
@@ -169,6 +170,7 @@ async def stop_audio():
|
||||
|
||||
return {"status": "stopped", "was_running": running}
|
||||
except Exception as e:
|
||||
log.error("Exception in /stop_audio: %s", traceback.format_exc())
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@@ -182,11 +184,12 @@ async def get_status():
|
||||
status.update(load_stream_settings())
|
||||
return status
|
||||
|
||||
@app.get("/audio_inputs")
|
||||
async def list_audio_inputs():
|
||||
"""Return available hardware audio input devices for USB mode."""
|
||||
|
||||
async def scan_audio_devices():
|
||||
"""Scans for available audio devices and updates the cache."""
|
||||
global AUDIO_INPUT_DEVICES_CACHE
|
||||
log.info("Scanning for audio input devices...")
|
||||
try:
|
||||
# Re-scan devices on Linux, see https://github.com/spatialaudio/python-sounddevice/issues/16
|
||||
if sys.platform == 'linux':
|
||||
log.info("Re-initializing sounddevice to scan for new devices")
|
||||
sd._terminate()
|
||||
@@ -197,12 +200,30 @@ async def list_audio_inputs():
|
||||
for idx, d in enumerate(devs)
|
||||
if d.get("max_input_channels", 0) > 0 and ("(hw:" in d["name"].lower() or "usb" in d["name"].lower())
|
||||
]
|
||||
log.info('Found %d audio input devices:', len(inputs))
|
||||
for i in inputs:
|
||||
log.info(' %s', i)
|
||||
return {"inputs": inputs}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
log.info('Found %d audio input devices: %s', len(inputs), inputs)
|
||||
AUDIO_INPUT_DEVICES_CACHE = inputs
|
||||
except Exception:
|
||||
log.error("Exception while scanning audio devices:", exc_info=True)
|
||||
# Do not clear cache on error, keep the last known good list
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup_event():
|
||||
"""Pre-scans audio devices on startup."""
|
||||
await scan_audio_devices()
|
||||
|
||||
|
||||
@app.get("/audio_inputs")
|
||||
async def list_audio_inputs():
|
||||
"""Return available hardware audio input devices from cache."""
|
||||
return {"inputs": AUDIO_INPUT_DEVICES_CACHE}
|
||||
|
||||
|
||||
@app.post("/refresh_audio_inputs")
|
||||
async def refresh_audio_inputs():
|
||||
"""Triggers a re-scan of audio devices."""
|
||||
await scan_audio_devices()
|
||||
return {"status": "ok", "inputs": AUDIO_INPUT_DEVICES_CACHE}
|
||||
|
||||
|
||||
@app.post("/offer")
|
||||
|
||||
Reference in New Issue
Block a user