-
Notifications
You must be signed in to change notification settings - Fork 2
Beta Testing
Thank you for your interest in Medley!
This guide will walk you through the process of setting up and running the beta version of Medley.
- Prerequisites
- Setting up
- WebRTC Configuration
- Prepare your music and jingles
- Configure Medley
- Starting Medley
- Web UI
- Adding the bot to your server
- Spotify Integration
Before you begin, ensure you have the following:
-
Docker Engine or Docker Desktop
-
A compatible system architecture:
- x86_64
- arm64
-
Docker Compose
- We'll be using Docker Compose to set up Medley and MongoDB together.
- Docker Compose usually comes with Docker Desktop. If you're using Docker Engine, you might need to install it separately: Install Docker Compose
-
MongoDB
- You need to have a MongoDB instance running that Medley can connect to.
-
Discord server
- The beta version of Medley currently only supports Discord as an audio output target.
- You must have administrative privileges on the server to add the Medley bot.
We provide an example docker-compose.yml file that sets up both Medley and MongoDB. This is the recommended method for most users.
-
Create a new directory for your Medley setup and navigate into it.
-
Create a file named
docker-compose.ymland paste the following content:
services:
mongo:
image: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
radio:
image: ghcr.io/seamless-medley/medley:latest
restart: unless-stopped
depends_on:
- mongo
ports:
# Web UI
- 3001:3001
# WebRTC
- 9989:9989
environment:
# MEDLEY_DEFAULT_RTC_IP: 192.168.1.100
# MEDLEY_DEFAULT_RTC_PORT: 9989
LOG_PRETTY: use-colors
FORCE_COLOR: 3
volumes:
- /Music-Station/medley/config.yml:/app/config.yml
- /Music-Station/musics:/data/musics
- /Music-Station/medley-drops:/data/medley-dropsMedley uses WebRTC (Web Real-Time Communication) for audio playback in web browsers.
The following environment variables allow you to configure the WebRTC connection settings.
This setting is required only when you want to play audio from a browser running on a different machine than the one hosting Docker.
- When to set: If your browser and Docker host are on different machines (e.g., Docker running on a server, browser on your laptop)
-
Value: Set this to your Docker host machine's IP address (e.g.,
192.168.1.100) - When to skip: If the browser and Docker are running on the same machine, leave this commented out
This setting allows you to change the WebRTC port from the default value of 9989.
Important
Please note that:
- The port must be available on your host machine
- You must update the port forwarding in the
portssection- The port forwarding format is
<host-port>:<container-port> - Both the host port and container port must be identical for WebRTC to work correctly
- Example: if changing to port 8888, update the ports section from default value
9989:9989to8888:8888
- The port forwarding format is
This section shows an example of how the setup would look like, feel free to change what you see fit.
-
Music Collections:
The
/data/musicsdirectory (mapped to/Music-Station/musicson your host) is where you should place your music files.Organize your music into subdirectories within this folder. Each subdirectory represents a separate music collection, mood, or category.
Example structure:
/Music-Station/musics/ ├── brokenhearted/ │ ├── Artist1 - Heartbreak Song.mp3 │ ├── Artist2 - Lost Love.flac │ └── ... ├── lonely/ │ ├── Artist3 - Solitude.mp3 │ ├── Artist4 - Alone Again.wav │ └── ... ├── chill/ │ ├── Artist5 - Relaxed Vibes.mp3 │ ├── Artist6 - Easy Sunday.ogg │ └── ... ├── lovesong/ │ ├── Artist7 - Romantic Ballad.mp3 │ ├── Artist8 - Forever Yours.flac │ └── ... ├── joyful/ │ ├── Artist9 - Happy Days.mp3 │ ├── Artist10 - Celebration.wav │ └── ... ├── upbeat/ │ ├── Artist11 - Dance All Night.mp3 │ ├── Artist12 - Energy Boost.ogg │ └── ... └── new-released/ ├── Artist13 - Fresh Hit.mp3 ├── Artist14 - Latest Single.flac └── ... -
Jingles (Drops):
The
/data/dropsdirectory (mapped to/Music-Station/medley-dropson your host) is where you should place your jingle files.These are short audio clips that Medley uses for various purposes.
Organize your jingles into the following subdirectories:
/Music-Station/medley-drops/ ├── intros/ │ ├── station_intro1.mp3 │ ├── station_intro2.wav │ └── ... ├── request_sweepers/ │ ├── request_intro1.mp3 │ ├── user_pick.wav │ └── ... └── jingles/ ├── to_blue/ │ ├── transition_to_blue1.mp3 │ ├── mood_shift_blue.wav │ └── ... ├── blue_to_easy/ │ ├── blue_to_easy1.mp3 │ ├── relaxing_transition.wav │ └── ... ├── blue_to_up/ │ ├── blue_to_upbeat1.mp3 │ ├── mood_lift.wav │ └── ... ├── to_up/ │ ├── transition_to_upbeat1.mp3 │ ├── energy_boost.wav │ └── ... ├── from_up/ │ ├── from_upbeat1.mp3 │ ├── cool_down.wav │ └── ... └── fresh/ ├── new_release_intro1.mp3 ├── fresh_track.wav └── ...-
intros/: This directory contains station intro jingles.These are typically played at the start of a session to identify your station/profile.
-
request_sweepers/: This directory contains jingles to be inserted before playing tracks requested by users. -
jingles/: This directory contains jingles used for transitioning between music collections.The subdirectories represent different transition types:
-
to_blue/: Transitions to blue moods -
blue_to_easy/: Transitions from blue to relaxed moods -
blue_to_up/: Transitions from blue to upbeat moods -
to_up/: Transitions to upbeat or energetic moods -
from_up/: Transitions from upbeat moods to other styles -
fresh/: Jingles for introducing new or fresh tracks
-
-
Create a file named config.yml in your Medley setup directory (/Music-Station/medley/config.yml /app/config.yml) and use the following as a template:
# yaml-language-server: $schema=https://raw.githubusercontent.com/seamless-medley/medley/refs/heads/main/packages/radio/medley-schema.json
db:
driver: mongodb
url: mongodb://mongo:27017
database: medley
connectionOptions:
auth:
username: root
password: example
stations:
default:
name: My Station
description: Various genres
musicCollections:
brokenhearted:
description: Broken Hearted
paths:
- /data/musics/brokenhearted
chill:
description: Chill
paths:
- /data/musics/chill
lonely:
description: Lonely
paths:
- /data/musics/lonely
lovesong:
description: Love Song
paths:
- /data/musics/lovesong
joyful:
description: Joyful
paths:
- /data/musics/joyful
upbeat:
description: Upbeat
paths:
- /data/musics/upbeat
new-released:
description: New Released
paths:
- /data/musics/new-released
disableLatch: true
noFollowOnRequest: true
thai:
auxiliary: true
description: Thai
paths:
- /data/musics/thai
profiles:
default:
name: Default profile
intros:
- /data/drops/intros
requestSweepers:
- /data/drops/request_sweepers
sequences:
# Randomly select this crate to play tracks from `new-released`, limited by one of [1, 1, 1, 2]
- chance: random
collections:
- id: new-released
limit:
by: one-of
list: [1, 1, 1, 2]
# This crate always play up to 2 tracks from `joyful`
- collections:
- id: joyful
limit:
by: upto
upto: 2
# This crate has 2/6 chance of being selected, play 1-2 tracks from `upbeat`
- chance:
yes: 2
no: 4
collections:
- id: upbeat
limit:
by: range
range:
min: 1
max: 2
# This crate always play 2-3 tracks from `chill`
- collections:
- id: chill
limit:
by: range
range:
min: 2
max: 3
# This crate always play up to 2 tracks from `lovesong`
- collections:
- id: lovesong
limit:
by: upto
upto: 2
# A compound crate, always play a track from either `lonely` or `brokenhearted` (with weights)
- collections:
- id: lonely
weight: 1
- id: brokenhearted
weight: 0.5
limit:
by: upto
upto: 1
# This crate always play 1-2 tracks from `brokenhearted`
- collections:
- id: brokenhearted
limit:
by: range
range:
min: 1
max: 2
# This crate always play 1-2 tracks from `lonely`
- collections:
- id: lonely
limit:
by: range
range:
min: 1
max: 2
# This crate always play upto 2 tracks from `lovesong`
- collections:
- id: lovesong
limit:
by: upto
upto: 2
# This crate has 1/2 chance of being selected, play upto 2 tracks from `chill`
- chance:
yes: 1
no: 1
collections:
- id: chill
limit:
by: upto
upto: 2
sweeperRules:
- to:
- lonely
- brokenhearted
path: /data/drops/jingles/to_blue
- from:
- lonely
- brokenhearted
to:
- lovesong
- chill
path: /data/drops/jingles/blue_to_easy
- from:
- lonely
- brokenhearted
to:
- upbeat
- joyful
path: /data/drops/jingles/blue_to_up
- to:
- upbeat
- joyful
path: /data/drops/jingles/to_up
- from:
- upbeat
- joyful
path: /data/drops/jingles/from_up
- to:
- new-released
path: /data/drops/jingles/fresh
automatons:
medley:
botToken: 'YOUR_DISCORD_BOT_TOKEN'
clientId: 'YOUR_DISCORD_CLIENT_ID'Detailed explanation of the configuration:
-
Database
The MongoDB url and credentials.
-
Stations
The
stationsobject is a key/value pair for constructing radio stations. Each key represents a unique station, and its value contains the station's configuration.stations: default: name: My Station description: Various genres musicCollections: # ... collections defined here ... profiles: # ... profiles defined here ...
- You can define multiple stations by adding more key/value pairs under
stations. - Each station has its own set of music collections and profiles.
- You can define multiple stations by adding more key/value pairs under
-
Music Collections
Within each station,
musicCollectionsdefines the available music categories:musicCollections: brokenhearted: description: Broken Hearted paths: - /data/musics/brokenhearted # ... other collections ...
- Each collection corresponds to a subdirectory in your music folder.
- You can set special properties for collections
-
Please see configuration file documentations for more detail
-
Profiles
Each station can have multiple
profiles, which define how the music collections are played and transitioned:profiles: default: name: Default profile intros: - /data/drops/intros requestSweepers: - /data/drops/request_sweepers sequences: # ... sequences defined here ... sweeperRules: # ... sweeper rules defined here ...
- Profiles allow for different playback behaviors that users can select.
- Each profile defines its own set of sequences and sweeper rules.
-
Sequences
The
sequencesarray in each profile describes the order of playback and how many tracks should be played for each sequence step:sequences: - chance: random collections: - id: new-released limit: by: one-of list: [1, 1, 1, 2] # ... other sequences ...
- Each sequence can have a
chanceof being selected, allowing for variety in playback. -
collectionsspecifies which music collection(s) to choose from. -
limitdefines how many tracks to play.
- Each sequence can have a
After you've set up your configuration and run the Docker container, Medley will start up.
- Navigate to the directory containing your
docker-compose.yml - Start Medley and its associated services using Docker Compose:
docker-compose up -d
- View the logs to ensure Medley is starting up properly
docker-compose logs -f medley
Upon startup, you'll see some important information displayed in your console. Here's what to expect:

