A CLI tool to transfer, sync, and backup playlists on music streaming services

Overview

unitunes PyPI version example workflow

unituneslogo

A command-line interface tool to manage playlists across music streaming services.

demo

Introduction

unitunes manages playlists across streaming services. unitunes can transfer songs between services and keep playlists in sync.

unitunes stores your playlists in plain text, allowing you to version control your music. Playlists can be pushed and pulled from streaming services. Tracks from one service can be searched on another.

Current Supported Streaming Services

Name Pullable Pushable Searchable
MusicBrainz
Spotify
Youtube Music

Want to add support for another service? See contributing.

Documentation

Documentation

Quickstart

Installation

pip install unitunes

Initialize

unitunes init

This creates a config.json file in the current directory.

Add Services

Spotify

Follow the instructions at https://spotipy.readthedocs.io/en/2.19.0/#getting-started to obtain client credentials.

Put the credentials in a file like so:

{
  "client_id": "...",
  "client_secret": "...",
  "redirect_uri": "http://example.com"
}

Register the service in unitunes:

unitunes service add spotify spotify_config.json

Youtube Music

Follow the instructions at https://ytmusicapi.readthedocs.io/en/latest/setup.html#manual-file-creation to create a ytm_config.json file.

Register the service in unitunes:

unitunes service add ytm ytm_config.json

Add Playlists

Initialize UP's from your existing playlists:

unitunes fetch spotify # use -f to skip confirmation
unitunes fetch ytm

Pull Playlists

Pull all tracks from all playlists.

unitunes pull

Search Playlists

Search for tracks on another service:

unitunes search SERVICE_TYPE PLAYLIST_NAME

Push Playlists

Push all changes to streaming services:

unitunes push

Contributing

unitunes is in alpha. Contributions are very welcome. I am looking for collaborators to grow unitunes into a foundation for user controlled music software.

Take a look at the open issues!

Development Setup

  1. Fork and clone the repository.
  2. Install poetry.
  3. In the root directory, run poetry shell.
  4. Run poetry install.
  5. unitunes should now be runnable.

Testing

Run pytest to run tests. With no arguments, it will skip tests that require service configs.

Add a service config to run more tests.

