Modern radio station tracking system for New Zealand radio stations.
- 🎵 Real-time song tracking via ICY metadata parsing
- 📊 Analytics and historical play data
- 🔄 Bull queue-driven automatic scraping (60-second intervals)
- 🚀 Next.js + Chakra UI frontend
- 🐳 Docker Compose for dev and production
- ✅ Currently tracking 3 SomaFM stations with live "Now Playing" data
- Node.js + Express + TypeScript
- PostgreSQL (database)
- Redis (cache & queue)
- Bull (job queue)
- Prisma (ORM)
- Socket.io (real-time)
- Next.js 15 (App Router)
- Chakra UI
- TypeScript
- Socket.io Client
# Start all services
docker compose -f docker-compose.dev.yml up -d
# View logs
docker compose -f docker-compose.dev.yml logs -f
# Stop services
docker compose -f docker-compose.dev.yml downServices:
- Frontend: http://localhost:3001
- Backend API: http://localhost:4000
- PostgreSQL: localhost:5433
- Redis: localhost:6380
Seed Database:
docker exec radionetwork_api_dev npm run prisma:seed# Build and start
docker compose -f docker-compose.prod.yml up -d
# View logs
docker compose -f docker-compose.prod.yml logs -fThe following stations are actively scraping "Now Playing" data:
- SomaFM Groove Salad - Ambient, Downtempo, Chillout
- SomaFM Drone Zone - Ambient, Drone, Space Music
- SomaFM Secret Agent - Lounge, Spy Jazz, Downtempo
The database includes 10 top NZ radio stations, but they use HLS streams which don't support ICY metadata:
- ZM - Top 40, Pop, Hit Music
- The Edge - Rock, Alternative, Hit Music
- The Rock - Rock, Classic Rock, Hard Rock
- More FM - Classic Hits, 80s, 90s, 00s
- Newstalk ZB - News, Talk, Current Affairs
- Radio Hauraki - Rock, Classic Rock, Alternative
- Coast - Easy Listening, Adult Contemporary, Classic Hits
- The Breeze - Easy Listening, Soft Rock, Adult Contemporary
- Mai FM - Hip Hop, R&B, Urban, Pacific
- George FM - Electronic, Dance, House, EDM
Note: NZ stations require alternative scraping methods (website parsing or official APIs) as they stream via HLS (.m3u8) instead of ICY metadata.
GET /api/stations- List all stationsGET /api/stations/:slug- Get station detailsGET /api/stations/:slug/current- Current playing songGET /api/stations/:slug/history- Play historyGET /api/songs- All songsGET /api/songs/top- Top songsGET /api/analytics/stats- System statistics
# Start services
docker compose -f docker-compose.dev.yml up -d
# Stop services
docker compose -f docker-compose.dev.yml down
# View logs
docker compose -f docker-compose.dev.yml logs -f
# Restart a service
docker restart radionetwork_api_dev
docker restart radionetwork_frontend_dev
# Seed database with NZ stations
docker exec radionetwork_api_dev npm run prisma:seed
# Run Prisma migrations
docker exec radionetwork_api_dev npx prisma migrate deploy
# Generate Prisma client
docker exec radionetwork_api_dev npx prisma generate
# Access database
docker exec -it radionetwork_db_dev psql -U radionetwork -d radionetwork_devCheck if songs are being scraped:
# View recent plays
docker exec radionetwork_db_dev psql -U radionetwork -d radionetwork_dev -c "SELECT st.name, s.artist, s.title, p.played_at FROM plays p JOIN stations st ON p.station_id = st.id JOIN songs s ON p.song_id = s.id ORDER BY p.played_at DESC LIMIT 10;"
# Check SomaFM Groove Salad current song
curl http://localhost:4000/api/stations/soma-groove-salad/current | jq
# View all working stations
curl http://localhost:4000/api/stations | jq '.[] | select(.name | contains("SomaFM")) | {name, lastScrapedAt}'Visit http://localhost:3001/stations/soma-groove-salad to see live updates in the UI.
MIT