b8ff25f370
Songs persist under songs/ (MP3 via LFS, metadata in git). Player shows saved library. Co-authored-by: Cursor <cursoragent@cursor.com>
116 lines
4.0 KiB
Markdown
116 lines
4.0 KiB
Markdown
# Live Ozan Radio
|
|
|
|
Personal AI radio — **no catalog music, ever**. DeepSeek is the DJ. Google **Lyria 3** composes every track. Spotify is read-only taste input.
|
|
|
|
Inspired by [Magenta RealTime 2](https://magenta.withgoogle.com/magenta-realtime-2) (live, ~200ms) and [Lyria 3](https://deepmind.google/models/lyria/) (full songs via Gemini API). On Mac you can layer MRT2 for true live improvisation; this repo ships the cross-platform Lyria + DeepSeek stack first.
|
|
|
|
## Stack
|
|
|
|
| Layer | Product | Role |
|
|
|-------|---------|------|
|
|
| DJ brain | DeepSeek (via Tinqs inference or BYOK) | Mood, prompts, variety |
|
|
| Music engine | Google Lyria 3 Pro / Clip | Generate MP3 tracks |
|
|
| Taste | Spotify Web API (optional) | Top artists, genres — never plays Spotify |
|
|
| Player | FastAPI + `gateway/player.html` | Stream generated queue |
|
|
| Live (optional) | Magenta RealTime 2 | Apple Silicon only — see below |
|
|
|
|
## Saved songs
|
|
|
|
Every track is written to `./songs/` and **committed via Git LFS** (audio) + plain git (metadata):
|
|
|
|
| File | Storage | Contents |
|
|
|------|---------|----------|
|
|
| `{id}_{title}.mp3` | LFS | Audio |
|
|
| `{id}.meta.json` | git | Title, mood, DJ line, prompt, lyrics, timestamp |
|
|
|
|
Browse in the player under **Saved songs**, or `GET /api/songs`. After clone: `git lfs install` then `git lfs pull`.
|
|
|
|
## Quick start (Forge / Windows)
|
|
|
|
```powershell
|
|
cd live-ozan-radio
|
|
python -m venv .venv
|
|
.venv\Scripts\activate
|
|
pip install -e .
|
|
copy .env.example .env
|
|
# Fill GEMINI_API_KEY + DEEPSEEK_API_KEY (and Spotify if you have them)
|
|
|
|
python -m ozan_radio serve
|
|
# Open http://127.0.0.1:8787/player
|
|
```
|
|
|
|
One-shot track (no server):
|
|
|
|
```powershell
|
|
python -m ozan_radio generate
|
|
```
|
|
|
|
## Environment
|
|
|
|
| Variable | Required | Notes |
|
|
|----------|----------|-------|
|
|
| `GEMINI_API_KEY` | Yes | [Google AI Studio](https://aistudio.google.com/apikey) — Lyria 3 |
|
|
| `DEEPSEEK_API_KEY` | Yes | Tinqs proxy or DeepSeek direct |
|
|
| `DEEPSEEK_BASE_URL` | No | Default `https://tinqs.com/api/v1/inference` |
|
|
| `SPOTIFY_*` | No | Refresh token flow — taste only |
|
|
| `LYRIA_MODEL` | No | `lyria-3-pro-preview` (default) or `lyria-3-clip-preview` |
|
|
|
|
### Spotify setup (taste profile)
|
|
|
|
1. Create an app at [Spotify Developer Dashboard](https://developer.spotify.com/dashboard).
|
|
2. Add redirect URI `http://127.0.0.1:8888/callback`.
|
|
3. Complete OAuth once to obtain a refresh token (scope: `user-top-read`).
|
|
4. Paste `SPOTIFY_CLIENT_ID`, `SPOTIFY_CLIENT_SECRET`, `SPOTIFY_REFRESH_TOKEN` into `.env`.
|
|
|
|
The Spotify MCP / tool you wired to DeepSeek can call the same endpoints — this repo exposes them natively for the DJ loop.
|
|
|
|
## API
|
|
|
|
| Method | Path | Description |
|
|
|--------|------|-------------|
|
|
| GET | `/api/now` | Current track metadata |
|
|
| GET | `/api/queue` | Full queue |
|
|
| POST | `/api/generate` | DJ plans + Lyria renders next track |
|
|
| POST | `/api/skip` | Advance queue |
|
|
| GET | `/stream/{file}` | MP3 stream |
|
|
| GET | `/player` | Web UI |
|
|
|
|
## Magenta RealTime 2 (optional live layer)
|
|
|
|
On **Apple Silicon** (Kraken), install [magenta-rt](https://github.com/magenta/magenta-realtime) for sub-second live generation:
|
|
|
|
```bash
|
|
uv pip install "magenta-rt[mlx]"
|
|
mrt models init && mrt models download
|
|
mrt mlx generate --prompt "disco funk" --duration 4.0 --model=mrt2_small
|
|
```
|
|
|
|
Wire MRT2 as a bridge between tracks or as a live “bed” under the Lyria queue — PRs welcome.
|
|
|
|
## Publish on tinqs.com (public repo)
|
|
|
|
1. On Git Studio: **+ → New Repository**
|
|
- Owner: `tinqs`
|
|
- Name: `live-radio`
|
|
- Visibility: **Public**
|
|
2. Push (with LFS for song MP3s):
|
|
|
|
```bash
|
|
git lfs install
|
|
git init
|
|
git remote add origin git@ssh.tinqs.com:tinqs/live-radio.git
|
|
git add .
|
|
git commit -m "Live Ozan Radio — DeepSeek DJ + Lyria 3"
|
|
git push -u origin main
|
|
```
|
|
|
|
3. Preview the player: `https://tinqs.com/tinqs/live-radio/src/branch/main/gateway/player.html` (static shell; audio streams from your running server).
|
|
|
|
## Agent usage
|
|
|
|
DeepSeek (Pi, Cursor, Claude Code) can operate the station via HTTP or the skill in `.cursor/skills/ozan-radio/SKILL.md`.
|
|
|
|
## License
|
|
|
|
Apache 2.0 — same spirit as Magenta RealTime 2 open weights.
|