pytest --spotify spotify_config.json --ytm ytm_config.json # may need to run with -s to paste spotify redirect URL the first time
Comments
  • Issue when opening app

    Issue when opening app

    When I try to open unitunes at the command line, I get the following message:

    Traceback (most recent call last): File "/home/xxxxxxxxx/.local/bin/unitunes", line 5, in from gui.main import main ModuleNotFoundError: No module named 'gui'

    Do I not have something installed? Am I missing something? Thanks

    opened by SteveH0401 4
  • Fix installation and startup on Windows

    Fix installation and startup on Windows

    • platformdirs is a dependency, but was not listed in pyproject.toml
    • mkdir failed for the config directory on Windows as user_data_dir returns two levels of directories by default
    opened by johan12345 1
  • fix spotify search?

    fix spotify search?

    I am currently trying to copy a playlist from Youtube Music to Spotify and getting no matches for any track in that playlist, even though I know that they exist on Spotify. I noticed that the Spotify search query always includes a formatted output for the AliasedString object such as track:"value='Some song' aliases=[]" instead of just the track name 'Some Song (track.name.value). Does the Spotify API actually support this pattern? I couldn't find any example of this in the docs. If I try to just pass track.name.value, as implemented in this PR, I get at least 2 matches for my playlist.

    I also noticed that Spotify seems to be very picky about search queries - if a track has multiple artists listed on Spotify, but we only know one of them from YTM, Spotify cannot find it. So maybe the query generator should also generate a query that omits the artist as a fallback?

    opened by johan12345 1
  • Formalize service configs

    Formalize service configs

    Currently service configs are parsed from json into dicts.

    Create classes for service configs. Provides type safety and clearly shows which options exist.

    opened by platers 1
  • Spotify query generator improvements

    Spotify query generator improvements

    This adds a couple of query variants to the Spotify query generator. This fixed search for a couple of tracks from my YouTube Music playlists that could previously not be matched to Spotify (mainly classical music, where e.g. the composer is sometimes listed as part of the track title on YouTube, while it's usually in the artist field on Spotify).

    see also #2

    opened by johan12345 0
  • GUI

    GUI

    Implements #13.

    Migrates unitunes from a CLI to a GUI. The GUI should make the tool accessible to more people. For programmatic control use the unitunes library.

    opened by platers 0
  • Change to spotify.py authorization scope to allow lists of playlists to be read

    Change to spotify.py authorization scope to allow lists of playlists to be read

    Found when I fetched the Spotify playlists, it only added the "Liked Songs" playlist to unitunes. After adding the "playlist-read-private" or "playlist-read-collabrative" scopes, I was able to read my list of Spotify playlists.

    opened by SteveH0401 0
  • SpotifyException: spotipy.exceptions.SpotifyException

    SpotifyException: spotipy.exceptions.SpotifyException

    When I try to search YTMusic's playlist on Spotify as: unitunes search spotify 'Your Likes'

    I get the following exception:
    ....
        raise SpotifyException(
    spotipy.exceptions.SpotifyException: http status: 404, code:-1 - https://api.spotify.com/v1/search?q=track%3A%22value%3D%27Me+%26+My+Friends+%28feat.+Fortune%29%27+aliases%3D%5B%5D%22+artist%3A%22Munn+%26+Jude.%22+album%3A%22Me+%26+My+Friends+%28feat.+fortune%29%22&limit=5&offset=0&type=track:
     Not found., reason: None
      3%|████                                                                                                                                                 | 17/619 [00:03<02:15,  4.43it/s]
    

    I guess, if the song is not found on Spotify then this exception gets raised and if so, then the exception should be caught as sound not found and continue the search for next songs in the playlist.

    If that's not it, then please help get the error solved. Thanks for the great tool, cheers!

    opened by pushp1997 0
  • A little unsure on how to use this

    A little unsure on how to use this

    After running the command in powershell (admin) it installs into "AppData\Local\Programs\Python\Python310\Scripts" but trying to run unitunes just closes it. Is there something I'm missing that I need to run this?

    opened by LadyHaywood 0
  • How to sink playlists between YTM and spotify

    How to sink playlists between YTM and spotify

    I have a spotify playlist with 140 ish songs and ytm with 1800+ How do I sync them. When I press Sync All it just pushes and pulls but my spotify playlist still has the same number of songs. I am probably missing something, could someone help me out?

    uni

    opened by Kshitij841 0
  • YouTube Music Playlist Pull Error - NoneType object is not iterable

    YouTube Music Playlist Pull Error - NoneType object is not iterable

    ENV: Win10, 21H2, Python: 3.10.2

    1. Configure
    • Unitunes directory
    • Added YouTube service with Request Headers
    • Added Playlist (https://music.youtube.com/playlist?list=LM)
    1. Attempted to Pull configured playlist
    2. Error: 'NoneType' object is not iterable
    3. Stacktrace:
    Job 0 failed: 'NoneType' object is not iterable
    Traceback (most recent call last):
      File "C:\Users\johndeo\AppData\Local\Programs\Python\Python310\lib\site-packages\unitunes\gui\engine.py", line 109, in _process_queue
        job.execute()
      File "C:\Users\johndeo\AppData\Local\Programs\Python\Python310\lib\site-packages\unitunes\gui\engine.py", line 66, in execute
        self.pm.pull_playlist(
      File "C:\Users\johndeo\AppData\Local\Programs\Python\Python310\lib\site-packages\unitunes\main.py", line 209, in pull_playlist
        remote_tracks = service.pull_tracks(uri)
      File "C:\Users\johndeo\AppData\Local\Programs\Python\Python310\lib\site-packages\unitunes\services\ytm.py", line 139, in pull_tracks
        return self.results_to_tracks(tracks)
      File "C:\Users\johndeo\AppData\Local\Programs\Python\Python310\lib\site-packages\unitunes\services\ytm.py", line 127, in results_to_tracks
        return list(
      File "C:\Users\johndeo\AppData\Local\Programs\Python\Python310\lib\site-packages\unitunes\services\ytm.py", line 171, in raw_to_track
        artists=[AliasedString(value=artist["name"]) for artist in raw["artists"]],
    TypeError: 'NoneType' object is not iterable
    Finished job 0: Pull Your Likes
    
    
    opened by wisefella 0
  • Error while running unitunes on windows 11

    Error while running unitunes on windows 11

    My environment

    • Python version: Python 3.10.7
    • OS: Windows 11
    • unitunes version I tried: 2.0.1 and 2.0.0

    Steps to reproduce:

    1. pip install unitunes without administrator privileges
    2. unitunes

    Problem:

    Error: ModuleNotFoundError: No module named 'platformdirs'

    Things I did to solve the issue:

    install platformdirs using pip. After doing that another error appears complaining about a directory not being created. "C:\Users%USER%\AppData\Local\unitunes" after creating it manually it solves de issue.

    opened by xenizs 2
  • Consider keeping the CLI?

    Consider keeping the CLI?

    It seems that the CLI was removed (8a8b2caed2c4f333950109ad553af185879add6d) in version 2.0.0 in favor of the new GUI. I think it would still be nice to have a CLI available, e.g. for running unitunes as part of a cron job. What do you think?

    opened by johan12345 2
  • Support a different YouTube playlist URL

    Support a different YouTube playlist URL

    First of all, thank you for this great piece of software.

    I couldn't get the right YT playlist URL format at first, then I noticed the supported URL format is different. The one I got from my address bar when browsing is as follows:

    https://music.youtube.com/browse/<playlist-id>
    

    Alternatively, as we have to specify the service anyway, wouldn't it be better if we just enter the playlist ID?

    opened by Sinderella 2
Owner
Victor Tao
Building tools. Previously @uoft, @google, @microsoft
Victor Tao
Python script to backup/convert your Spotify playlists into the XSPF format.

Python script to backup/convert your Spotify playlists into the XSPF format.

Chris Ovenden 4 Jun 9, 2022
Implement backup and recovery with AWS Backup across your AWS Organizations using a CI/CD pipeline (AWS CodePipeline).

Backup and Recovery with AWS Backup This repository provides you with a management and deployment solution for implementing Backup and Recovery with A

AWS Samples 8 Nov 22, 2022
EzilaX Music ❤ is the best and only Telegram VC player with playlists, Multi Playback, Channel play and more POWERD By SDBOTs

EzilaX-Music ?? A bot that can play music on Telegram Group and Channel Voice Chats Available on telegram as @EzilaXMBot Features ?? Thumbnail Support

Sadew Jayasekara 9 Oct 24, 2021
TG-Streaming-bot - TG Simple Streaming bot

TG Simple Streaming bot telegram video straming bot ??️ Features Play youtube li

HyDrix 4 May 5, 2022
veez music bot is a telegram music bot project, allow you to play music on voice chat group telegram.

?? Veez Music Bot Music bot for playing music on telegram voice chat group. Requirements ?? FFmpeg NodeJS nodesource.com Python 3.7+ PyTgCalls ?? Get

levina 143 Jun 19, 2022
veez music is a telegram music bot project, allow you to play music on voice chat group telegram.

?? VEEZ MUSIC BOT Veez Music is a telegram bot project that's allow you to play music on telegram voice chat group. Requirements ?? FFmpeg NodeJS node

levina 23 Aug 29, 2021
ELiza music is a telegram music bot project, allow you to play music on voice chat group telegram.

❤️ ?????????? ?????????? ❤️ Unmaintained. The new repo of @MrsElizaRobot is private. (It is no longer based on this source code. The completely rewrit

Team Eliza 2 Dec 8, 2022
Video-Player - Telegram Music/ Video Streaming Bot Using Pytgcalls

Video Player ?? ᴢᴀɪᴅ ᴠᴄ ᴘʟᴀyᴇʀ ɪꜱ ᴀ ᴛᴇʟᴇɢʀᴀᴍ ᴘʀᴏᴊᴇᴄᴛ ʙᴀꜱᴇᴅ ᴏɴ ᴘʏʀᴏɢʀᴀᴍ ꜰᴏʀ ᴘʟᴀʏ

Zaid 16 Nov 30, 2022
A Telegram bot to download youtube playlists and upload them to telegram. (may be slow becoz youtube limitations)

YTPlaylistDL ?? A Telegram bot to download youtube playlists and upload them to telegram. (may be slow becoz youtube limitations) ?? Follow me and sta

Anjana Madu 43 Dec 28, 2022
A Python script to create customised Spotify playlists using the JSON, Spotipy Library and Spotify Web API, based on seed tracks in your history.

A Python script to create customised Spotify playlists using the JSON, Spotipy Library and Spotify Web API, based on seed tracks in your history.

Youngseo Park 1 Feb 1, 2022
A smart tool to backup members 📈 So you even after a raid/ ban you can easily restore them in seconds 🎲

?? Discord-backer ?? A open-source Discord member backup and restore tool for your server. This can help you get all your members in 5 Seconds back af

John 29 Dec 21, 2022
Sync mastodon toot and Telegram channel or group in both direction.

Sync mastodon toot and telegram channel or group in both direction.

Littlebear0729 7 Dec 18, 2022
It's a simple python script to take backup of directories (compressing) then the same to move your mentioned S3 bucket with the help of AWS IAM User.

Directory Backup Moved to S3 (Pyscript) Description Here it's a python script that needs to use this script simply create a directory backup and moved

Yousaf K Hamza 3 Mar 4, 2022
Confirm that files have been uploaded to Backblaze Cloud Backup successfully

Backblaze Backup Checker This Python script compares metadata captured from files within source folders against data parsed from Backblaze Cloud Backu

null 18 Jul 29, 2022
API Basica per a synologys Active Backup For Buissiness

Synology Active Backup for Business API-NPP Informació Per executar el programa

Nil Pujol 0 May 13, 2022
A Python script to backup all repos (public or private) of a user.

GithubBackupAllRepos A Python script to backup all repos (public or private) of a user. Features Clone public and private repos Load specified SSH key

Podalirius 15 Jan 3, 2023
JAKYM, Just Another Konsole YouTube-Music. A command line based Youtube music player written in Python with spotify and youtube playlist support

Just Another Konsole YouTube-Music Overview I wanted to create this application so that I could use the command line to play music easily. I often pla

Mayank Jha 73 Jan 1, 2023
A Telegram Music Tag Editor Bot that can remove almost all usernames in the music tags and add own username instead.

Music Tag Editor Bot A Telegram Music Tag Editor Bot that can remove almost all usernames in the music tags and add own username instead. It can also

null 14 Oct 21, 2022
A simple worker for OpenClubhouse to sync data.

OpenClubhouse-Worker This is a simple worker for OpenClubhouse to sync CH channel data.

null 100 Dec 17, 2022