Skip to content

Beta Testing

Wittawas Nakkasem edited this page Dec 29, 2025 · 13 revisions

Medley Beta Testing Guide

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.

Table of content

Getting Started

Prerequisites

Before you begin, ensure you have the following:

  1. Docker Engine or Docker Desktop

  2. A compatible system architecture:

    • x86_64
    • arm64
  3. 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
  4. MongoDB

    • You need to have a MongoDB instance running that Medley can connect to.
  5. 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.

Setting Up Medley with Docker Compose

We provide an example docker-compose.yml file that sets up both Medley and MongoDB. This is the recommended method for most users.

  1. Create a new directory for your Medley setup and navigate into it.

  2. Create a file named docker-compose.yml and 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-drops

WebRTC Configuration

Medley uses WebRTC (Web Real-Time Communication) for audio playback in web browsers.

The following environment variables allow you to configure the WebRTC connection settings.

MEDLEY_DEFAULT_RTC_IP

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

MEDLEY_DEFAULT_RTC_PORT

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 ports section
    • 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:9989 to 8888:8888

Prepare your music and jingles

This section shows an example of how the setup would look like, feel free to change what you see fit.

  • Music Collections:

    The /data/musics directory (mapped to /Music-Station/musics on 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/drops directory (mapped to /Music-Station/medley-drops on 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

Configure Medley

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 stations object 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.
  • Music Collections

    Within each station, musicCollections defines 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 sequences array 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 chance of being selected, allowing for variety in playback.
    • collections specifies which music collection(s) to choose from.
    • limit defines how many tracks to play.

Starting Medley

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

Web UI

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>:3001
    

    Replace <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:3001

If 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:8080

Adding the bot to your server

After 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:

  1. 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>
    
  2. Open the URL in your web browser.

  3. Authorize the bot and complete any additional verification steps.

  4. 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.

Spotify Integration

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.

Requirements for Spotify Integration:

  • Music files in your collection must have Spotify IDs embedded using custom tags:
    • Use SPOTIFY:TRACK tag for Spotify Track IDs
    • Use SPOTIFY:ARTIST tag for Spotify Artist IDs

Setting up Spotify Integration:

  1. Ensure your music files are properly tagged with Spotify IDs.
  2. Enable the Message Content Intent for your Discord bot, to allow messages reading.