Compare commits
4 Commits
2ca35620d9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cd2d62e22 | |||
| 8e44de6bb5 | |||
| ee433157f4 | |||
| 159d2be52d |
@@ -1,5 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
carplay-audio:
|
carplay-audio:
|
||||||
build: .
|
build: .
|
||||||
@@ -10,13 +8,13 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
# Mount your music library (change the left path to your music folder)
|
# Mount your music library (change the left path to your music folder)
|
||||||
- /Volumes/Data/Music:/data/music:ro
|
- /Volumes/Data/Music:/data/music:ro
|
||||||
# Persistent data (database, artwork, config)
|
# Persistent data (database and artwork stored in data directory)
|
||||||
- ./data/artwork:/app/artwork
|
- ./data:/app/data
|
||||||
- ./data/database:/app
|
|
||||||
- ./config.json:/app/config.json
|
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- PORT=4000
|
- PORT=4000
|
||||||
|
- DB_PATH=/app/data/audio_server.db
|
||||||
|
- LIBRARY_PATH=/data/music
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:4000/health"]
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:4000/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import sqlite3 from 'sqlite3';
|
import sqlite3 from 'sqlite3';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
|
||||||
const db = new sqlite3.Database('./audio_server.db');
|
const dbPath = process.env.DB_PATH || './audio_server.db';
|
||||||
|
const db = new sqlite3.Database(dbPath);
|
||||||
|
|
||||||
const run = promisify(db.run.bind(db));
|
const run = promisify(db.run.bind(db));
|
||||||
const get = promisify(db.get.bind(db));
|
const get = promisify(db.get.bind(db));
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ await initDatabase();
|
|||||||
|
|
||||||
// Load config to get library path
|
// Load config to get library path
|
||||||
const config = await loadConfig();
|
const config = await loadConfig();
|
||||||
const libraryPath = process.argv[2] || config.libraryPath;
|
// Override with environment variable if set
|
||||||
|
const libraryPath = process.argv[2] || process.env.LIBRARY_PATH || config.libraryPath;
|
||||||
|
|
||||||
// Resolve path
|
// Resolve path
|
||||||
const resolvedPath = path.isAbsolute(libraryPath)
|
const resolvedPath = path.isAbsolute(libraryPath)
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ const app = express();
|
|||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
const config = await loadConfig();
|
const config = await loadConfig();
|
||||||
|
// Override with environment variables if set
|
||||||
|
if (process.env.LIBRARY_PATH) {
|
||||||
|
config.libraryPath = process.env.LIBRARY_PATH;
|
||||||
|
}
|
||||||
const PORT = process.env.PORT || config.port || 3000;
|
const PORT = process.env.PORT || config.port || 3000;
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
@@ -51,7 +55,12 @@ const libraryPath = path.isAbsolute(config.libraryPath)
|
|||||||
? config.libraryPath
|
? config.libraryPath
|
||||||
: path.join(process.cwd(), config.libraryPath);
|
: path.join(process.cwd(), config.libraryPath);
|
||||||
app.use('/audio', express.static(libraryPath));
|
app.use('/audio', express.static(libraryPath));
|
||||||
app.use('/artwork', express.static(path.join(process.cwd(), 'artwork')));
|
|
||||||
|
// Artwork can be in data directory (Docker) or root (local)
|
||||||
|
const artworkPath = process.env.NODE_ENV === 'production'
|
||||||
|
? path.join(process.cwd(), 'data', 'artwork')
|
||||||
|
: path.join(process.cwd(), 'artwork');
|
||||||
|
app.use('/artwork', express.static(artworkPath));
|
||||||
|
|
||||||
// Health check
|
// Health check
|
||||||
app.get('/health', (req, res) => {
|
app.get('/health', (req, res) => {
|
||||||
|
|||||||
22
tasks.md
22
tasks.md
@@ -37,12 +37,32 @@
|
|||||||
- [x] User management
|
- [x] User management
|
||||||
- [x] Now playing
|
- [x] Now playing
|
||||||
- [x] Full Amperfy compatibility
|
- [x] Full Amperfy compatibility
|
||||||
|
- [x] Docker deployment with docker-compose
|
||||||
|
- [x] Persistent data volumes
|
||||||
|
- [x] Environment variable configuration
|
||||||
|
- [x] Library scanning in Docker
|
||||||
|
- [x] Pushed to Gitea repository
|
||||||
|
- [x] Production-ready deployment
|
||||||
|
|
||||||
## Todo
|
## Project Complete! ✅
|
||||||
|
|
||||||
|
**CarPlay Audio Streaming Server is fully operational:**
|
||||||
|
- 🎵 Streaming music to Amperfy and CarPlay
|
||||||
|
- 🐳 Docker containerized for easy deployment
|
||||||
|
- 🔄 Git repository on Gitea for version control
|
||||||
|
- 🌐 Accessible via HTTPS through Cloudflare Tunnel
|
||||||
|
- 📊 Web admin panel for management
|
||||||
|
- 🎨 Album artwork support
|
||||||
|
- 📁 Folder/artist/album browsing
|
||||||
|
- 🔍 Full search functionality
|
||||||
|
- 📋 Playlist management
|
||||||
|
|
||||||
|
## Future Enhancements (Optional)
|
||||||
- [ ] Implement favorites/starred tracking in database
|
- [ ] Implement favorites/starred tracking in database
|
||||||
- [ ] Add play count tracking
|
- [ ] Add play count tracking
|
||||||
- [ ] Optimize cover art caching
|
- [ ] Optimize cover art caching
|
||||||
- [ ] Add transcoding support
|
- [ ] Add transcoding support
|
||||||
|
- [ ] Multi-user support with authentication
|
||||||
- [ ] Enhanced user authentication
|
- [ ] Enhanced user authentication
|
||||||
- [ ] Multiple user support
|
- [ ] Multiple user support
|
||||||
- [ ] Advanced filtering
|
- [ ] Advanced filtering
|
||||||
|
|||||||
Reference in New Issue
Block a user