From cc2f1d00519f7bb8ab743b07c753d828d6b3a423 Mon Sep 17 00:00:00 2001 From: Benoit Date: Tue, 23 Dec 2025 14:33:25 +0100 Subject: [PATCH] Fix CORS --- .env.example | 7 +++-- backend/src/utils/config.py | 11 ++++++-- docker-compose.build.yml | 2 +- docker-compose.yml | 2 +- frontend/app/page.tsx | 20 +++++++++++--- frontend/components/AudioPlayer.tsx | 42 ++++++++++++++++++----------- 6 files changed, 59 insertions(+), 25 deletions(-) diff --git a/.env.example b/.env.example index 6f00655..1ae717a 100644 --- a/.env.example +++ b/.env.example @@ -5,7 +5,9 @@ POSTGRES_PASSWORD=audio_password POSTGRES_DB=audio_classifier # Backend API -CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 +# Use "*" to allow all origins (recommended for development/local deployment) +# Or specify comma-separated URLs for production: http://yourdomain.com,https://yourdomain.com +CORS_ORIGINS=* API_HOST=0.0.0.0 API_PORT=8000 @@ -16,4 +18,5 @@ ESSENTIA_MODELS_PATH=/app/models AUDIO_LIBRARY_PATH=/path/to/your/audio/library # Frontend -NEXT_PUBLIC_API_URL=http://localhost:8000 +# API URL accessed by the browser (use port 8001 since backend is mapped to 8001) +NEXT_PUBLIC_API_URL=http://localhost:8001 diff --git a/backend/src/utils/config.py b/backend/src/utils/config.py index 3814f38..dde2ffd 100644 --- a/backend/src/utils/config.py +++ b/backend/src/utils/config.py @@ -10,7 +10,8 @@ class Settings(BaseSettings): DATABASE_URL: str = "postgresql://audio_user:audio_password@localhost:5432/audio_classifier" # API Configuration - CORS_ORIGINS: str = "http://localhost:3000,http://127.0.0.1:3000" + # Comma-separated list of allowed origins, or use "*" to allow all + CORS_ORIGINS: str = "*" API_HOST: str = "0.0.0.0" API_PORT: int = 8000 @@ -33,7 +34,13 @@ class Settings(BaseSettings): @property def cors_origins_list(self) -> List[str]: - """Parse CORS origins string to list.""" + """Parse CORS origins string to list. + + If CORS_ORIGINS is "*", allow all origins. + Otherwise, parse comma-separated list. + """ + if self.CORS_ORIGINS.strip() == "*": + return ["*"] return [origin.strip() for origin in self.CORS_ORIGINS.split(",")] diff --git a/docker-compose.build.yml b/docker-compose.build.yml index 0b627f7..46d2ef7 100644 --- a/docker-compose.build.yml +++ b/docker-compose.build.yml @@ -31,7 +31,7 @@ services: condition: service_healthy environment: DATABASE_URL: postgresql://${POSTGRES_USER:-audio_user}:${POSTGRES_PASSWORD:-audio_password}@postgres:5432/${POSTGRES_DB:-audio_classifier} - CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000} + CORS_ORIGINS: ${CORS_ORIGINS:-*} ANALYSIS_USE_CLAP: ${ANALYSIS_USE_CLAP:-false} ANALYSIS_NUM_WORKERS: ${ANALYSIS_NUM_WORKERS:-4} ESSENTIA_MODELS_PATH: /app/models diff --git a/docker-compose.yml b/docker-compose.yml index 4b9be24..46b9707 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,7 @@ services: condition: service_healthy environment: DATABASE_URL: postgresql://${POSTGRES_USER:-audio_user}:${POSTGRES_PASSWORD:-audio_password}@postgres:5432/${POSTGRES_DB:-audio_classifier} - CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000} + CORS_ORIGINS: ${CORS_ORIGINS:-*} ANALYSIS_USE_CLAP: ${ANALYSIS_USE_CLAP:-false} ANALYSIS_NUM_WORKERS: ${ANALYSIS_NUM_WORKERS:-4} ESSENTIA_MODELS_PATH: /app/models diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index 9ee1e26..706dd5e 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -52,6 +52,7 @@ export default function Home() { const [filters, setFilters] = useState({}) const [page, setPage] = useState(0) const [currentTrack, setCurrentTrack] = useState(null) + const [isPlaying, setIsPlaying] = useState(false) const [searchQuery, setSearchQuery] = useState("") const [isScanning, setIsScanning] = useState(false) const [scanStatus, setScanStatus] = useState("") @@ -233,10 +234,19 @@ export default function Home() {
{/* Play button */}
) diff --git a/frontend/components/AudioPlayer.tsx b/frontend/components/AudioPlayer.tsx index 3d41340..ba7d332 100644 --- a/frontend/components/AudioPlayer.tsx +++ b/frontend/components/AudioPlayer.tsx @@ -5,10 +5,11 @@ import type { Track } from "@/lib/types" interface AudioPlayerProps { track: Track | null + isPlaying: boolean + onPlayingChange: (playing: boolean) => void } -export default function AudioPlayer({ track }: AudioPlayerProps) { - const [isPlaying, setIsPlaying] = useState(false) +export default function AudioPlayer({ track, isPlaying, onPlayingChange }: AudioPlayerProps) { const [currentTime, setCurrentTime] = useState(0) const [duration, setDuration] = useState(0) const [volume, setVolume] = useState(1) @@ -22,7 +23,7 @@ export default function AudioPlayer({ track }: AudioPlayerProps) { // Load audio and waveform when track changes useEffect(() => { if (!track) { - setIsPlaying(false) + onPlayingChange(false) setCurrentTime(0) setWaveformPeaks([]) return @@ -33,13 +34,13 @@ export default function AudioPlayer({ track }: AudioPlayerProps) { if (audioRef.current) { audioRef.current.load() - // Autoplay when track loads - audioRef.current.play().then(() => { - setIsPlaying(true) - }).catch((error: unknown) => { - console.error("Autoplay failed:", error) - setIsPlaying(false) - }) + // Autoplay when track loads if isPlaying is true + if (isPlaying) { + audioRef.current.play().catch((error: unknown) => { + console.error("Autoplay failed:", error) + onPlayingChange(false) + }) + } } }, [track?.id]) @@ -54,7 +55,7 @@ export default function AudioPlayer({ track }: AudioPlayerProps) { setDuration(audio.duration) } } - const handleEnded = () => setIsPlaying(false) + const handleEnded = () => onPlayingChange(false) audio.addEventListener("timeupdate", updateTime) audio.addEventListener("loadedmetadata", updateDuration) @@ -91,15 +92,24 @@ export default function AudioPlayer({ track }: AudioPlayerProps) { } } - const togglePlay = () => { - if (!audioRef.current || !track) return + // Sync playing state with audio element + useEffect(() => { + const audio = audioRef.current + if (!audio) return if (isPlaying) { - audioRef.current.pause() + audio.play().catch((error: unknown) => { + console.error("Play failed:", error) + onPlayingChange(false) + }) } else { - audioRef.current.play() + audio.pause() } - setIsPlaying(!isPlaying) + }, [isPlaying, onPlayingChange]) + + const togglePlay = () => { + if (!audioRef.current || !track) return + onPlayingChange(!isPlaying) } const handleVolumeChange = (e: React.ChangeEvent) => {