Radai is an attempt to create a radio experience using podcasts and Spotify. If you like listening to podcasts, love listening to music and want to do both at the same time, I've made this for you.
It's a private, always-on internet radio station that combines prepared YouTube podcasts with Spotify music breaks. It runs on your server, streams through the web interface, and keeps running even after the browser is closed. Any suggestions and contributions are welcome. Email me at me@mathiasmagambo.com if you want me to help you set this up for you (at a fee).
The podcast is pulled from Youtube with a transcript. The transcript is run through an AI model of your choice (currently DeepSeek, will configure other models later) to generate cut timetamps where ads are or based on topics. Music gets played in between the podcast ad breaks using Spotify. The Radai engine controls Spotify installed on your server through the GUI. spotifyd is used as an audio capture device. Like having Bluetooth headphones for your server to be able to listen to audio.
YouTube channel/video
→ yt-dlp downloads audio and subtitles
→ AI model identifies ads and music-break positions
→ FFmpeg removes ads and prepares normalized podcast audio
→ Radai Engine plays podcast segments
│
Spotify Desktop → spotifyd PCM ──┤
▼
FFmpeg MP3 encoder
▼
Icecast source
▼
Radai buffered web stream
▼
Nginx + browser/VLC
This is only for the main features and updates. Everything else is in FEATURES.md.
- Add links to YouTube channels as podcast sources. New episodes are pulled periodically.
- Add a single video link and listen to it immediately.
- Set how many new podcasts per channel you want stored on the server and how many played podcasts you want saved.
- Add extra music breaks as you listen to a podcast. Click the ADD MUSIC BREAK button and scrub along the timeline to where you want a break.
- You can search for a song in the Spotify search and use the song's Song Radio as a music source.
- Use your saved playlists as the saved music sources by default.
- See history of played podcasts.
- See where the music breaks are and how many they are.
- Python 3 backend
- Python standard-library ThreadingHTTPServer
- Vanilla HTML, CSS and JavaScript frontend; no frontend build step
- FFmpeg/ffprobe for decoding, editing and MP3 encoding
- Icecast as the local MP3 source server
- Optional Node.js runtime for newer YouTube JavaScript challenges
Runtime state, downloaded media, transcripts, prepared audio and authentication caches live under data/ and are excluded from Git.
────────────────────────────────────────────────────────────────────────────────
The following example assumes Ubuntu and installs the project at /opt/radai.
- Install system packages
sudo apt update
sudo apt install \
git \
python3 \
python3-venv \
ffmpeg \
icecast2 \
nginxOptional HTTPS support:
sudo apt install certbot python3-certbot-nginxInstall Spotify Desktop. For example, using the official Snap:
sudo snap install spotifyInstall spotifyd (https://docs.spotifyd.rs/installation/index.html) using your distribution package or one of its release binaries (https://github.com/Spotifyd/spotifyd/releases). Confirm it is available:
spotifyd --versionA Spotify Premium account is normally required for Spotify Connect playback through spotifyd.
- Clone and install Radai Engine
sudo git clone https://github.com/MathiasMagambo/radai /opt/radai
sudo chown -R "$USER:$USER" /opt/radai
cd /opt/radai
python3 -m venv .venv
.venv/bin/pip install --upgrade pip
.venv/bin/pip install -e .
.venv/bin/pip install yt-dlpFor development:
.venv/bin/pip install -e '.[dev]'
.venv/bin/pytest- Configure the environment
cd /opt/radai
cp .env.example .env
chmod 600 .envAt minimum, configure:
RADAI_ROOT=/opt/radai
RADIO_HOST=127.0.0.1
RADIO_PORT=8090
RADIO_USERNAME=radio
RADIO_PASSWORD=replace-with-a-long-random-password
DEEPSEEK_API_KEY=your-deepseek-api-key
DEEPSEEK_MODEL=deepseek-chat
ICECAST_SOURCE_PASSWORD=replace-with-another-random-password
ICECAST_PORT=8001
SPOTIFY_DEVICE_NAME=Radai Radio
SPOTIFY_CDP_URL=http://127.0.0.1:9223
SPOTIFYD_PATH=/home/your-user/.local/bin/spotifydThe legacy Spotify Web API fields are not required for the current Spotify Desktop/Song Radio workflow.
- Configure Icecast
Edit:
/etc/icecast2/icecast.xml
Set its source password to exactly the same value as:
ICECAST_SOURCE_PASSWORD=Configure Icecast to listen locally on port 8001. Restart it:
sudo systemctl restart icecast2
sudo systemctl status icecast2Radai publishes its source at:
http://127.0.0.1:8001/spotify.mp3
Icecast does not need to be exposed publicly.
- Authenticate Spotify
Run Spotify Desktop as the same Linux user that will run Radai. Sign into your Spotify account once. If you're running a headless server you can open Spotify with a GUI using Xvfb and log in using your qr code.
Authenticate spotifyd as that same user:
spotifyd authenticateFollow the browser authorization link. spotifyd stores its OAuth credentials in its user cache. See the spotifyd authentication documentation (https://docs.spotifyd.rs/configuration/auth.html).
- Start Spotify Desktop with remote debugging
Copy the supplied service:
mkdir -p ~/.config/systemd/user
cp deploy/radai-spotify-desktop.service ~/.config/systemd/user/Edit the copied unit if necessary:
- Change /usr/bin/spotify to /snap/bin/spotify for Snap.
- Set the correct DISPLAY.
- Keep remote debugging on port 9223.
Then enable it:
systemctl --user daemon-reload
systemctl --user enable --now radai-spotify-desktop.serviceCheck it:
systemctl --user status radai-spotify-desktop.service
curl http://127.0.0.1:9223/jsonA headless server needs a persistent graphical session, such as Xvfb, with the service’s DISPLAY pointed at that session.
- Install the Radai web service
cp deploy/radai-web.service ~/.config/systemd/user/Adjust /opt/radai in the unit if the repository is installed elsewhere.
Enable it:
systemctl --user daemon-reload
systemctl --user enable --now radai-web.serviceFor startup without an interactive SSH login:
sudo loginctl enable-linger "$USER"Verify:
systemctl --user status radai-web.service
curl -u 'radio:your-password' http://127.0.0.1:8090/api/status- Configure Nginx and HTTPS
Copy the supplied Nginx template:
sudo cp deploy/nginx.conf.example /etc/nginx/sites-available/radai
sudo ln -s /etc/nginx/sites-available/radai /etc/nginx/sites-enabled/radaiEdit server_name and replace radio.example.com with your domain.
Validate and reload:
sudo nginx -t
sudo systemctl reload nginxFor HTTPS:
sudo certbot --nginx -d radio.example.comNginx proxies the control site to port 8090 and serves the authenticated, unbuffered MP3 endpoint at:
https://radio.example.com/stream.mp3
-
Start using it
-
Open the configured site.
-
Sign in with RADIO_USERNAME and RADIO_PASSWORD.
-
Add one or more YouTube podcast sources.
-
Wait for an episode to download and prepare.
-
Select a Spotify playlist or Song Radio seed.
-
Configure the number of songs per music break.
-
Press START RADIO.
-
Listen in the browser or open /stream.mp3 in VLC.
For restricted YouTube content, place a Netscape-format cookie file at:
data/state/youtube-cookies.txt
Keep cookies, Spotify OAuth credentials, generated media and .env private; none should be committed to Git.