subsonic-cli.md (6095B)
1 # Command-line interfaces for self-hosted music 2 3 <time id="post-date">2023-09-28</time> 4 5 <p id="post-excerpt"> 6 Self-hosting a music server is great. 7 Listening to the tunes via the command line is the way. 8 </p> 9 10 ## Subsonic-compatible server backbone 11 12 I have [Navidrome](https://www.navidrome.org/) installed (via Docker on NixOS). 13 It's very nice. 14 15 With a reverse proxy, [tailscale](https://tailscale.com/), and LetsEncrypt set up, 16 I can access it via any Subsonic-compatible music player at 17 <https://music.beauslab.casa> 18 (this URL is available only on my tailnet, so it will 404 for everyone else). 19 20 21 ## Desktop GUI interfaces 22 23 [Sublime-music](https://sublimemusic.app/) is pretty good. 24 I also often find myself using the Navidrome web UI. 25 26 (On mobile, [Symfonium](https://symfonium.app/) (paid) or [SubStreamer](https://substreamerapp.com/) on Android 27 and [play:Sub](http://michaelsapps.dk/playsubapp/) (paid) or [SubStreamer](https://substreamerapp.com/) on iOS are my go-tos, 28 though there are many [others](http://www.subsonic.org/pages/apps.jsp)) 29 30 ## CLI interfaces: contenders (STMP, jellycli, sksonic) 31 32 If I'm in programming mode, 33 I prefer command-line interfaces, 34 particularly if they let me use keyboard muscle-memory (i.e. vi bindings). 35 36 As such, I tried a few CLI front-ends to access and play my Navidrome-served tunes. 37 38 I'm sure there are others. 39 40 [STMP](https://github.com/wildeyedskies/stmp/tree/main) 41 is clean and works well, but doesn't have vi bindings yet. 42 43 [jellycli](https://github.com/tryffel/jellycli/tree/master) is the most polished, 44 and uses vi bindings, 45 but even so the in-app nav is finicky and doesn't quite fit my brain 46 (though that might be mostly due to conflicts with other terminal keybindings I have set up). 47 48 [sksonic](https://gitlab.com/yvelon/sksonic) is a suckless-style implementation in C, e.g. edit config.h and recompile. 49 It works, but isn't polished enough for daily usage 50 (though I don't expect it to be - the author states it's a personal project, 51 and I think they're doing a great job, so will keep an eye on it). 52 Partial vi-key support, could easily be added given the suckless style. 53 54 55 ## CLI interfaces: the one I picked (ncmpcpp with mopidy backend) 56 57 After these, I found myself wishing that I could use [ncmpcpp](https://github.com/ncmpcpp/ncmpcpp) and hook it up to my Subsonic back end. 58 59 And then I realized: 60 hey, this is a Linux TUI, 61 and ncmpcpp is just a front-end for [mpd](https://www.musicpd.org/), 62 of course you can switch out mpd for something that's Subsonic-aware. 63 64 ncmpcpp is beautiful, polished, fast, with great vi-key support, and I've been using it for years for local music playback. 65 66 [mopidy](https://mopidy.com/) is a fairly drop-in mpd replacement that is pluggable, 67 with a number of awesome [extensions](https://mopidy.com/ext/). 68 69 I should have looked here first. C'est la vie. 70 71 I perused a few blog posts to get a sense of what to do: 72 - [fsylum's post](https://fsylum.net/blog/setting-up-ncmpcpp-mopidy-spotify-arch-linux/) 73 - [Deepjyoti Barman's post](https://blog.deepjyoti30.dev/using-spotify-with-ncmpcpp-mopidy-linux) 74 - [Digital Neanderthals' post](https://www.digitalneanderthal.com/post/ncmpcpp/) (what a great online moniker, well done - his physical setup is also a delight, sheer cyberdeck practicality) 75 76 It's pretty easy. 77 78 The rad thing is that you can get a unified frontend for all your sources, 79 e.g. Subsonic, Spotify, local files, YouTube, SoundCloud, etc., 80 just install a plugin and add a config section and you're off to the races, 81 never having to leave the terminal. 82 83 84 > Source selection (could have many more items here). 85 86 ![Source selection](/images/ncmpcpp-mopidy-selector.png) 87 88 89 > Artist selection. 90 91 ![Preview](/images/ncmpcpp-mopidy-full.png) 92 93 94 > Track view. 95 96 ![Track view](/images/ncmpcpp-mopidy-tracks.png) 97 98 99 ## Set up 100 101 ### Install the things 102 103 My main laptop still runs Arch (btw). 104 If I ever switch to NixOS on this machine, 105 or add this setup to the NixOS server, 106 I'll probably make a new post with the Nix way to do this. 107 I bet it's hardly different, other than the `.nix` files. 108 109 e.g. `paru -S ncmpcpp mopidy mopidy-subidy mopidy-mpd` 110 111 Also uninstall and stop mpd, if you're using it. 112 113 ### Config files 114 115 (most of the what's in the files below is unnecessary for this post, 116 but I've never been mad that someone posted their whole config) 117 118 (also note that the mopidy config file doesn't allow # comments, 119 I just used them for ease of reading with syntax highlighting, 120 will have to delete prior to actually using) 121 122 `~/.config/ncmpcpp/config` 123 124 ```sh 125 ncmpcpp_directory = ~/.config/ncmpcpp 126 lyrics_directory = ~/.config/lyrics 127 128 progressbar_look = -> 129 display_volume_level = no 130 131 autocenter_mode = yes 132 message_delay_time = 1 133 134 playlist_display_mode = columns 135 playlist_editor_display_mode = columns 136 browser_display_mode = columns 137 138 media_library_primary_tag = album_artist 139 media_library_albums_split_by_date = no 140 141 ignore_leading_the = yes 142 ignore_diacritics = yes 143 external_editor = vim 144 use_console_editor = yes 145 ``` 146 147 `~/.config/mopidy/mopidy.conf` 148 149 ```sh 150 [core] 151 cache_dir = $XDG_CACHE_DIR/mopidy 152 config_dir = $XDG_CONFIG_DIR/mopidy 153 data_dir = $XDG_DATA_DIR/mopidy 154 max_tracklist_length = 10000 155 restore_state = true 156 157 [file] # might switch out for mopidy-local at some point, adds search support via sqlite metadata archive 158 enabled = true 159 media_dirs = 160 ~/media/tunes 161 excluded_file_extensions = 162 .directory 163 .html 164 .jpeg 165 .jpg 166 .log 167 .nfo 168 .pdf 169 .png 170 .txt 171 .zip 172 show_dotfiles = false 173 follow_symlinks = false 174 metadata_timeout = 1000 175 176 [m3u] 177 playlists_dir = $XDG_CONFIG_DIR/mopidy/playlists 178 179 [mpd] 180 enabled = true 181 hostname = 127.0.0.1 182 port = 6600 # defaults ftw - no change to ncmpcpp config needed if defaults are kept 183 max_connections = 20 184 connection_timeout = 60 185 186 [subidy] 187 enabled = true 188 url = https://music.beauslab.casa 189 username = admin 190 password = admin # behind a tailnet anyway, come at me bro 191 api_version = 1.16 192 ``` 193 194 ## Future goals 195 196 - snapcast for whole-house audio ([Reddit post](https://www.reddit.com/r/selfhosted/comments/icjmiq/a_music_server_with_a_tli_client/) with some good tips)