diff --git a/Cargo.toml b/Cargo.toml index 4d6a6f5..4c0d284 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,93 +1,93 @@ [package] -name = "ncspot" -description = "ncurses Spotify client written in Rust using librespot, inspired by ncmpc and the likes." -exclude = ["images/**"] -version = "0.10.0" authors = ["Henrik Friedrichsen "] -repository = "https://github.com/hrkfdn/ncspot" +description = "ncurses Spotify client written in Rust using librespot, inspired by ncmpc and the likes." +edition = "2021" +exclude = ["images/**"] keywords = ["spotify", "ncurses", "librespot", "terminal"] license = "BSD-2-Clause" +name = "ncspot" readme = "README.md" -edition = "2021" +repository = "https://github.com/hrkfdn/ncspot" +version = "0.10.0" [badges] -maintenance = { status = "actively-developed" } +maintenance = {status = "actively-developed"} [dependencies] -clap = "3.2.5" chrono = "0.4" -reqwest = { version = "0.11", features = ["blocking", "json"] } +clap = "3.2.5" +clipboard = {version = "0.5", optional = true} crossbeam-channel = "0.5" -platform-dirs = "0.3.0" +dbus = {version = "0.9.5", optional = true} +dbus-tree = {version = "0.9.2", optional = true} fern = "0.6" futures = "0.3" +ioctl-rs = {version = "0.2", optional = true} lazy_static = "1.3.0" +libc = "0.2.124" librespot-core = "0.4.0" librespot-playback = "0.4.0" librespot-protocol = "0.4.0" log = "0.4.16" +pancurses = {version = "0.17.0", optional = true} +parse_duration = "2.1.1" +platform-dirs = "0.3.0" +rand = "0.8" +regex = "1" +reqwest = {version = "0.11", features = ["blocking", "json"]} serde = "1.0" +serde_cbor = "0.11.2" serde_json = "1.0" -tokio = { version = "1", features = ["rt-multi-thread", "sync", "time"] } +strum = "0.24.1" +strum_macros = "0.24.1" +tokio = {version = "1", features = ["rt-multi-thread", "sync", "time"]} tokio-stream = "0.1.9" toml = "0.5" unicode-width = "0.1.9" -dbus = { version = "0.9.5", optional = true } -dbus-tree = { version = "0.9.2", optional = true } -rand = "0.8" -clipboard = { version = "0.5", optional = true } -wl-clipboard-rs = { version = "0.6", optional = true } url = "2.2" -strum = "0.24.1" -strum_macros = "0.24.1" -regex = "1" -ioctl-rs = { version = "0.2", optional = true } -serde_cbor = "0.11.2" -pancurses = { version = "0.17.0", optional = true } -libc = "0.2.124" -parse_duration = "2.1.1" +wl-clipboard-rs = {version = "0.6", optional = true} [dependencies.rspotify] -version = "0.11.5" default-features = false features = ["client-ureq", "ureq-rustls-tls"] +version = "0.11.5" [dependencies.cursive] -version = "0.18.0" default-features = false +version = "0.18.0" [dependencies.notify-rust] -version = "4" default-features = false +version = "4" # Use dbus, which we already depend on, instead of zbus. features = ["d"] optional = true [features] -share_clipboard = ["clipboard"] -wayland_clipboard = ["wl-clipboard-rs"] # Support wayland clipboard - linux only -share_selection = ["clipboard", "wl-clipboard-rs"] # Use the primary selection for sharing - linux only alsa_backend = ["librespot-playback/alsa-backend"] +cover = ["ioctl-rs"] # Support displaying the album cover +default = ["share_clipboard", "pulseaudio_backend", "mpris", "notify", "pancurses_backend"] +mpris = ["dbus", "dbus-tree"] # Allow ncspot to be controlled via MPRIS API +notify = ["notify-rust"] # Show what's playing via a notification +pancurses_backend = ["cursive/pancurses-backend", "pancurses/win32"] +portaudio_backend = ["librespot-playback/portaudio-backend"] pulseaudio_backend = ["librespot-playback/pulseaudio-backend"] rodio_backend = ["librespot-playback/rodio-backend"] -portaudio_backend = ["librespot-playback/portaudio-backend"] +share_clipboard = ["clipboard"] # Share a link to the system clipboard +share_selection = ["clipboard", "wl-clipboard-rs"] # Use the primary selection for sharing - linux only termion_backend = ["cursive/termion-backend"] -pancurses_backend = ["cursive/pancurses-backend", "pancurses/win32"] -mpris = ["dbus", "dbus-tree"] -notify = ["notify-rust"] -cover = ["ioctl-rs"] -default = ["share_clipboard", "pulseaudio_backend", "mpris", "notify", "pancurses_backend"] +wayland_clipboard = ["wl-clipboard-rs"] # Support wayland clipboard - linux only [package.metadata.deb] +assets = [ + ["target/release/ncspot", "usr/bin/", "755"], + ["misc/ncspot.desktop", "usr/share/applications/", "644"], + ["README.md", "usr/share/doc/ncspot/README.md", "644"], +] depends = "$auto, pulseaudio" -section = "sound" -priority = "optional" extended-description = """\ ncurses Spotify client written in Rust using librespot. \ It is heavily inspired by ncurses MPD clients, such as ncmpc.""" license-file = ["LICENSE"] -assets = [ - ["target/release/ncspot", "usr/bin/", "755"], - ["misc/ncspot.desktop", "usr/share/applications/", "644"], - ["README.md", "usr/share/doc/ncspot/README.md", "644"], -] +priority = "optional" +section = "sound" diff --git a/README.md b/README.md index da74453..d4dfa62 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,12 @@ provide a simple and resource friendly alternative to the official client as well as to support platforms that currently don't have a Spotify client, such as the \*BSDs. -[![Search](/images/screenshot-thumb.png?raw=true)](/images/screenshot.png?raw=true) +Note that `ncspot` offers features that are legally incompatible with free Spotify +accounts. See [feature comparison](https://support.spotify.com/us/article/premium-plans/) +and [Spotify user guidelines](https://www.spotify.com/us/legal/user-guidelines/). +You **must** have an existing premium Spotify subscription to use `ncspot`. + +![Search Screen](images/screenshot-thumb.png) ## Table of Contents @@ -30,9 +35,12 @@ as the \*BSDs. - [On macOS](#on-macos) - [On Windows](#on-windows) - [On Linux](#on-linux) - - [Building a Debian Package](#building-a-debian-package) - [Build](#build) + - [Prerequisites](#prerequisites) + - [Compiling](#compiling) + - [Building a Debian Package](#building-a-debian-package) - [Audio Backends](#audio-backends) + - [Other Features](#other-features) - [Key Bindings](#key-bindings) - [Navigation](#navigation) - [Playback](#playback) @@ -55,7 +63,7 @@ as the \*BSDs. Measured using `ps_mem` on Linux during playback: | Client | Private Memory | Shared Memory | Total | -| ------- | -------------- | ------------- | ---------- | +|---------|----------------|---------------|------------| | ncspot | 22.1 MiB | 24.1 MiB | 46.2 MiB | | Spotify | 407.3 MiB | 592.7 MiB | 1000.0 MiB | @@ -79,101 +87,121 @@ scoop install ncspot ### On Linux -Requirements: +Your distribution may have packaged `ncspot` in its package repository. +If so, simply install using your distribution's package manager - it +is by far the easiest way. If not, you can build from source instead. +See [Build](#build). -- Rust +In case your package manager does not perform dependency resolution, +here are the runtime dependencies: + +- `dbus`, `libncurses`, `libssl` +- `libpulse` (or `portaudio`, if built using the PortAudio backend) +- `libxcb` (if built with the `clipboard` feature) +- `ueberzug` (if built with the `cover` feature) + +## Build + +### Prerequisites + +- A working [Rust installation](https://www.rust-lang.org/tools/install) - Python 3 (needed for building `rust-xcb` dependency) -- `libpulse-dev` (or `portaudio-dev`, if you want to use the PortAudio backend) -- `libncurses-dev` and `libssl-dev` -- `libdbus-1-dev` -- `libxcb` + development headers (for clipboard access) -- `pkg-config` -- A Spotify premium account -On Debian based systems you need following packages for development headers: +On Linux, you also need: +- `pkgconf` (or `pkg-config`) +- Development headers for the [aforementioned runtime dependencies](#on-linux) + - Debian and derivatives: + ```sh + sudo apt install libdbus-1-dev libncursesw5-dev libpulse-dev libssl-dev libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev + ``` + - Fedora: + ```sh + sudo dnf install dbus-devel libxcb-devel ncurses-devel openssl-devel pulseaudio-libs-devel + ``` + - Arch and derivatives: + ```sh + # headers are included in the base packages + sudo pacman -S dbus libpulse libxcb ncurses openssl + ``` -```bash -sudo apt install libncursesw5-dev libdbus-1-dev libpulse-dev libssl-dev libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev +### Compiling + +Compile and install the latest release with `cargo-install`: + +```sh +cargo install ncspot ``` -For Fedora, these dependencies are required: +Or clone and build locally: -```bash -dnf install pulseaudio-libs-devel libxcb-devel openssl-devel ncurses-devel dbus-devel +```sh +git clone https://github.com/hrkfdn/ncspot +cargo build --release +``` + +**You may need to manually set the audio backend on non-Linux OSes.** See +[Audio Backends](#audio-backends). + +For debugging, you can pass a debug log filename and pipe `stderr` to a file: + +```sh +RUST_BACKTRACE=full cargo run -- -d debug.log 2> stderr.log ``` #### Building a Debian Package -You can use `cargo-deb` create in order to build a Debian package from source. -Install it with: +You can also use `cargo-deb` to build a Debian package -```bash +```sh cargo install cargo-deb -``` - -Then you can build a Debian package with: - -```bash cargo deb ``` -You can find it under `target/debian`. - -## Build - -Install the latest `ncspot` release using: - -```bash -cargo install ncspot -``` - -Or build it yourself using: - -```bash -cargo build --release - -# NB: add these flags on Windows -cargo build --release --no-default-features --features rodio_backend,cursive/pancurses-backend -``` - -- Both approaches require a working [Rust installation](https://www.rust-lang.org/tools/install). -- For debugging, you can pass a debug log filename and log stderr to a file, - e.g. : - - ```bash - RUST_BACKTRACE=full cargo run -- -d debug.log 2> stderr.log - ``` +You can find the package under `target/debian`. ### Audio Backends By default `ncspot` is built using the PulseAudio backend. To make it use the PortAudio backend (e.g. for \*BSD or macOS) or Rodio backend (e.g. for -Windows), you need to recompile `ncspot` with the respective features: +Windows), you need to compile `ncspot` with the respective features: -```bash +```sh # PortAudio (BSD/macOS) -cargo run --no-default-features --features portaudio_backend,cursive/pancurses-backend +cargo build --release --no-default-features --features portaudio_backend,pancurses-backend # Rodio (Windows) -cargo run --no-default-features --features rodio_backend,cursive/pancurses-backend +cargo build --release --no-default-features --features rodio_backend,pancurses-backend ``` +### Other Features + +Here are some auxiliary features you may wish to enable: + +| Feature | Default | Description | +|-------------------|---------|--------------------------------------------------------------------------------------------| +| `cover` | off | Add a screen to show the album art. See [Cover Drawing](#cover-drawing). | +| `mpris` | on | Control `ncspot` via dbus. See [Arch Wiki: MPRIS](https://wiki.archlinux.org/title/MPRIS). | +| `notify` | on | Send a notification to show what's playing. | +| `share_clipboard` | on | Ability to copy the URL of a song/playlist/etc. to system clipboard. | + +Consult [Cargo.toml](Cargo.toml) for the full list of supported features. + ## Key Bindings The keybindings listed below are configured by default. Additionally, if you -run `ncspot` with MPRIS support, you may be able to use media keys to control +built `ncspot` with MPRIS support, you may be able to use media keys to control playback depending on your desktop environment settings. Have a look at the [configuration section](#configuration) if you want to set custom bindings. ### Navigation | Key | Command | -| :---------------- | :---------------------------------------------------------------------------- | +|-------------------|-------------------------------------------------------------------------------| | ? | Show help screen. | | F1 | Queue (See [specific commands](#queue)). | | F2 | Search. | | F3 | Library (See [specific commands](#library)). | -| F8 | Album Art (if compiled with the `cover` feature). | +| F8 | Album Art (if built with the `cover` feature). | | / | Open a Vim-like search bar (See [specific commands](#vim-like-search-bar)). | | : | Open a Vim-like command prompt (See [specific commands](#vim-like-commands)). | | Escape | Close Vim-like search bar or command prompt. | @@ -182,7 +210,7 @@ playback depending on your desktop environment settings. Have a look at the ### Playback | Key | Command | -| :---------------------------- | :------------------------------------------------------------- | +|-------------------------------|----------------------------------------------------------------| | Return | Play track or playlist. | | Space | Queue track or playlist. | | . | Play the selected item after the currently playing track. | @@ -194,29 +222,29 @@ playback depending on your desktop environment settings. Have a look at the | Shift+U | Update the library cache (tracks, artists, albums, playlists). | | < | Play the previous track. | | > | Play the next track. | -| F | Seek forward. | -| Shift+F | Seek forward with a 10-second step. | -| B | Seek backwards. | -| Shift+B | Seek backwards with a 10-second step. | -| - | Decrease volume by 1. | -| + | Increase volume by 1. | -| [ | Decrease volume by 5. | -| ] | Increase volume by 5. | +| F | Seek forward by 1 second. | +| Shift+F | Seek forward by 10 seconds. | +| B | Seek backward by 1 second. | +| Shift+B | Seek backward by 10 seconds. | +| - | Decrease volume by 1%. | +| + | Increase volume by 1%. | +| [ | Decrease volume by 5%. | +| ] | Increase volume by 5%. | | R | Toggle _Repeat_ mode. | | Z | Toggle _Shuffle_ state. | ### Context Menus -| Key | Command | -| :---------------------------- | :--------------------------------------------------------------------- | -| O | Open a detail view or context for the **selected item**. | -| Shift+O | Open a context menu for the **currently playing track**. | -| A | Open the **album view** for the selected item. | -| Shift+A | Open the **artist view** for the selected item. | -| M | Open the **recommendations view** for the **selected item**. | -| Shift+M | Open the **recommendations view** for the **currently playing track**. | -| Ctrl+V | Open the context menu for a Spotify link in your clipboard. | -| Backspace | Close the current view. | +| Key | Command | +|-------------------------------|-----------------------------------------------------------------------------------------------------------| +| O | Open a detail view or context for the **selected item**. | +| Shift+O | Open a context menu for the **currently playing track**. | +| A | Open the **album view** for the selected item. | +| Shift+A | Open the **artist view** for the selected item. | +| M | Open the **recommendations view** for the **selected item**. | +| Shift+M | Open the **recommendations view** for the **currently playing track**. | +| Ctrl+V | Open the context menu for a Spotify link in your clipboard (if built with the `share_clipboard` feature). | +| Backspace | Close the current view. | When pressing O: @@ -224,21 +252,23 @@ When pressing O: - If the _selected item_ **is** a track, it opens a context menu with: - "Show Artist" - "Show Album" - - "Share" + - "Share" (if built with the `share_clipboard` feature) - "Add to playlist" - "Similar tracks" ### Sharing -| Key | Command | -| :---------------------------- | :------------------------------------------------------------------------------ | -| X | Copy a shareable URL of the **currently selected item** to the system clipboard. | -| Shift+X | Copy a shareable URL of the **currently playing track** to the system clipboard. | +(if built with the `share_clipboard` feature) + +| Key | Command | +|-------------------------------|--------------------------------------------------------------------------| +| X | Copy the URL to the **currently selected item** to the system clipboard. | +| Shift+X | Copy the URL to the **currently playing track** to the system clipboard. | ### Queue | Key | Command | -| :--------------------------- | :----------------------------------- | +|------------------------------|--------------------------------------| | C | Clear the entire queue. | | D | Delete the currently selected track. | | Ctrl+S | Delete the currently selected track. | @@ -246,13 +276,13 @@ When pressing O: ### Library | Key | Command | -| :----------- | :-------------------------------------- | +|--------------|-----------------------------------------| | D | Delete the currently selected playlist. | ### Vim-Like Search Bar -| Key | Command | -| :----------- | :------------------------- | +| Key | Command | +|--------------|-----------------------------| | n | Previous search occurrence. | | N | Next search occurrence. | @@ -261,101 +291,125 @@ When pressing O: You can open a Vim-style command prompt using :, and close it at any time with Escape. -The following is an abridged list of commonly-used commands. For the full list, see [source code](/src/command.rs). +The following is an abridged list of the more useful commands. For the full list, see [source code](/src/command.rs). -| Command | Action | -|---|---| -| `help` | Show current key bindings. | -| `quit`
Aliases: `q`, `x` | Quit `ncspot`. | -| `logout` | Remove any cached credentials from disk and quit `ncspot`. | -| `playpause`
Aliases: `pause`, `toggleplay`, `toggleplayback` | Toggle playback. | -| `stop` | Stop playback. | -| `seek [+\|-]