- To stop Medley and its associated services:
docker-compose down
Once Medley is running, you can access the web UI to listen to your radio stations.
Note
The web UI currently supports listening to stations.
Features for managing stations and browsing the music library will be available in future releases.
Accessing the Web UI:
-
Local access: If you're on the same machine as Docker, open your browser and go to:
http://localhost:3001 -
Remote access: If you're accessing from a different machine on your network:
http://<docker-host-ip>:3001Replace
<docker-host-ip>with your Docker host machine's IP address (e.g.,http://192.168.1.100:3001)
Port Configuration:
The web UI runs on port 3001 by default. This is configured in the ports section of the docker-compose.yml:
ports:
- 3001:3001If port 3001 is already in use on your host machine, you can change the host port (the first number) while keeping the container port (the second number) as 3001:
ports:
- 8080:3001 # Access via http://localhost:8080After Medley has started successfully, you'll need to add the Discord bot to your server. You only need to do this once per server.
Here's how to do it:
-
Look for the OAuth URL in Medley's log output:
Once Medley is running, scan the log output for a line tagged with "automaton".
It will contain an
Ready!that looks something like this:INFO: [automaton]-[<your_bot_name>] - Ready! Use this link to add the bot to your server: https://discord.com/api/oauth2/authorize?client_id=<your_client_id>&scope=bot+applications.commands&permissions=<some number> -
Open the URL in your web browser.
-
Authorize the bot and complete any additional verification steps.
-
Once completed, the Medley bot should appear in your Discord server's member list.
You can now interact with it using the slash commands, try /medley to see the available commands.
Important
Ensure you have the necessary permissions on the Discord server to add bots.
If you're not the server owner, you may need to ask for permission or have an administrator add the bot for you.
Medley now includes Spotify integration, allowing users to easily request songs or artists by sharing Spotify URLs in Discord.
This feature enhances the music discovery capabilities.
Important
Medley does not support playing music directly from Spotify.
This integration is solely for matching and requesting tracks that are already in your local music collection. Playing or downloading content directly from Spotify would violate their terms and conditions.
- Music files in your collection must have Spotify IDs embedded using custom tags:
- Use
SPOTIFY:TRACKtag for Spotify Track IDs - Use
SPOTIFY:ARTISTtag for Spotify Artist IDs
- Use
- Ensure your music files are properly tagged with Spotify IDs.
- Enable the Message Content Intent for your Discord bot, to allow messages reading.