Update 2022
ultrasonics is not depricated, but I don't have as much time as I'd like to work on developing it. I plan to get back to it in the future, I hope you can bear with me! An important upcoming update is regarding ultrasonics-api. I'm currently hosting a public version on Heroku free tier, which is shutting down at the end of November 2022 as announced back in August. It's needed for any public streaming services (Spotify, Last.fm, etc).
I don't have any alternative set up yet, so before that time comes I urge you to set up your own ultrasonics-api instance alongside ultrasonics, and keys for any online services you want to sync with. The instructions are all available over on that repo!
Overview
Installation
systemd
Option 1 (Manual Install)
Option 2 (Docker)
Applets
Inputs
Modifiers (Optional)
Outputs
Triggers
Plugins
Playlists Mode vs Songs Mode
Contributing
Writing Your Own Plugin
Improving ultrasonics Source Code
Welcome to ultrasonics!
ultrasonics is a tool designed to help you take control of your music library and music playlists. Gone are the days of having your playlists scattered across three different services, or being limited to using one service because you don't have the time to manually curate multiple copies of the same playlist.
ultrasonics uses plugins to interact with your favourite services. This means that functionality can be added by simply installing a new plugin. Each plugin may provide compatibility with a service, e.g. the official Spotify plugin links up to... well, Spotify of course. Other plugins provide additional functionality, such as merging playlists from more than one source.
The overview of all included plugins can be found at [documentation incomplete].
To run ultrasonics you have two options:
Download and run ultrasonics directly.
Pull and run the official docker image.
ultrasonics was developed on Linux. It should be cross-platform compatible, but it's not been tested so be ready for bugs or issues on Windows / macOS!
Make sure you have Python 3 installed
# If this command doesn't work, install Python 3callum at uluru in ~↪ python3 --version Python 3.8.2
Clone the repo to an install directory, maybe /opt/ultrasonics
# Move to your install directorycallum at uluru in ~↪ cd /opt# Clone this repocallum at uluru in /opt ↪ git clone https://github.com/XDGFX/ultrasonics# Make sure you have ownership of the ultrasonics foldercallum at uluru in /opt ↪ sudo chown -R callum:callum ultrasonics/
Create a virtual environment, and install the required dependencies inside it.
# Move into the ultrasonics directorycallum at uluru in /opt ↪ cd ultrasonics# Create a virtual environment in the folder '.venv'callum at uluru in /o/ultrasonics ↪ python3 -m venv .venv# Activate the environment.# If you're using a different shell use activate.<shell># e.g. source .venv/bin/activate.fish for fish!callum at uluru in /o/ultrasonics ↪ source .venv/bin/activate# Ensure your venv is active (see the .venv at the start of the line)# Install the Python dependenciescallum at uluru in /o/ultrasonics (.venv) ↪ pip3 install -r requirements.txt
Run app.py
# With the venv still active, run app.pycallum at uluru in /o/ultrasonics (.venv) ↪ python3 app.py
If you want to run this as a systemd process, follow the steps below:
Copy the example service file to /etc/systemd/system/ultrasonics.service
sudo cp ultrasonics.service /etc/systemd/system/ultrasonics.service
Reload the systemctl daemon to pick up the new service
sudo systemctl daemon-reload
Enable and start the service
sudo systemctl enable --now ultrasonics
You can check the status of the process using:
systemctl status ultrasonics
The official ultrasonics image is located at xdgfx/ultrasonics. You can pull and run it manually, or stick it in your docker-compose.yml
file.
version: "3.7"services: ultrasonics:image: xdgfx/ultrasonicscontainer_name: ultrasonicsrestart: unless-stoppedports: - 5000:5000volumes: - /path/to/config:/config - /path/to/plugins:/plugins # Used for third-party pluginsenvironment: - PUID=${PUID} - PGID=${PGID}
If you've ever used IFTTT you already understand the fundamentals. ultrasonics works with the concept of 'applets'. Each applet you create contains plugins which fit into one of four categories:
These plugins connect to a service to get a list of songs or playlists, and pass that list onto the Modifiers and Output plugins.
These plugins take a list of songs or playlists from one or more input plugins, and modify the list in some way. For example, they may merge duplicate playlists, or replace the songs with similar songs using a music discovery api.
These plugins take the list of playlists passed to them, and save them to a service. Maybe they update or create your playlists in Plex, or save them to a .m3u file on your home server.
These plugins aren't part of the songs / playlist flow, but instead determine when the applet actually runs. The most simple trigger is time-based, e.g. 'Run once every 6 hours'.
You can build your custom applets using the installed plugins, save it to the database, and then it will run automatically from a Trigger plugin, or by manually running the applet from the homepage.
ultrasonics comes bundled with several official plugins. For more info, see [documentation incomplete].
New plugins can be installed by simply copying the plugin containing folder into the plugins
directory.
Each applet needs at least one input and one output plugin. To run automatically, it also needs at a trigger plugin.
Most plugins will have settings to configure, which could be global persistent settings (common for all instances of the plugin, across all your applets), or specific for this instance of the plugin.
You will be prompted to enter any required settings when you are building your applet.
Settings can always be left blank! In some cases, this is fine or expected, however in other cases this can result in plugin errors which might require manual fixing of the ultrasonics database! Make sure you fill out any settings you are supposed to!
Some plugins are designed to work with playlists - e.g. the Spotify plugin interacts with your Spotify playlists. Some plugins are designed to work with songs, e.g. your top 100 songs on Last.fm.
If a plugin only works in songs-mode, a warning will be displayed on the "select plugin" screen.
Adding a songs-mode plugin to an input will effectively work by adding a single playlist to the applet flow. This should work without an issue, as long as the plugin in question provides a name for this single playlist.
Trying to feed multiple playlists into a single songs-mode output plugin will likely cause issues, it's not recommended.
So you want to help improve ultrasonics? First of all - thank you! As someone who is not a software engineer, this is one of the biggest projects I've worked on. Any help or suggestions are greatly appreciated!
Expanding on the functionality of ultrasonics is easy! A plugin is a drag-and-drop installation, and so can greatly improve the project with minimal complexity. The best way to learn is through the wiki. You can fork this project, or create your own repo specifically for your plugin. It can be kept separate, or if you feel it would benefit the community by making if a default plugin, let me know through a GitHub issue!
I will put any future plans, known issues, or general improvements in the issues. Also have a look at the projects boards, which should show the issues that are high priority.
Or, if you have a new idea, give it a go and let me know with a pull request or issue! ?