Skip to content

Beta Testing

Wittawas Nakkasem edited this page Oct 9, 2024 · 11 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: always
    depends_on:
      - mongo
    environment:
      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

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

# This is for the future use, but must be defined
server:
  port: 3001

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

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 "OAuthURL" that looks something like this:

    INFO: [automaton]-[<your_bot_name>] - OAUthURL: 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.