forked from computertech/techdj
beep
This commit is contained in:
Binary file not shown.
90
script.js
90
script.js
@@ -2180,20 +2180,49 @@ function initListenerMode() {
|
||||
|
||||
// AudioContext will be created when user enables audio to avoid suspension
|
||||
|
||||
// Create or reuse audio element to handle the MediaSource
|
||||
// ALWAYS create a fresh audio element to avoid MediaSource/MediaElementSource conflicts
|
||||
// This is critical for page refreshes - you can only create MediaElementSource once per element
|
||||
let audio;
|
||||
if (window.listenerAudio) {
|
||||
// Reuse existing audio element from previous initialization
|
||||
audio = window.listenerAudio;
|
||||
console.log('♻️ Reusing existing audio element');
|
||||
|
||||
// Clean up old MediaSource if it exists
|
||||
if (audio.src) {
|
||||
URL.revokeObjectURL(audio.src);
|
||||
audio.removeAttribute('src');
|
||||
audio.load(); // Reset the element
|
||||
// Clean up old audio element if it exists
|
||||
if (window.listenerAudio) {
|
||||
console.log('🧹 Cleaning up old audio element and AudioContext nodes');
|
||||
try {
|
||||
window.listenerAudio.pause();
|
||||
if (window.listenerAudio.src) {
|
||||
URL.revokeObjectURL(window.listenerAudio.src);
|
||||
}
|
||||
} else {
|
||||
window.listenerAudio.removeAttribute('src');
|
||||
window.listenerAudio.remove(); // Remove from DOM
|
||||
} catch (e) {
|
||||
console.warn('Error cleaning up old audio:', e);
|
||||
}
|
||||
|
||||
// Reset all AudioContext-related nodes
|
||||
if (listenerMediaElementSourceNode) {
|
||||
try {
|
||||
listenerMediaElementSourceNode.disconnect();
|
||||
} catch (e) { }
|
||||
listenerMediaElementSourceNode = null;
|
||||
}
|
||||
if (listenerAnalyserNode) {
|
||||
try {
|
||||
listenerAnalyserNode.disconnect();
|
||||
} catch (e) { }
|
||||
listenerAnalyserNode = null;
|
||||
}
|
||||
if (listenerGainNode) {
|
||||
try {
|
||||
listenerGainNode.disconnect();
|
||||
} catch (e) { }
|
||||
listenerGainNode = null;
|
||||
}
|
||||
|
||||
window.listenerAudio = null;
|
||||
window.listenerMediaSource = null;
|
||||
window.listenerAudioEnabled = false;
|
||||
}
|
||||
|
||||
// Create a new hidden media element.
|
||||
// Note: MSE (MediaSource) support is often more reliable on <video> than <audio>.
|
||||
audio = document.createElement('video');
|
||||
@@ -2204,10 +2233,7 @@ function initListenerMode() {
|
||||
audio.setAttribute('playsinline', '');
|
||||
audio.style.display = 'none';
|
||||
document.body.appendChild(audio);
|
||||
console.log('🆕 Created new media element (video) for listener');
|
||||
|
||||
// AudioContext will be created later on user interaction
|
||||
}
|
||||
console.log('🆕 Created fresh media element (video) for listener');
|
||||
|
||||
// Initialize MediaSource for streaming binary chunks
|
||||
const mediaSource = new MediaSource();
|
||||
@@ -2470,8 +2496,38 @@ async function enableListenerAudio() {
|
||||
return window.listenerAudio.buffered && window.listenerAudio.buffered.length > 0;
|
||||
};
|
||||
|
||||
// Attempt playback IMMEDIATELY to capture user gesture
|
||||
// We do this before waiting for data so we don't lose the "user interaction" token
|
||||
// CRITICAL: Wait for buffered data before calling play()
|
||||
// This prevents NotSupportedError when buffer is empty
|
||||
if (!hasBufferedData()) {
|
||||
console.log('⏳ Waiting for audio data to buffer before playback...');
|
||||
if (audioText) audioText.textContent = 'BUFFERING...';
|
||||
|
||||
// Wait for data with timeout (max 5 seconds)
|
||||
const waitForData = new Promise((resolve, reject) => {
|
||||
const timeout = setTimeout(() => {
|
||||
clearInterval(checkInterval);
|
||||
reject(new Error('Timeout waiting for audio data'));
|
||||
}, 5000);
|
||||
|
||||
const checkInterval = setInterval(() => {
|
||||
if (hasBufferedData()) {
|
||||
clearInterval(checkInterval);
|
||||
clearTimeout(timeout);
|
||||
console.log('✅ Audio data buffered, ready to play');
|
||||
resolve();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
try {
|
||||
await waitForData;
|
||||
} catch (e) {
|
||||
console.warn('⚠️ Timeout waiting for buffer data:', e.message);
|
||||
}
|
||||
} else {
|
||||
console.log('✅ Audio already has buffered data');
|
||||
}
|
||||
|
||||
console.log('▶️ Attempting to play audio...');
|
||||
const playPromise = window.listenerAudio.play();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user