# CarPlay Audio Server A Node.js server application for managing and streaming audio files to CarPlay-compatible clients. ## Features ### Audio Management - 🎵 Automatic library scanning with metadata extraction - 📁 Folder-based organization - 🎼 Album vs Single classification - 🎨 Artwork extraction and serving - 📝 ID3 tag parsing (title, artist, album, year, genre, etc.) - 📤 File upload support ### Organization - 📀 Album management with track grouping - 🎯 Singles collection - 📋 Custom playlists - 🗂️ Folder browsing ### Streaming - 🚗 CarPlay-compatible REST API - 🎧 Direct audio file streaming - 🖼️ Album artwork delivery - ⚡ Efficient file serving ## Requirements - Node.js 16+ - npm or yarn ## Installation ```bash # Install dependencies npm install # Create audio library directory mkdir -p audio_library # Copy your audio files to audio_library/ # Organize them in folders as you like ``` ## Usage ### 1. Scan Your Library ```bash # Scan default library (./audio_library) npm run scan # Scan custom path node src/scripts/scanLibrary.js /path/to/your/music ``` This will: - Find all audio files (mp3, m4a, flac, wav, aac, ogg) - Extract metadata from ID3 tags - Detect albums vs singles - Extract and save artwork - Create database entries ### 2. Start the Server ```bash # Production npm start # Development (with auto-reload) npm run dev ``` Server runs on `http://localhost:3000` ## API Endpoints ### Tracks - `GET /api/tracks` - Get all tracks - Query params: `?album=`, `?artist=`, `?folder=`, `?single=true/false` - `GET /api/tracks/:id` - Get single track - `PATCH /api/tracks/:id` - Update track metadata - `GET /api/tracks/folders/list` - List all folders ### Albums - `GET /api/albums` - Get all albums - `GET /api/albums/:id` - Get album with tracks - `GET /api/albums/singles/list` - Get all singles ### Playlists - `GET /api/playlists` - Get all playlists - `POST /api/playlists` - Create playlist - `GET /api/playlists/:id` - Get playlist with tracks - `POST /api/playlists/:id/tracks` - Add track to playlist - `DELETE /api/playlists/:id/tracks/:trackId` - Remove track - `DELETE /api/playlists/:id` - Delete playlist ### Upload - `POST /api/upload` - Upload audio file - Form data: `audio` (file), `isSingle` (boolean) ### Static Files - `/audio/*` - Stream audio files - `/artwork/*` - Serve album artwork ## Library Organization The server supports flexible organization: ``` audio_library/ ├── Artist Name/ │ ├── Album Name/ │ │ ├── 01 - Track.mp3 │ │ └── 02 - Track.mp3 │ └── Singles/ │ └── Single Track.mp3 └── Various Artists/ └── Compilation Album/ ``` ### Album vs Single Detection Files are marked as singles if: - Located in a folder named "singles" or "single" - No album tag in metadata - You manually mark them via API Update track classification: ```bash curl -X PATCH http://localhost:3000/api/tracks/:id \ -H "Content-Type: application/json" \ -d '{"isSingle": true}' ``` ## CarPlay Client Integration Your CarPlay client should: 1. Fetch tracks: `GET /api/tracks` 2. Get stream URL from response 3. Play using AVPlayer with the `streamURL` 4. Display artwork from `artworkURL` Example response: ```json { "tracks": [ { "id": "abc123", "title": "Song Title", "artist": "Artist Name", "album": "Album Name", "duration": 180, "streamURL": "http://localhost:3000/audio/path/to/file.mp3", "artworkURL": "http://localhost:3000/artwork/abc123.jpg" } ] } ``` ## Project Structure ``` ├── src/ │ ├── server.js # Main server │ ├── database/ │ │ └── db.js # SQLite database │ ├── routes/ │ │ ├── tracks.js # Track endpoints │ │ ├── albums.js # Album endpoints │ │ ├── playlists.js # Playlist endpoints │ │ └── upload.js # Upload endpoint │ ├── services/ │ │ └── audioScanner.js # Library scanner │ └── scripts/ │ └── scanLibrary.js # CLI scanner ├── audio_library/ # Your audio files ├── artwork/ # Extracted artwork └── audio_server.db # SQLite database ```