Fix buffering issue and app bugs: improve stream delivery, fixed reset UI desync, and EQ naming

This commit is contained in:
ComputerTech 2026-01-20 18:14:50 +00:00
parent 1776f631ef
commit 02f72e2372
3 changed files with 45 additions and 15 deletions

View File

@ -2242,7 +2242,17 @@ function initListenerMode() {
socket.on('broadcast_started', () => {
const nowPlayingEl = document.getElementById('listener-now-playing');
if (nowPlayingEl) nowPlayingEl.textContent = '🎵 Stream is live!';
// Reset MediaSource for fresh stream if needed
// Force a reload of the audio element to capture the fresh stream
if (window.listenerAudio) {
console.log('🔄 Broadcast started: Refreshing audio stream...');
const wasPlaying = !window.listenerAudio.paused;
window.listenerAudio.src = getMp3FallbackUrl();
window.listenerAudio.load();
if (wasPlaying || window.listenerAudioEnabled) {
window.listenerAudio.play().catch(e => console.warn('Auto-play after refresh blocked:', e));
}
}
});
socket.on('stream_status', (data) => {

View File

@ -55,7 +55,7 @@ _transcode_threads_started = False
_transcoder_bytes_out = 0
_transcoder_last_error = None
_last_audio_chunk_ts = 0.0
_mp3_preroll = collections.deque(maxlen=60) # Pre-roll (~2.5s at 192k)
_mp3_preroll = collections.deque(maxlen=256) # Pre-roll (~10s at 192k with 1KB chunks)
def _start_transcoder_if_needed(is_mp3_input=False):
@ -141,7 +141,8 @@ def _start_transcoder_if_needed(is_mp3_input=False):
break
continue
except Exception as e:
print(f"⚠️ Transcoder writer error: {e}")
if _ffmpeg_proc is not None:
print(f"⚠️ Transcoder writer error: {e}")
_transcoder_last_error = f'stdin write failed: {e}'
break
_transcode_threads_started = False
@ -153,8 +154,9 @@ def _start_transcoder_if_needed(is_mp3_input=False):
proc = _ffmpeg_proc
while proc and proc.poll() is None:
try:
# Use a larger read for efficiency
data = proc.stdout.read(4096)
# Smaller read for smoother delivery (1KB)
# This prevents buffering delays at lower bitrates
data = proc.stdout.read(1024)
if not data:
break
_transcoder_bytes_out += len(data)
@ -199,6 +201,17 @@ def _stop_transcoder():
if proc is None:
return
# Signal all listening clients to finish their stream
with _mp3_lock:
clients = list(_mp3_clients)
for q in clients:
try:
q.put_nowait(None)
except:
pass
_mp3_clients.clear()
try:
proc.terminate()
except Exception:

View File

@ -57,6 +57,7 @@ class AudioEngine:
'loop_active': False,
'repeat': False,
'queue': [],
'needs_next_track': False,
},
'B': {
'audio_data': None,
@ -75,6 +76,7 @@ class AudioEngine:
'loop_active': False,
'repeat': False,
'queue': [],
'needs_next_track': False,
}
}
@ -410,8 +412,8 @@ class BroadcastThread(QThread):
# Thread to read encoded chunks from stdout
def read_output():
# Smaller buffer for more frequent updates (4KB = ~0.15s @ 192k)
buffer_size = 4096
# Smaller buffer for more frequent updates (2KB = ~0.08s @ 192k)
buffer_size = 2048
while self.running:
try:
data = self.process.stdout.read(buffer_size)
@ -806,8 +808,9 @@ class DeckWidget(QWidget):
eq_widget = QWidget()
eq_layout = QHBoxLayout(eq_widget)
eq_layout.setSpacing(8)
self.eq_sliders = {}
for band in ['HI', 'MID', 'LO']:
for band in ['HIGH', 'MID', 'LOW']:
band_widget = QWidget()
band_layout = QVBoxLayout(band_widget)
band_layout.setSpacing(2)
@ -819,6 +822,7 @@ class DeckWidget(QWidget):
slider.setFixedHeight(80)
slider.setStyleSheet(self.get_slider_style())
slider.valueChanged.connect(lambda v, b=band.lower(): self.on_eq_change(b, v))
self.eq_sliders[band.lower()] = slider
label = QLabel(band)
label.setStyleSheet("color: #888; font-size: 9px;")
@ -1001,20 +1005,23 @@ class DeckWidget(QWidget):
def reset_deck(self):
"""Reset all deck controls to default values"""
# Setting values on sliders will trigger the valueChanged signal
# which will in turn update the audio engine.
# Reset volume to 80%
self.volume_slider.setValue(80)
# Reset speed to 100%
self.speed_slider.setValue(100)
# Reset EQ to 0 (just update the engine, sliders will update via signals)
self.audio_engine.set_eq(self.deck_id, 'high', 0)
self.audio_engine.set_eq(self.deck_id, 'mid', 0)
self.audio_engine.set_eq(self.deck_id, 'low', 0)
# Reset EQ sliders to 0
if hasattr(self, 'eq_sliders'):
for band, slider in self.eq_sliders.items():
slider.setValue(0)
# Reset filters
self.audio_engine.set_filter(self.deck_id, 'lowpass', 100)
self.audio_engine.set_filter(self.deck_id, 'highpass', 0)
# Reset filter sliders
self.lp_slider.setValue(100)
self.hp_slider.setValue(0)
print(f"🔄 Deck {self.deck_id} reset to defaults")