This commit is contained in:
2026-01-02 20:15:32 +00:00
parent 0fb7bc6f9e
commit 28e2994649
2 changed files with 62 additions and 41 deletions

View File

@@ -2085,7 +2085,7 @@ function initListenerMode() {
// Create a hidden audio element to handle the MediaSource
const audio = new Audio();
audio.autoplay = true;
audio.autoplay = false; // Don't autoplay - we use the Enable Audio button
audio.hidden = true;
document.body.appendChild(audio);
@@ -2118,9 +2118,24 @@ function initListenerMode() {
}
sourceBuffer.addEventListener('updateend', () => {
// Process next chunk in queue
if (audioQueue.length > 0 && !sourceBuffer.updating) {
sourceBuffer.appendBuffer(audioQueue.shift());
}
// Periodic cleanup of old buffer data to prevent memory bloat
// Keep the last 60 seconds of audio data
if (audio.buffered.length > 0 && !sourceBuffer.updating && mediaSource.readyState === 'open') {
const end = audio.buffered.end(audio.buffered.length - 1);
const start = audio.buffered.start(0);
if (end - start > 120) { // If buffer is > 2 mins
try {
sourceBuffer.remove(0, end - 60);
} catch (e) {
console.warn('Buffer cleanup skipped:', e.message);
}
}
}
});
} catch (e) {
console.error('❌ Failed to add SourceBuffer:', e);
@@ -2141,6 +2156,7 @@ function initListenerMode() {
// Store audio element and context for later activation
window.listenerAudio = audio;
window.listenerMediaSource = mediaSource;
window.listenerAudioEnabled = false; // Track if user has enabled audio
// Initialize socket and join
initSocket();
@@ -2166,16 +2182,6 @@ function initListenerMode() {
const next = audioQueue.shift();
sourceBuffer.appendBuffer(next);
// Periodic cleanup of old buffer data to prevent memory bloat
// Keep the last 60 seconds of audio data
if (audio.buffered.length > 0 && !sourceBuffer.updating) {
const end = audio.buffered.end(audio.buffered.length - 1);
const start = audio.buffered.start(0);
if (end - start > 120) { // If buffer is > 2 mins
sourceBuffer.remove(0, end - 60);
}
}
// Reset error counter on success
if (window.sourceBufferErrorCount) window.sourceBufferErrorCount = 0;
} catch (e) {
@@ -2197,9 +2203,9 @@ function initListenerMode() {
}
}
// UI Update
// UI Update (only if audio is already enabled, don't overwrite the enable prompt)
const now = Date.now();
if (now - lastStatusUpdate > 1000) {
if (now - lastStatusUpdate > 1000 && window.listenerAudioEnabled) {
const statusEl = document.getElementById('connection-status');
if (statusEl) {
statusEl.textContent = `🟢 Connected - ${chunksReceived} chunks (${audioQueue.length} buffered)`;
@@ -2230,11 +2236,15 @@ function initListenerMode() {
socket.on('connect', () => {
const statusEl = document.getElementById('connection-status');
if (statusEl) statusEl.textContent = '🟢 Connected';
// Only update if audio is enabled, otherwise keep the "Click Enable Audio" message
if (statusEl && window.listenerAudioEnabled) {
statusEl.textContent = '🟢 Connected';
}
});
socket.on('disconnect', () => {
const statusEl = document.getElementById('connection-status');
// Always show disconnect status as it's critical
if (statusEl) statusEl.textContent = '🔴 Disconnected';
});
}
@@ -2261,15 +2271,49 @@ async function enableListenerAudio() {
console.log('✅ Audio context resumed');
}
// 3. Kickstart the hidden audio element
// 3. Wait for buffered data before attempting playback
if (window.listenerAudio) {
// Unmute just in case
window.listenerAudio.muted = false;
window.listenerAudio.volume = settings.volume || 0.8;
// Check if we have buffered data
const hasBufferedData = () => {
return window.listenerAudio.buffered && window.listenerAudio.buffered.length > 0;
};
if (!hasBufferedData()) {
console.log('⏳ Waiting for audio data to buffer...');
if (audioText) audioText.textContent = 'WAITING FOR STREAM...';
// Wait up to 5 seconds for data to arrive
const waitForData = new Promise((resolve, reject) => {
let attempts = 0;
const maxAttempts = 50; // 5 seconds (50 * 100ms)
const checkInterval = setInterval(() => {
attempts++;
if (hasBufferedData()) {
clearInterval(checkInterval);
console.log('✅ Audio data buffered, ready to play');
resolve();
} else if (attempts >= maxAttempts) {
clearInterval(checkInterval);
reject(new Error('Timeout waiting for audio data'));
}
}, 100);
});
await waitForData;
}
// Attempt playback
await window.listenerAudio.play();
console.log('✅ Audio playback started successfully');
// Mark audio as enabled so status updates can now display
window.listenerAudioEnabled = true;
}
// 4. Hide the button and update status
@@ -2293,7 +2337,9 @@ async function enableListenerAudio() {
if (audioText) audioText.textContent = 'RETRY ENABLE';
if (stashedStatus) {
stashedStatus.textContent = '⚠️ Browser blocked audio. Please click again.';
stashedStatus.textContent = '⚠️ ' + (error.message === 'Timeout waiting for audio data'
? 'No stream data yet. Is the DJ broadcasting?'
: 'Browser blocked audio. Please click again.');
}
}
}