fix: Prevent stale audio playback after long pause and reorganize spectrum analyzer
- Detect pauses longer than 10 seconds across all player modes - Intercept 'playing' event to stop stale buffered audio - Force stream reconnect to get live audio after long pause - Reset and reinitialize spectrum analyzer during reconnect - Prevent 'Now Playing' updates while stream is paused - Move spectrum-analyzer.lisp to parenscript/ directory - Update all documentation dates to 2025-12-06 - Add comprehensive project statistics (408 commits, 9,300 LOC) - Add Phase 9 (Visual Audio Features) to project history Fixes issue where resuming playback after a long pause would play old buffered audio instead of the current live stream. The fix uses the 'playing' event to detect when stale audio starts and immediately stops it, then reconnects to get fresh stream data. All player modes updated: main player, front page, popout, and frame player.
This commit is contained in:
parent
6e8260172f
commit
7c7b2c921e
|
|
@ -41,7 +41,8 @@
|
||||||
(:file "conditions")
|
(:file "conditions")
|
||||||
(:file "database")
|
(:file "database")
|
||||||
(:file "template-utils")
|
(:file "template-utils")
|
||||||
(:file "spectrum-analyzer")
|
(:module :parenscript
|
||||||
|
:components ((:file "spectrum-analyzer")))
|
||||||
(:file "stream-media")
|
(:file "stream-media")
|
||||||
(:file "user-management")
|
(:file "user-management")
|
||||||
(:file "playlist-management")
|
(:file "playlist-management")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - API Endpoints Reference
|
#+TITLE: Asteroid Radio - API Endpoints Reference
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - API Reference
|
#+TITLE: Asteroid Radio - API Reference
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Current Interfaces
|
* Current Interfaces
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - Development Guide
|
#+TITLE: Asteroid Radio - Development Guide
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Development Setup
|
* Development Setup
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - Docker Streaming Setup
|
#+TITLE: Asteroid Radio - Docker Streaming Setup
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Docker Streaming Overview
|
* Docker Streaming Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - Installation Guide
|
#+TITLE: Asteroid Radio - Installation Guide
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Installation Overview
|
* Installation Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Playlist System - Complete (MVP)
|
#+TITLE: Playlist System - Complete (MVP)
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: PostgreSQL Setup for Asteroid Radio
|
#+TITLE: PostgreSQL Setup for Asteroid Radio
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - Project Development History
|
#+TITLE: Asteroid Radio - Project Development History
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
#+DESCRIPTION: Comprehensive history of the Asteroid Radio project from inception to present
|
#+DESCRIPTION: Comprehensive history of the Asteroid Radio project from inception to present
|
||||||
|
|
||||||
* Project Overview
|
* Project Overview
|
||||||
|
|
@ -11,7 +11,8 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea
|
||||||
- *Backend*: Common Lisp (SBCL), Radiance web framework
|
- *Backend*: Common Lisp (SBCL), Radiance web framework
|
||||||
- *Streaming*: Icecast2, Liquidsoap
|
- *Streaming*: Icecast2, Liquidsoap
|
||||||
- *Database*: PostgreSQL (configured, ready for migration)
|
- *Database*: PostgreSQL (configured, ready for migration)
|
||||||
- *Frontend*: HTML5, JavaScript, CLIP templating, LASS (CSS in Lisp)
|
- *Frontend*: HTML5, JavaScript, Parenscript, CLIP templating, LASS (CSS in Lisp)
|
||||||
|
- *Audio Visualization*: Web Audio API, Canvas
|
||||||
- *Infrastructure*: Docker, Docker Compose
|
- *Infrastructure*: Docker, Docker Compose
|
||||||
|
|
||||||
* Project Timeline
|
* Project Timeline
|
||||||
|
|
@ -231,19 +232,43 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea
|
||||||
- Synchronized with upstream/main
|
- Synchronized with upstream/main
|
||||||
- Prepared comprehensive documentation PR
|
- Prepared comprehensive documentation PR
|
||||||
|
|
||||||
|
** Phase 9: Visual Audio Features (December 2025)
|
||||||
|
|
||||||
|
*** 2025-12-06: Real-Time Spectrum Analyzer
|
||||||
|
- *Lead*: Brian O'Reilly (Fade), Glenn Thompson
|
||||||
|
- Implemented spectrum analyzer using Parenscript
|
||||||
|
- Web Audio API integration for real-time visualization
|
||||||
|
- Dynamic JavaScript generation via API endpoint
|
||||||
|
- Canvas-based frequency display
|
||||||
|
- Works across all player modes (inline, pop-out, frameset)
|
||||||
|
- Lisp-to-JavaScript compilation for maintainability
|
||||||
|
|
||||||
* Development Statistics
|
* Development Statistics
|
||||||
|
|
||||||
** Contributors (by commit count)
|
** Contributors (by commit count)
|
||||||
1. Glenn Thompson (glenneth/Glenneth) - 135+ commits
|
1. Glenn Thompson (glenneth/Glenneth) - 236 commits
|
||||||
2. Brian O'Reilly (Fade) - 55+ commits
|
2. Brian O'Reilly (Fade) - 109 commits
|
||||||
3. Luis Pereira (easilok) - 23+ commits
|
3. Luis Pereira (easilok) - 63 commits
|
||||||
|
|
||||||
** Total Commits: 213+ commits
|
** Total Commits: 408 commits
|
||||||
|
|
||||||
|
** Code Statistics
|
||||||
|
- *Total Lines of Code*: ~9,300 lines
|
||||||
|
- *Common Lisp*: 2,753 lines (.lisp, .asd)
|
||||||
|
- *JavaScript*: 2,315 lines (.js)
|
||||||
|
- *Templates*: 1,505 lines (.ctml)
|
||||||
|
- *Other*: 2,720 lines (CSS, Shell, Python, etc.)
|
||||||
|
- *Source Files*: 50 files
|
||||||
|
|
||||||
|
** Release Information
|
||||||
|
- *Current Version*: Development (pre-1.0)
|
||||||
|
- *Tagged Releases*: None (continuous development)
|
||||||
|
- *Deployment Status*: Production-ready
|
||||||
|
|
||||||
** Active Development Period
|
** Active Development Period
|
||||||
- Start: August 12, 2025
|
- Start: August 12, 2025
|
||||||
- Current: November 1, 2025
|
- Current: December 6, 2025
|
||||||
- Duration: ~2.75 months of active development
|
- Duration: ~4 months of active development
|
||||||
|
|
||||||
* Major Features Implemented
|
* Major Features Implemented
|
||||||
|
|
||||||
|
|
@ -266,6 +291,7 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea
|
||||||
- ✅ Multiple quality options (AAC 96k, MP3 128k, MP3 64k)
|
- ✅ Multiple quality options (AAC 96k, MP3 128k, MP3 64k)
|
||||||
- ✅ ReplayGain volume normalization
|
- ✅ ReplayGain volume normalization
|
||||||
- ✅ Live now-playing information
|
- ✅ Live now-playing information
|
||||||
|
- ✅ Real-time spectrum analyzer visualization
|
||||||
- ✅ Icecast integration
|
- ✅ Icecast integration
|
||||||
- ✅ Liquidsoap DJ controls
|
- ✅ Liquidsoap DJ controls
|
||||||
- ✅ Stream queue management
|
- ✅ Stream queue management
|
||||||
|
|
@ -325,7 +351,7 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea
|
||||||
- Parallel music scanning
|
- Parallel music scanning
|
||||||
- Client-side caching
|
- Client-side caching
|
||||||
|
|
||||||
* Current State (November 2025)
|
* Current State (December 2025)
|
||||||
|
|
||||||
** Production Ready Features
|
** Production Ready Features
|
||||||
- Full music streaming platform
|
- Full music streaming platform
|
||||||
|
|
@ -333,6 +359,7 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea
|
||||||
- Admin control panel
|
- Admin control panel
|
||||||
- DJ controls
|
- DJ controls
|
||||||
- Multiple player modes
|
- Multiple player modes
|
||||||
|
- Real-time spectrum analyzer
|
||||||
- Complete Docker deployment (streams + application)
|
- Complete Docker deployment (streams + application)
|
||||||
- Multi-environment support with dynamic URLs
|
- Multi-environment support with dynamic URLs
|
||||||
- Comprehensive documentation
|
- Comprehensive documentation
|
||||||
|
|
@ -392,9 +419,9 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea
|
||||||
|
|
||||||
* Conclusion
|
* Conclusion
|
||||||
|
|
||||||
Asteroid Radio has evolved from a simple concept into a full-featured internet radio platform in just 2.75 months of active development. The project demonstrates the power of Common Lisp for web development and the collaborative nature of open-source development.
|
Asteroid Radio has evolved from a simple concept into a full-featured internet radio platform in just 4 months of active development. The project demonstrates the power of Common Lisp for web development and the collaborative nature of open-source development.
|
||||||
|
|
||||||
With complete Docker deployment, comprehensive documentation, and a growing feature set, Asteroid Radio is ready for production use while continuing to evolve with regular improvements, bug fixes, and new features based on user needs and technical requirements.
|
With complete Docker deployment, real-time audio visualization, comprehensive documentation, and a growing feature set, Asteroid Radio is ready for production use while continuing to evolve with regular improvements, bug fixes, and new features based on user needs and technical requirements.
|
||||||
|
|
||||||
** Project Links
|
** Project Links
|
||||||
- Repository: https://github.com/fade/asteroid
|
- Repository: https://github.com/fade/asteroid
|
||||||
|
|
@ -403,4 +430,4 @@ With complete Docker deployment, comprehensive documentation, and a growing feat
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Last Updated: 2025-11-01*
|
*Last Updated: 2025-12-06*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - Project Overview
|
#+TITLE: Asteroid Radio - Project Overview
|
||||||
#+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade)
|
#+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade)
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* 🎯 Mission
|
* 🎯 Mission
|
||||||
|
|
||||||
|
|
@ -45,6 +45,8 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack
|
||||||
- **HTML5** with semantic templates
|
- **HTML5** with semantic templates
|
||||||
- **CSS3** with dark hacker theme
|
- **CSS3** with dark hacker theme
|
||||||
- **JavaScript** for interactive features
|
- **JavaScript** for interactive features
|
||||||
|
- **Parenscript** - Lisp-to-JavaScript compiler for spectrum analyzer
|
||||||
|
- **Web Audio API** - Real-time audio visualization
|
||||||
- **VT323 Font** for retro terminal aesthetic
|
- **VT323 Font** for retro terminal aesthetic
|
||||||
|
|
||||||
**Streaming:**
|
**Streaming:**
|
||||||
|
|
@ -81,6 +83,7 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack
|
||||||
- ✅ **Music Library** - Track management with pagination, search, and filtering
|
- ✅ **Music Library** - Track management with pagination, search, and filtering
|
||||||
- ✅ **User Playlists** - Create, manage, and play personal music collections
|
- ✅ **User Playlists** - Create, manage, and play personal music collections
|
||||||
- ✅ **Multiple Player Modes** - Inline, pop-out, and persistent frameset players
|
- ✅ **Multiple Player Modes** - Inline, pop-out, and persistent frameset players
|
||||||
|
- ✅ **Real-Time Spectrum Analyzer** - Visual audio frequency display using Web Audio API and Parenscript
|
||||||
- ✅ **Stream Queue Control** - Admin control over broadcast stream queue (M3U-based)
|
- ✅ **Stream Queue Control** - Admin control over broadcast stream queue (M3U-based)
|
||||||
- ✅ **REST API** - Comprehensive JSON API with 15+ endpoints
|
- ✅ **REST API** - Comprehensive JSON API with 15+ endpoints
|
||||||
- ✅ **Music Streaming** - Multiple quality formats (128k MP3, 96k AAC, 64k MP3)
|
- ✅ **Music Streaming** - Multiple quality formats (128k MP3, 96k AAC, 64k MP3)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ Pagination system for efficient browsing of large music libraries.
|
||||||
- **Music Library**: Track management with pagination, search, and filtering
|
- **Music Library**: Track management with pagination, search, and filtering
|
||||||
- **Playlists**: User playlists with creation and playback
|
- **Playlists**: User playlists with creation and playback
|
||||||
- **Multiple Player Modes**: Inline, pop-out, and persistent frameset players
|
- **Multiple Player Modes**: Inline, pop-out, and persistent frameset players
|
||||||
|
- **Real-Time Spectrum Analyzer**: Visual audio frequency display using Web Audio API
|
||||||
- **Stream Queue Control**: Admin control over broadcast stream queue
|
- **Stream Queue Control**: Admin control over broadcast stream queue
|
||||||
- **Docker Streaming Infrastructure**: Icecast2 + Liquidsoap containers
|
- **Docker Streaming Infrastructure**: Icecast2 + Liquidsoap containers
|
||||||
- **Three Quality Streams**: 128kbps MP3, 96kbps AAC, 64kbps MP3
|
- **Three Quality Streams**: 128kbps MP3, 96kbps AAC, 64kbps MP3
|
||||||
|
|
@ -147,5 +148,5 @@ For detailed technical information, see the **[[file:PROJECT-OVERVIEW.org][Proje
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Last Updated: 2025-10-26*
|
*Last Updated: 2025-12-06*
|
||||||
*Documentation Version: 3.0*
|
*Documentation Version: 3.1*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Stream Queue Control System
|
#+TITLE: Stream Queue Control System
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio Testing Guide
|
#+TITLE: Asteroid Radio Testing Guide
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Track Pagination System - Complete
|
#+TITLE: Track Pagination System - Complete
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: User Management System - Complete
|
#+TITLE: User Management System - Complete
|
||||||
#+AUTHOR: Asteroid Radio Development Team
|
#+AUTHOR: Asteroid Radio Development Team
|
||||||
#+DATE: 2025-10-26
|
#+DATE: 2025-12-06
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,8 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||||
if (audioElement) {
|
if (audioElement) {
|
||||||
// Track pause timestamp to detect long pauses and reconnect
|
// Track pause timestamp to detect long pauses and reconnect
|
||||||
let pauseTimestamp = null;
|
let pauseTimestamp = null;
|
||||||
|
let isReconnecting = false;
|
||||||
|
let needsReconnect = false;
|
||||||
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
||||||
|
|
||||||
audioElement.addEventListener('pause', function() {
|
audioElement.addEventListener('pause', function() {
|
||||||
|
|
@ -121,9 +123,24 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
audioElement.addEventListener('play', function() {
|
audioElement.addEventListener('play', function() {
|
||||||
if (pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
// Check if we need to reconnect after long pause
|
||||||
|
if (!isReconnecting && pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
||||||
|
needsReconnect = true;
|
||||||
|
console.log('Long pause detected, will reconnect when playing starts...');
|
||||||
|
}
|
||||||
|
pauseTimestamp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Intercept the playing event to stop stale audio
|
||||||
|
audioElement.addEventListener('playing', function() {
|
||||||
|
if (needsReconnect && !isReconnecting) {
|
||||||
|
isReconnecting = true;
|
||||||
|
needsReconnect = false;
|
||||||
console.log('Reconnecting stream after long pause to clear stale buffers...');
|
console.log('Reconnecting stream after long pause to clear stale buffers...');
|
||||||
|
|
||||||
|
// Stop the stale audio immediately
|
||||||
|
audioElement.pause();
|
||||||
|
|
||||||
// Reset spectrum analyzer before reconnect
|
// Reset spectrum analyzer before reconnect
|
||||||
if (typeof resetSpectrumAnalyzer === 'function') {
|
if (typeof resetSpectrumAnalyzer === 'function') {
|
||||||
resetSpectrumAnalyzer();
|
resetSpectrumAnalyzer();
|
||||||
|
|
@ -139,9 +156,10 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||||
initSpectrumAnalyzer();
|
initSpectrumAnalyzer();
|
||||||
console.log('Spectrum analyzer reinitialized after reconnect');
|
console.log('Spectrum analyzer reinitialized after reconnect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReconnecting = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
pauseTimestamp = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
audioElement.addEventListener('error', function(e) {
|
audioElement.addEventListener('error', function(e) {
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
// Track pause timestamp to detect long pauses and reconnect
|
// Track pause timestamp to detect long pauses and reconnect
|
||||||
let pauseTimestamp = null;
|
let pauseTimestamp = null;
|
||||||
|
let isReconnecting = false;
|
||||||
|
let needsReconnect = false;
|
||||||
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
||||||
|
|
||||||
liveAudio.addEventListener('pause', function() {
|
liveAudio.addEventListener('pause', function() {
|
||||||
|
|
@ -37,9 +39,24 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
liveAudio.addEventListener('play', function() {
|
liveAudio.addEventListener('play', function() {
|
||||||
if (pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
// Check if we need to reconnect after long pause
|
||||||
|
if (!isReconnecting && pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
||||||
|
needsReconnect = true;
|
||||||
|
console.log('Long pause detected, will reconnect when playing starts...');
|
||||||
|
}
|
||||||
|
pauseTimestamp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Intercept the playing event to stop stale audio
|
||||||
|
liveAudio.addEventListener('playing', function() {
|
||||||
|
if (needsReconnect && !isReconnecting) {
|
||||||
|
isReconnecting = true;
|
||||||
|
needsReconnect = false;
|
||||||
console.log('Reconnecting live stream after long pause to clear stale buffers...');
|
console.log('Reconnecting live stream after long pause to clear stale buffers...');
|
||||||
|
|
||||||
|
// Stop the stale audio immediately
|
||||||
|
liveAudio.pause();
|
||||||
|
|
||||||
// Reset spectrum analyzer before reconnect
|
// Reset spectrum analyzer before reconnect
|
||||||
if (typeof resetSpectrumAnalyzer === 'function') {
|
if (typeof resetSpectrumAnalyzer === 'function') {
|
||||||
resetSpectrumAnalyzer();
|
resetSpectrumAnalyzer();
|
||||||
|
|
@ -55,9 +72,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
initSpectrumAnalyzer();
|
initSpectrumAnalyzer();
|
||||||
console.log('Spectrum analyzer reinitialized after reconnect');
|
console.log('Spectrum analyzer reinitialized after reconnect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReconnecting = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
pauseTimestamp = null;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Restore user quality preference
|
// Restore user quality preference
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@
|
||||||
|
|
||||||
// Track pause timestamp to detect long pauses and reconnect
|
// Track pause timestamp to detect long pauses and reconnect
|
||||||
let pauseTimestamp = null;
|
let pauseTimestamp = null;
|
||||||
|
let isReconnecting = false;
|
||||||
|
let needsReconnect = false;
|
||||||
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
||||||
|
|
||||||
audioElement.addEventListener('pause', function() {
|
audioElement.addEventListener('pause', function() {
|
||||||
|
|
@ -56,23 +58,25 @@
|
||||||
console.log('Frame player stream paused at:', pauseTimestamp);
|
console.log('Frame player stream paused at:', pauseTimestamp);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add event listeners for debugging
|
|
||||||
audioElement.addEventListener('waiting', function() {
|
|
||||||
console.log('Audio buffering...');
|
|
||||||
});
|
|
||||||
|
|
||||||
audioElement.addEventListener('playing', function() {
|
|
||||||
console.log('Audio playing');
|
|
||||||
});
|
|
||||||
|
|
||||||
audioElement.addEventListener('error', function(e) {
|
|
||||||
console.error('Audio error:', e);
|
|
||||||
});
|
|
||||||
|
|
||||||
audioElement.addEventListener('play', function() {
|
audioElement.addEventListener('play', function() {
|
||||||
if (pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
// Check if we need to reconnect after long pause
|
||||||
|
if (!isReconnecting && pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
||||||
|
needsReconnect = true;
|
||||||
|
console.log('Long pause detected, will reconnect when playing starts...');
|
||||||
|
}
|
||||||
|
pauseTimestamp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Intercept the playing event to stop stale audio
|
||||||
|
audioElement.addEventListener('playing', function() {
|
||||||
|
if (needsReconnect && !isReconnecting) {
|
||||||
|
isReconnecting = true;
|
||||||
|
needsReconnect = false;
|
||||||
console.log('Reconnecting frame player stream after long pause to clear stale buffers...');
|
console.log('Reconnecting frame player stream after long pause to clear stale buffers...');
|
||||||
|
|
||||||
|
// Stop the stale audio immediately
|
||||||
|
audioElement.pause();
|
||||||
|
|
||||||
// Reset spectrum analyzer before reconnect
|
// Reset spectrum analyzer before reconnect
|
||||||
if (typeof resetSpectrumAnalyzer === 'function') {
|
if (typeof resetSpectrumAnalyzer === 'function') {
|
||||||
resetSpectrumAnalyzer();
|
resetSpectrumAnalyzer();
|
||||||
|
|
@ -88,9 +92,21 @@
|
||||||
initSpectrumAnalyzer();
|
initSpectrumAnalyzer();
|
||||||
console.log('Spectrum analyzer reinitialized after reconnect');
|
console.log('Spectrum analyzer reinitialized after reconnect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReconnecting = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
|
} else {
|
||||||
|
console.log('Audio playing');
|
||||||
}
|
}
|
||||||
pauseTimestamp = null;
|
});
|
||||||
|
|
||||||
|
// Add event listeners for debugging
|
||||||
|
audioElement.addEventListener('waiting', function() {
|
||||||
|
console.log('Audio buffering...');
|
||||||
|
});
|
||||||
|
|
||||||
|
audioElement.addEventListener('error', function(e) {
|
||||||
|
console.error('Audio error:', e);
|
||||||
});
|
});
|
||||||
|
|
||||||
const selector = document.getElementById('stream-quality');
|
const selector = document.getElementById('stream-quality');
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,8 @@
|
||||||
|
|
||||||
// Track pause timestamp to detect long pauses and reconnect
|
// Track pause timestamp to detect long pauses and reconnect
|
||||||
let pauseTimestamp = null;
|
let pauseTimestamp = null;
|
||||||
|
let isReconnecting = false;
|
||||||
|
let needsReconnect = false;
|
||||||
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
const PAUSE_RECONNECT_THRESHOLD = 10000; // 10 seconds
|
||||||
|
|
||||||
audioElement.addEventListener('pause', function() {
|
audioElement.addEventListener('pause', function() {
|
||||||
|
|
@ -144,9 +146,24 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
audioElement.addEventListener('play', function() {
|
audioElement.addEventListener('play', function() {
|
||||||
if (pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
// Check if we need to reconnect after long pause
|
||||||
|
if (!isReconnecting && pauseTimestamp && (Date.now() - pauseTimestamp) > PAUSE_RECONNECT_THRESHOLD) {
|
||||||
|
needsReconnect = true;
|
||||||
|
console.log('Long pause detected, will reconnect when playing starts...');
|
||||||
|
}
|
||||||
|
pauseTimestamp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Intercept the playing event to stop stale audio
|
||||||
|
audioElement.addEventListener('playing', function() {
|
||||||
|
if (needsReconnect && !isReconnecting) {
|
||||||
|
isReconnecting = true;
|
||||||
|
needsReconnect = false;
|
||||||
console.log('Reconnecting popout stream after long pause to clear stale buffers...');
|
console.log('Reconnecting popout stream after long pause to clear stale buffers...');
|
||||||
|
|
||||||
|
// Stop the stale audio immediately
|
||||||
|
audioElement.pause();
|
||||||
|
|
||||||
// Reset spectrum analyzer before reconnect
|
// Reset spectrum analyzer before reconnect
|
||||||
if (typeof resetSpectrumAnalyzer === 'function') {
|
if (typeof resetSpectrumAnalyzer === 'function') {
|
||||||
resetSpectrumAnalyzer();
|
resetSpectrumAnalyzer();
|
||||||
|
|
@ -162,9 +179,10 @@
|
||||||
initSpectrumAnalyzer();
|
initSpectrumAnalyzer();
|
||||||
console.log('Spectrum analyzer reinitialized after reconnect');
|
console.log('Spectrum analyzer reinitialized after reconnect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReconnecting = false;
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
pauseTimestamp = null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
audioElement.addEventListener('error', function(e) {
|
audioElement.addEventListener('error', function(e) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue