Add debug logging for audio source handling and API initialization; improve error handling in AudioPlayer and AudioPlayerContext

This commit is contained in:
2025-08-01 18:17:09 +00:00
committed by GitHub
parent be2266bf3a
commit fd7690b725
2 changed files with 81 additions and 18 deletions

View File

@@ -248,8 +248,71 @@ export const AudioPlayer: React.FC = () => {
// Always clear current track time when changing tracks
localStorage.removeItem('navidrome-current-track-time');
console.log('🔄 Setting audio source:', currentTrack.url);
// Debug: Check if URL is valid
if (!currentTrack.url || currentTrack.url === 'undefined' || currentTrack.url === '') {
console.error('❌ Invalid audio URL:', currentTrack.url);
return;
}
// Debug: Log current audio element state
console.log('🔍 Audio element state before loading:', {
src: audioCurrent.src,
readyState: audioCurrent.readyState,
networkState: audioCurrent.networkState,
crossOrigin: audioCurrent.crossOrigin,
canPlayType_mp3: audioCurrent.canPlayType('audio/mpeg'),
canPlayType_mp4: audioCurrent.canPlayType('audio/mp4'),
canPlayType_webm: audioCurrent.canPlayType('audio/webm'),
canPlayType_ogg: audioCurrent.canPlayType('audio/ogg'),
canPlayType_flac: audioCurrent.canPlayType('audio/flac'),
canPlayType_wav: audioCurrent.canPlayType('audio/wav')
});
// Clear any previous error handlers
audioCurrent.onerror = null;
audioCurrent.onloadstart = null;
audioCurrent.oncanplay = null;
// Simple error handling
audioCurrent.onerror = (e) => {
const event = e as Event;
const error = event.target as HTMLAudioElement;
console.error('❌ Audio element error:', {
error: error.error,
networkState: error.networkState,
readyState: error.readyState,
src: error.src
});
};
audioCurrent.onloadstart = () => {
console.log('📥 Audio load started');
};
audioCurrent.oncanplay = () => {
console.log('✅ Audio can play');
};
// Set source without any CORS configuration
audioCurrent.removeAttribute('crossorigin');
audioCurrent.src = currentTrack.url;
// Force load and log state after setting source
audioCurrent.load();
// Log state after load
setTimeout(() => {
console.log('🔍 Audio element state after load:', {
src: audioCurrent.src,
readyState: audioCurrent.readyState,
networkState: audioCurrent.networkState,
error: audioCurrent.error,
duration: audioCurrent.duration
});
}, 100);
// For iOS, ensure audio element is properly loaded
if (isMobile) {
audioCurrent.load();
@@ -721,10 +784,7 @@ export const AudioPlayer: React.FC = () => {
<button
className="p-4 hover:bg-muted/50 rounded-full transition-all duration-200 active:scale-95 bg-primary/10 touch-manipulation"
onClick={togglePlayPause}
onTouchStart={(e) => {
// Prevent iOS double-tap zoom on the play button
e.preventDefault();
}}
style={{ touchAction: 'manipulation' }}
type="button"
data-testid="play-pause-button"
aria-label={isPlaying ? 'Pause' : 'Play'}
@@ -746,11 +806,8 @@ export const AudioPlayer: React.FC = () => {
{/* Single audio element - shared across all UI states */}
<audio
ref={audioRef}
hidden
playsInline
preload={isMobile ? "none" : "auto"}
controls={false}
crossOrigin="anonymous"
preload="metadata"
style={{ display: 'none' }}
/>
<audio ref={preloadAudioRef} hidden preload="metadata" />
@@ -814,11 +871,8 @@ export const AudioPlayer: React.FC = () => {
{/* Single audio element - shared across all UI states */}
<audio
ref={audioRef}
hidden
playsInline
preload={isMobile ? "none" : "auto"}
controls={false}
crossOrigin="anonymous"
preload="metadata"
style={{ display: 'none' }}
/>
<audio ref={preloadAudioRef} hidden preload="metadata" />
@@ -929,11 +983,8 @@ export const AudioPlayer: React.FC = () => {
{/* Single audio element - shared across all UI states with mobile support */}
<audio
ref={audioRef}
hidden
playsInline
preload={isMobile ? "none" : "auto"}
controls={false}
crossOrigin="anonymous"
preload="metadata"
style={{ display: 'none' }}
/>
<audio ref={preloadAudioRef} hidden preload="metadata" />

View File

@@ -53,7 +53,15 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
const [isLoading, setIsLoading] = useState(false);
const [shuffle, setShuffle] = useState(false);
const { toast } = useToast();
const api = useMemo(() => getNavidromeAPI(), []);
const api = useMemo(() => {
const navidromeApi = getNavidromeAPI();
if (!navidromeApi) {
console.warn('⚠️ Navidrome API not configured');
} else {
console.log('✅ Navidrome API initialized');
}
return navidromeApi;
}, []);
useEffect(() => {
const savedQueue = localStorage.getItem('navidrome-audioQueue');
@@ -98,10 +106,14 @@ export const AudioPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ c
if (!api) {
throw new Error('Navidrome API not configured');
}
const streamUrl = api.getStreamUrl(song.id);
console.log('🎵 Creating track with stream URL:', streamUrl);
return {
id: song.id,
name: song.title,
url: api.getStreamUrl(song.id),
url: streamUrl,
artist: song.artist,
album: song.album,
duration: song.duration,