A modern React Next.js audio player for BMIR (Black Rock City Information Radio) clips with Fireproof local database storage and Redis session management.
- π΅ Modern Audio Player - Clean, responsive interface with custom controls
- π± Session Persistence - Redis stores playback state, volume, and current clip
- ποΈ Local Database - Fireproof stores all audio metadata locally
- π² Navigation - Previous, Next, and Random clip selection
- π¨ Beautiful UI - Tailwind CSS with custom styling
- β‘ Fast & Responsive - Built with Next.js 14 and React 18
- Frontend: Next.js 14, React 18, TypeScript
- Styling: Tailwind CSS
- Database: Fireproof (local, encrypted)
- Session Storage: Redis
- Audio: HTML5 Audio API
- Node.js 18+
- Redis server running locally (or Redis Cloud)
-
Clone and install dependencies:
cd bmir-audio-player npm install
-
Set up environment variables: Create a
.env.local
file:REDIS_URL=redis://localhost:6379 # Or for Redis Cloud: # REDIS_URL=redis://username:password@host:port
-
Start Redis (if running locally):
# macOS with Homebrew brew services start redis # Or start manually redis-server
-
Run the development server:
npm run dev
-
Open your browser: Navigate to http://localhost:3000
src/
βββ app/ # Next.js app directory
β βββ globals.css # Global styles
β βββ page.tsx # Main page
βββ components/ # React components
β βββ AudioPlayer.tsx # Main audio player component
βββ lib/ # Services and utilities
β βββ audio-db.ts # Fireproof database service
β βββ redis.ts # Redis session service
βββ types/ # TypeScript type definitions
β βββ audio.ts # Audio and session types
βββ scripts/ # Data import scripts
βββ import-audio-data.ts
interface AudioClip {
_id: string; // Fireproof auto-generated ID
title: string; // Display title
audioUrl: string; // S3 URL to audio file
category: string; // 'long-talks' | 'random' | 'camps-arts' | 'warnings'
filename: string; // Original filename
transcript?: string; // Optional transcript
createdAt: number; // Timestamp
}
interface SessionState {
currentClipId: string; // Currently playing clip ID
volume: number; // Audio volume (0-1)
isPlaying: boolean; // Playback state
currentTime: number; // Current playback position
sessionId: string; // Unique session identifier
lastUpdated: number; // Last update timestamp
}
- Play/Pause: Click the green button
- Previous/Next: Use the blue navigation buttons
- Random: Click the purple "Random Clip" button
- Volume: Adjust with the volume slider
- Seek: Drag the progress bar to jump to any position
- Your current clip, volume, and playback position are saved to Redis
- When you reopen the page, it will resume exactly where you left off
- Session data expires after 24 hours
The app uses Fireproof for local storage, which means:
- All data is stored encrypted in your browser
- No server setup required for the database
- Data persists between browser sessions
- Can be synced to cloud storage later
To import your actual BMIR audio files:
- Update the import script with your actual audio URLs and titles
- Run the import (you can add this as a development script)
- Customize the data as needed
- Push to GitHub
- Connect to Vercel
- Add Redis environment variable
- Deploy
- Ensure Redis is available (Redis Cloud, Upstash, etc.)
- Set environment variables
- Build and deploy
- Audio clips are stored in Fireproof database
- Session state is managed in Redis
- UI components are in
src/components/
- Types are defined in
src/types/
- Uses Tailwind CSS for styling
- Custom slider styles in
globals.css
- Responsive design for mobile/desktop
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - feel free to use this for your own projects!
- BMIR for the audio content
- Fireproof for the local database
- Next.js team for the amazing framework
- Tailwind CSS for the styling system