This is the git project for the Rainwave website, https://rainwave.cc.
Rainwave is a system to control an external player such as MPD, or a streaming source such as Ices or Liquidsoap. Rainwave.cc uses its own custom player which is available on Github. Rainwave cannot play or stream audio by itself.
The software stack and data flow for broadcasting:
- The media player asks Rainwave's backend server what song/MP3 file should be played next.
- Rainwave's backend replies with a song/MP3 file.
- The player reads and encodes the stream to Icecast.
- Icecast distributes audio to users.
- Icecast tells Rainwave's web API when users tune in/out.
- Users interact with Rainwave through the website/API.
Authentication for Rainwave users is dependant on Discord.
- Enable external auth by placing your app keys in the config file
- If you're just running Rainwave for streaming audio, you do not need Discord.
- If you are just testing/developing locally, you do not need Discord.
- Rainwave requires a library of ~2000 songs to function properly, and all songs must be tagged with album, artist, and title.
- Rainwave requires the commandline
rsgaintool to be installed on its path.
If using Icecast, Icecast 2.4.x or above is required.
Rainwave is designed to run on Python 3.14 using uv.
git clone https://github.com/rmcauley/rainwave.git
cd rainwave
sudo apt install rsgain
uv sync
sudo -u postgres createdb rainwave
sudo -u postgres psql -d rainwave -c "CREATE EXTENSION IF NOT EXISTS pg_trgm"
You then need to run the schema initialization found in schema.py.
Edit your configuration file in ./src/common/config.py, and follow the instructions
within to setup your install. Please read through the entire config carefully.
Some options are very important.
Tips:
- Until you're ready to deploy a production version, it's best to leave development mode on and keep Rainwave single-processed.
- Station ID 0 cannot be used, station IDs must start at 1.
Locate the "song_dir" entry from your configuration file and copy/paste your music library to this directory.
- Your MP3 tags must be accurate. Rainwave reads the tags to obtain track information, which is necessary to manage song rotation.
- Upload a minimum of 1,000 songs. Rainwave requires a minimal library of this size to operate correctly.
- Place albums in separate directories if using album art. To add album art, create a file named "folder.jpg" and place it in each album directory for it to appear. (sorry, embedded album art is not supported)
- Rainwave and LiquidSoap support unicode MP3 tags, but do not support unicode filenames. Please rename files that contain accents and symbols. Rainwave will reject and skip files that contain accents or symbols.
Open a terminal/command line to your Rainwave repository directory. You need to initialize the database and then add your songs to the database:
uv run db_init.py
Now have Rainwave pick up the music you added to your song_dirs:
uv run rw_scanner.py --full
This will run a full scan of your song_dirs. To monitor song_dirs
continuously without using CPU, run rw_scanner.py without the --full switch.
Once done, open another terminal/command line and start the music management backend that LiquidSoap talks to:
uv run rw_song_change_api.py
Once that is started successfully, open another terminal/command line and start the public-facing website and API:
uv run rw_api.py
Now use the same tool LiquidSoap uses to test that everything works:
uv run rw_get_next.py
If successful, you should see a song file name as output.
Open the beta URL at /?sid=1 to see your Rainwave.
If you are not running against an installed phpBB and want
to emulate being logged in, open /api4/test/login_tuned_in/1.
For this project, HTML coverage should be generated with run_coverage.sh directly,
not pytest --cov, because the test suite starts the API in a separate process.
Use:
./scripts/run_coverage.shTo run a subset:
./scripts/run_coverage.sh src/tests/http_requestsThis writes the HTML report to htmlcov/index.html.
[[TODO]]
Rainwave's currently undergoing changes to its deployment and startup scripts so that it runs as a Rainwave user and everything is contained to its own home directory.
During installation, Rainwave has no safety mechanisms or rolling restarts. Rainwave will appear to be shutdown for a few seconds to the outside world while installing/updating. If the restart fails, Rainwave will be offline.
For user tune in recognition to work, you have to use Icecast's user authentication system.
You can get help for deployment and development through the main developer, Rob, on the Rainwave discord:
On modernize deployment:
- ALTER TABLE r4_elections ALTER COLUMN elec_id TYPE BIGINT;
- ALTER TABLE r4_elections ALTER COLUMN elec_id SET DEFAULT nextval('r4_timeline_id_seq');
- ALTER TABLE r4_one_ups ALTER COLUMN one_up_id TYPE BIGINT;
- ALTER TABLE r4_one_ups ALTER COLUMN one_up_id SET NOT NULL;
- ALTER TABLE r4_one_ups ADD PRIMARY KEY (one_up_id);
- remove r4_album_sid.album_updated as it was replaced with album_updated_at
- Route https://rainwave.cc/api4/rainwave-openapi.json
- CREATE UNIQUE INDEX r4_listeners_user_id_unique_idx ON r4_listeners (user_id) WHERE user_id > 1
- ALTER TABLE r4_listeners SET user_id NOT NULL;
- CREATE UNIQUE INDEX r4_listeners_listener_key_unique_idx ON r4_listeners (listener_ip) WHERE user_id = 1 AND listener_ip IS NOT NULL
- CREATE UNIQUE INDEX r4_listeners_listener_key_unique_idx ON r4_listeners (listener_key) WHERE user_id = 1 AND listener_key IS NOT NULL
- Update the CSP header based on the debug output