Harmoniq is an automated playlist generator for your Plex Media Server, designed to bring the dynamic and personalized experience of streaming service playlists to your self-hosted music library. It leverages Plex's sonic analysis, your listening history, and (optionally) Last.fm data to create engaging, context-aware playlists that refresh automatically.
- "Harmoniq Flow" - Dynamic Time-Based Playlists:
- Generates a central playlist (default name: "Harmoniq Flow") that adapts its vibe throughout the day.
- Uses user-defined named periods (e.g., "Morning Focus," "Evening Chill") with configurable start times.
- Learned Vibe Augmentation: Analyzes your listening history for each period and dynamically augments the target mood/style, making playlists more personalized over time.
- Vibe & Familiar Anchors: Selects "Vibe Anchors" (discovery tracks matching the period's augmented vibe) and "Familiar Anchors" (from your history, compatible with the vibe).
- Sonic Adventure Bridging (Optional): Utilizes Plex's
sonicAdventurefeature to create sonically flowing paths between anchor tracks. - Sonic Expansion (Optional): Further expands the playlist with tracks sonically similar to selected seeds.
- Refinement Filters: Applies filters for minimum rating (includes unrated by default), recency (excludes recently played), and skip count.
- Sonic Sort (Optional): Can apply a greedy sonic sort for flow if
sonicAdventureis not used or as a final polish.
- Last.fm Integration (Optional):
- Creates "Last.fm Discovery" playlists based on derived recommendations (User Top Artists -> Similar Artists -> Top Tracks).
- Creates "Last.fm Global Charts" playlists.
- Continuous Operation & Scheduling:
- Runs as a persistent background service.
- "Harmoniq Flow" updates at the start of each user-defined period.
- Last.fm playlists update based on a configurable interval.
- Plex Support:
- Directly interacts with your Plex Media Server.
- Supports multiple Plex music libraries.
- Requires Plex Sonic Analysis to be enabled and completed for full "Harmoniq Flow" functionality (Moods, Styles, Sonic features).
- Configuration via YAML & Environment Variables:
- Primary configuration via a
config.yamlfile for structured settings. - Environment variables (and
.envfile) can be used for secrets and overrides.
- Primary configuration via a
- Dockerized: Easy deployment using Docker and Docker Compose.
- Dynamic Playlist Covers (Optional): Generates custom cover art for the "Harmoniq Flow" playlist based on the active period.
- (Planned) Missing Track Output, Other Playlist Types, Jellyfin Support.
- Docker & Docker Compose.
- Plex Media Server:
- Network accessible.
- Sonic Analysis enabled and run on your music libraries for full "Harmoniq Flow" features.
- Plex Token: Find your token here.
- (Optional) Last.fm Account & API Key: If using Last.fm features.
- API Key: Get one here.
- Your Last.fm Username.
-
Prepare Configuration:
- Copy
config.yaml.examplefrom the repository to a directory on your host (e.g.,./harmoniq-config/config.yaml). - Edit your
config.yamlto define your Plex server, music libraries,TIME_PERIOD_SCHEDULE, and other preferences. Seeconfig.yaml.examplefor all options and detailed comments. - Copy
.env.exampleto.envin your project root (or wheredocker-compose.ymlwill reside). Edit it to add yourPLEX_URL,PLEX_TOKEN, and any Last.fm credentials.
- Copy
-
Create
docker-compose.yml:version: '3.7' services: harmoniq: # Option 1: Use a pre-built image (replace with actual image path if published) # image: your_dockerhub_username/harmoniq:latest # Option 2: Build from local source build: context: . # Or ./src if your Dockerfile is in a 'src' subdirectory dockerfile: Dockerfile # Assuming Dockerfile is in the context path container_name: harmoniq restart: unless-stopped env_file: - .env # For secrets and top-level overrides volumes: # Mount your local config directory to /app/config inside the container - ./harmoniq-config:/app/config:ro # Mount as read-only # Optional: Mount a directory for fonts if you want to use custom fonts for covers # - ./my_fonts:/app/harmoniq/fonts:ro environment: # Tells Harmoniq where to find the YAML config inside the container - CONFIG_FILE_PATH=/app/config/config.yaml # Example of overriding a config value (LOG_LEVEL from YAML could be overridden here) # - LOG_LEVEL=DEBUG
-
Run:
- If building locally:
docker-compose build harmoniq(or letup --builddo it). - Start the service:
docker-compose up -d - View logs:
docker-compose logs -f harmoniq - Stop:
docker-compose stop harmoniq - Stop and remove:
docker-compose down
- If building locally:
Harmoniq uses a hierarchical configuration system:
- Environment Variables (highest precedence): Set directly in
docker-compose.ymlor loaded from the.envfile. Ideal for secrets and quick overrides. config.yaml(mounted into/app/config/config.yaml): For structured and detailed configuration of features, playlists, periods, etc. Seeconfig.yaml.examplefor the full structure and options.- Internal Python Defaults (lowest precedence): Defined in
src/harmoniq/config.py.
Key sections in config.yaml:
plex_url,plex_token,plex_music_library_namestimezonelastfm_api_key,lastfm_userfeatures: Toggle various functionalities likeenable_time_playlist,time_playlist.learn_from_history,time_playlist.use_sonic_adventure, etc.playlists: Define names, sizes, and specific parameters for "Harmoniq Flow" (time_flow), Last.fm playlists, etc. Includes refinement settings (min rating, recency, skips) and history integration parameters for "Harmoniq Flow".time_periods: A list defining your named day parts for "Harmoniq Flow", their start hours, and optional mood/style overrides. Example:time_periods: - name: "Morning" start_hour: 7 # criteria: # Optional: overrides Harmoniq's internal defaults for "Morning" # moods: ["Focused", "Productive"] # styles: ["Instrumental", "Electronic"] - name: "EveningChill" # Custom name start_hour: 20 criteria: moods: ["Relaxed", "Mellow"] styles: ["Jazz", "Acoustic"]
cover_settings: Configure playlist cover font, output path, and custom colors for different periods.log_level.
Refer to config.yaml.example for detailed comments on all options.
Once Harmoniq is running:
- It initializes and schedules jobs based on your configuration.
- The "Harmoniq Flow" playlist will update at the start of each period defined in
time_periods(fromconfig.yaml) orTIME_PERIOD_SCHEDULE_RAW_ENV. - Last.fm playlists update based on
run_interval_minutes. - Check your Plex server for the generated playlists (e.g., "Harmoniq Flow," "Last.fm Discovery"). Playlist covers for "Harmoniq Flow" will update if enabled.
See ROADMAP.md for planned features and development phases.
Contributions are welcome! Whether it's bug reports, feature suggestions, or code contributions:
- Please check for existing issues before opening a new one.
- Feel free to open an issue to discuss proposed changes.
- Submit pull requests against the
main(ordevelop) branch.
This project is licensed under the [CHOOSE A LICENSE - e.g., MIT License]. See the LICENSE file for details.
- Built with Python.
- Key libraries: python-plexapi, Requests, schedule, pytz.
- Thanks to Last.fm for their public API and Plex for the rich metadata accessible via Sonic Analysis.