Dead-simple queue-oriented client for Spotify

Overview

Spotiqueue

A terribly simple macOS app for keyboard-based, queue-oriented Spotify use. Many years ago i built a version which relied on a now-deprecated library — Spotify doesn't publish libspotify any more, which is a shame. The old Spotiqueue is archived for posterity; this version does pretty much exactly the same as the old one did, and more, although i'd like to think it's a bit more refined.

Spotiqueue now also has the GNU Guile extension language built in: this means you can extend its behaviour with arbitrary Scheme! More details below. Beware of rough edges. Scratches my itch, no other guarantees granted.

Obligatory screenshot to give an idea what the app does.

Usage, a crash course

Spotiqueue is intended to be keyboard-driven. As such, you may be surprised that clicking and dragging doesn't work. Read on for instructions!

The left-hand pane is your queue of tracks to be played. The top track is next, and once it has started playing, it's removed from the queue. The right-hand pane is for search results.

  • Searching: To search, enter text (such as britney spears or sandstorm) into the search field, and press (Return, Enter, whatever you call it). This will focus the search results pane and tracks matching your query will start to populate. There's also a filter field at the bottom of the search pane — it understands Regex and will narrow the search results.
  • Navigating: Use the arrow keys to navigate: up and down, or press the left arrow to select the queue, or the right arrow to select the search results pane. Use shift to select multiple items.
  • Playing: Pressing (Return) on a single item plays it immediately. Pressing with multiple tracks selected adds them to the top of the queue and starts playing them.

Of course, you may want to manipulate the queue.

  • When you're in the search pane, ⌘← enqueues at the bottom, and ⌘⇧← enqueues at the top of the queue.
  • When you're in the queue pane, holding (the command key) and using the navigation keys moves selected tracks up or down in the queue.
  • Space bar pauses and unpauses (unless search field has focus).
  • ⌘N skips to the next track. Also useful for starting playback.

Note that instead of the arrows, you can use Vim-like movement keys too!

  • Left and right arrows or h, l switch focus between queue and search results.
  • Supports some Vim keys (e.g., j,k,g,G).
  • Tab cycles through search (or hit ⌘F or ⌘L to search), search results, and queue.

More detail on keybindings

The basic Vim and Emacs movement keys are supported instead of using arrow keys.

Key Description
left, right, h, l search or queue Focus between search and queue
up, down, j, k search or queue Move up or down
/ search Focus the filter field
Enter search Place selected items at the top of the queue and immediately play first item
Enter queue Play the selected item, removing items above it
⌘F or ⌘L global Focus the search bar
⌘Q global Quit Spotiqueue
⌘O global List all of your saved playlists
⌘N global Play next track from queue
⌘; or ⌘→ search or queue Browse details of selected item (see description below)
⌘h or ⌘← search Enqueue selection at the bottom of the queue
⌘⇧h or ⌘⇧← search Enqueue selection at the top of the queue
? global Show current track's album in search results
TAB global Cycle focus search field -> search results -> queue
x, d, Delete, Backspace queue Remove selected item(s) from queue
x, d, Delete, Backspace search Only when viewing user's playlists: delete playlist
⌘S search Save current search results to new playlist
⌘S queue Save current queue to new playlist
^b, ^f, ^u, ^d search or queue Scroll up/down by full or half page
⌘C search or queue Place highlighted items on clipboard
⌘⇧C search or queue Place highlighted items' album link on clipboard
⌘V queue Paste items on clipboard into the queue

Note:

  • ^ is Control
  • is Command
  • is Shift

Browsing details

For any item in a list you can press ⌘; or ⌘→, to "dive deeper". If the item you selected is a track, the search pane will be populated by the album it's on. If you dive deeper after having opened an album, you'll get all the artist's tracks. When playlists are listed in the search results, diving deeper will return all the tracks of the playlist.

But wait, there's more! Or, writing Scheme to extend Spotiqueue

What it currently supports:

  • Setting arbitrary keybindings — if you don't like my choices, change them!
  • Hooks — get a callback when the track ends, when items are copied, etc.
  • Remote control — easily hook up media keys, network access, whatever you want. The sky's the limit.

If you already know Scheme and just want to get started, place a file in your home directory, and it'll automatically get loaded next time Spotiqueue starts up:

~/.config/spotiqueue/init.scm

For more details, check out the example init.scm file, which i use myself. You'll probably also want to look at the Scheme internals of Spotiqueue.

Download and install

If you don't like hassling about with Xcode (quite rightly so), you can find compiled versions on the Github releases page. Unfortunately, for now you need at least macOS 10.15, because the app makes heavy use of the Combine framework.

Development

Have a look at HACKING.md for a run-through of the development tools required.

Copyright © 2021 paul at denknerd dot org

Comments
  • Current track and position are forgotten after quit and restart

    Current track and position are forgotten after quit and restart

    What I did

    1. Start playing a track
    2. Quit Spotiqueue
    3. Restart Spotiqueue

    What I expected

    Spotiqueue remembers what track it was playing, and what position it was up to.

    What happened

    The current track display (bottom left) showed:

    title: -
    album: -
    -:-- / --:-- / -:--
    

    The queue was preserved, though, which is nice :)

    opened by lucaswilric 1
  • Don't crash on non-premium / bad credentials.

    Don't crash on non-premium / bad credentials.

    Users around and about run into a hard crash if they happen to provide incorrect credentials (or a non-premium account, which we can't use – Spotify won't let us).

    This patchset will at least aim to show the user what went wrong logging in, and let them try again (perhaps with correct/better credentials).

    I went ahead and did a bump of all the Rust dependencies, too.

    opened by toothbrush 0
  • Okay fine, vendor in manually-crafted binaries

    Okay fine, vendor in manually-crafted binaries

    To build a Universal binary, i need to have ARM64 and Intel versions of all my dependencies. I could learn how to build libguile, bdw-gc, etc. but their build instructions are .. non-trivial. So instead i'm cheating and downloading the Intel and ARM versions from Homebrew (they kindly do the work of working out how to build for me) and stitch them together myself with lipo, the now apparently deprecated tool...

    Anyway this appears to work. Pending testing on ARM and Intel devices, when built on either.

    opened by toothbrush 0
  • Get/set queue from Guile

    Get/set queue from Guile

    This PR does a few things:

    • Expose a queue:get-tracks and queue:set-tracks function to Guile land so you can.. well, you know.
    • Implement an example using these new functions, shuffle tracks in queue.
    • Make it build on my new computer. I really need to (one day..) make the XCode project auto-build dependencies instead of relying on flaky shit to find Homebrew-installed libs that really aren't intended to be used for building software against.

    Kinda silly making a PR on my own project!

    opened by toothbrush 0
  • Bundle Guile stdlib and ccache

    Bundle Guile stdlib and ccache

    We really don't want Spotiqueue to rely on users doing brew install guile -- that would exclude half the world that doesn't like terminals. So, we vendor in the Guile stdlib. However, that's not enough, because if my guile*.a file was compiled in a different location than someone else's Guile installation path (e.g. the Homebrew 3.0.7 vs 3.0.7_1 path issue) the built-in %load-path won't match up with theirs!

    Subsequently (yes, there's more) if i don't also bundle in the ccache (*.go files) then at startup Spotiqueue thinks its own stdlib is newer than the user's one and busily starts compiling. No bueno. So we package up both the stdlib source & compiled files, and manually tweak the search paths so that we're sure that only those files will be used. Not great, but it seems to work, and best of all, folks won't need to install Guile themselves if they don't want to.

    Closes #2

    opened by toothbrush 0
  • Spotiqueue: Guile edition!

    Spotiqueue: Guile edition!

    Changes in this version (slated to be v2.4):

    • Basic Guile support! Pause, next, get current song, as well as the ability to bind keys to arbitrary Scheme code.
    • Create playlists from search results or current queue.
    • Delete playlists from user library.
    • / filter is a bit smarter regarding your selection in search results. For example, narrow results with / then Esc leaves the filtered result selected.
    • Toggle button to disable auto-advancing on end-of-track event. Useful for "stop after currently-playing track".
    • ? will surface the album of the currently-playing track, and highlight the current track.
    opened by toothbrush 0
  • Feature/load users saved tracks

    Feature/load users saved tracks

    Not sure if you're interested in this or not, but I modified Spotiqueue to add the ability to fetch my saved tracks aka ones that I have "liked" or hearted, or whatever. PS this is my first time playing with Swift so if there's anything weird - please let me know!

    opened by faaarmer 0
  • Ennicen how we find original `.a` files

    Ennicen how we find original `.a` files

    TODO probably want to work out a smarter way of finding the .a files. These paths will change when versions change.

    Refers to this stuff:

    https://github.com/toothbrush/Spotiqueue/blob/1c795c6bcd4f926ec8c1e88c2b218704426d073d/vendor/Makefile#L8-L11

    Originally posted by @toothbrush in https://github.com/toothbrush/Spotiqueue/pull/6#discussion_r758859150

    opened by toothbrush 0
Releases(v2.7.1)
  • v2.7.1(Jan 4, 2022)

    As requested in #4, we now restore the previous session's current track & playback position.

    If you prefer the old behaviour (that is, no current track when opening Spotiqueue), simply add the following snippet to your ~/.config/spotiqueue/init.scm configuration file:

    (if (defined? 'player:set-restore-playback)
        (player:set-restore-playback #f))
    
    Source code(tar.gz)
    Source code(zip)
    Spotiqueue-v2.7.1.zip(25.47 MB)
  • v2.7(Jan 2, 2022)

    Main changes:

    • Exception handling: making a mistake in your Guile code won't terminate the entire player! You'll just get an alert popup. This makes developing and reloading your code interactively (e.g., in Emacs with Geiser connected to Spotiqueue) much more convenient.
    • queue:set-tracks now supports both <track> records as well as strings with Spotify URIs like spotify:track:f00bar.
    • search:get-selection exposes search selection to Guile.
    • queue:insert-tracks allows one to insert new queued tracks at any position. Useful if you want a custom top-enqueue function that takes into account the currently-playing album!
    • paul:enqueue-after-current-album demonstrates a smarter top-enqueue.
    • GUI: you can copy from the track/album/title display labels.

    Changelog highlights:

    94ad77a * paul-config.scm(paul:enqueue-after-current-album): Smarter top-enqueue. c4969a0 * Spotiqueue/GuileHelpers.m(queue:insert-tracks): Expose new procedure. ed1a379 * Instead of append, let's support insert(at:) for queue. 5003f4b * RBQueueTableView.swift(paste): Deal gracefully with bad input. a93387b * GuileHelpers.m(search_get_selection): Expose search selection to Guile. 4f98964 * Introduce record, plus some plumbing. 0b18346 * GuileHelpers.m(get_tracks_from): Slightly more general queue_get_tracks. 1f0aad9 * base.scm(flatten-track): Rename procedure. 934f7f7 * paul-config.scm: Find hs binary in M1 Mac Homebrew location. 48fce70 * records.scm: Just use module-export-all!, more concise. 85d9f3a * (spotiqueue base): Rename from (spotiqueue init). 7284a8d * init.scm: Use simpler re-export logic. 6134e92 * init.scm(re-export-public-interface): Syntax to re-export all defines. 7ddbed7 * (spotiqueue functions): Renamed from internal. ef93861 * RBGuileBridge.swift(guile_handle_key): Remove scm_eval. ceca189 * init.scm(define-key): Procedures instead of symbols in keymaps. a4bd3af * paul-config.scm: Demonstrate config as standalone module. ddebf44 * paul-config.scm: Fixup forgotten reset-hook!. a4a3597 * Ensure we always do module-name-qualified lookups. 7907742 * RBGuileBridge.swift(hook_with_track): Remove and inline boring admin. db4a5f9 * init.scm(define-key): Ensure user passed <kbd> and hash-table. be46b70 * keybindings.scm(kbd?): Predicate to check for <kbd> structs. 0e50346 * RBGuileBridge.swift(call_hook): Consolidate hook_0, hook_1; catch exceptions. 311b78e * RBGuileBridge.swift(load_user_initscm_if_present): Use "safe" primitive-load. 970504b * RBGuileBridge.swift(guile_handle_key): Only output key name in DEBUG. 5091d87 * RBGuileBridge.swift(guile_handle_key): Use exception handler for keybindings. d636b00 * RBGuileBridge.swift(track_to_scm_record): Comment. 7717782 * exceptions.scm: New module with some "safe" procedure wrappers. 67f7c58 * GuileHelpers.m(player:alert): Procedure to show NSAlert from Guile. ea15ad0 * GuileHelpers.m: Alphabetise scm defines. f22be39 * GuileHelpers.m(queue:set-tracks): Rename to queue:_set-tracks, introduce helper. b03a2e6 * Make album/track labels selectable.

    Source code(tar.gz)
    Source code(zip)
    Spotiqueue-v2.7.zip(25.46 MB)
  • v2.5.2(Dec 6, 2021)

  • v2.5.1(Nov 30, 2021)

    What's Changed

    • Universal binary! Should work on old and new Macs!
    • Get/set queue from Guile land, in https://github.com/toothbrush/Spotiqueue/pull/5
    • Ctrl-Alt-s to shuffle the current queue! wink wink

    Full Changelog: https://github.com/toothbrush/Spotiqueue/compare/v2.4.2...v2.5.1

    Source code(tar.gz)
    Source code(zip)
    Spotiqueue-v2.5.1.zip(25.25 MB)
  • v2.4.2(Oct 2, 2021)

  • v2.4(Sep 18, 2021)

    ⚠ This release is broken for some. Use more recent release.

    Have you ever thought it'd be rad to add features to Spotiqueue using everyone's favourite language? Wait no more, with Spotiqueue's Guile integration!

    Changes in this version (v2.4):

    • Basic Guile support! Pause, next, get current song, as well as the ability to bind keys to arbitrary Scheme code.
    • Create playlists from search results or current queue.
    • Delete playlists from user library.
    • / filter is a bit smarter regarding your selection in search results. For example, narrow results with / then Esc leaves the filtered result selected.
    • Toggle button to disable auto-advancing on end-of-track event. Useful for "stop after currently-playing track".
    • ? will surface the album of the currently-playing track, and highlight the current track.
    Source code(tar.gz)
    Source code(zip)
    Spotiqueue-v2.4.zip(10.03 MB)
  • v2.3.1(Jul 31, 2021)

  • v2.3.0(Jul 5, 2021)

  • v2.2.0(Jun 29, 2021)

    • Ability to paste songs, albums or playlists into the queue (⌘V when queue has focus) – try pasting spotify:album:2XY6A8TMHbPaffK00b72BO or a Spotify link like https://open.spotify.com/playlist/60NJZPEWekQZhuVKclRXgB?si=e9f2de627d8342c3
    • Disabled dark mode
    • Display total queue time
    • Display a user's playlists (⌘O)
    • Copy songs by selecting and ⌘C

    Bug fixes:

    • Focus loop fixed (TAB between search box, results and queue)
    Source code(tar.gz)
    Source code(zip)
    Spotiqueue-v2.2.0.zip(9.03 MB)
  • v2.1.2(Jun 17, 2021)

  • v2.1.1(Jun 17, 2021)

Owner
paul
🏝️ 🐊
paul
An iOS app that visually clones Spotify's app and consumes the official Spotify's Web API to show(and play) songs, podcasts, artists and more.

SpotifyClone An iOS app that visually clones Spotify's app and consumes the official Spotify's Web API to show(and play) songs, podcasts, artists and

null 104 Jan 7, 2023
Queue management system for AVSpeechSynthesizer

QHSpeechSynthesizerQueue Queue management system for AVSpeechSynthesizer Installation Cocoapods Add this to your Podfile: pod 'QHSpeechSynthesizerQueu

Quentin Hayot 42 Dec 17, 2021
A simple Spotify lyrics viewer menu bar app for macOS in Swift 3

lyricsify This is a simple macOS menu bar application that shows you the lyrics of current playing spotify track. All the lyricses are from Wikia webs

Mohamad Jahani 85 Dec 31, 2022
A tiny menu bar app detecting the chords of the songs you are listening on iTunes or Spotify.

ChordDetector A tiny menu bar app that listens iTunes and Spotify to detect chords of songs! Demo Features iTunes and Spotify support. Saves up to 20

Cem Olcay 72 Dec 26, 2022
macOS app that allows the control of Spotify and AppleMusic/iTunes music playback from the menu bar.

PlayStatus is a simple macOS app that allows the control of Spotify, Apple Music(macOS 10.15+) and iTunes including iTunes Radio/Beats1 playback from

Nikhil Bolar 114 Dec 28, 2022
A pure Swift Spotify Music App in Apple Music style

HBMusic A pure Swift Spotify Music App in Apple Music style. How to run pod inst

haoboxuxu 6 Dec 29, 2021
A Spotify clone created using SwiftUI

Spotify Clone Its a Spotify clone created using SwiftUI. Deployment To deploy th

Manav Deep Singh Lamba 1 Jan 17, 2022
HomeHub - Swift app to control my home's smart devices + show spotify current playback

HomeHub iPad app to control my home's smart devices + show spotify current playb

Cooper Bell 2 Oct 22, 2022
RHPreviewCell - I envied so much Spotify iOS app this great playlist preview cell 😍

I envied so much Spotify iOS app this great playlist preview cell ??, I decided to create my own one ??. Now you can give your users ability to quick check what content is hidden under your UITableViewCell. Great think is that this Library not requires 3D Touch support from user device??.

Robert Herdzik 387 Sep 23, 2022
The official OS X client to the Radio Paradise web radio.

Introduction Radio Paradise is a unique blend of many styles and genres of music, carefully selected and mixed by two real human beings — enhanced by

Giacomo Tufano 19 Aug 17, 2022
AudioPlayer is a simple class for playing audio in iOS, macOS and tvOS apps.

AudioPlayer AudioPlayer is a simple class for playing audio in iOS, macOS and tvOS apps.

Tom Baranes 260 Nov 27, 2022
Soundable is a tiny library that uses AVFoundation to manage the playing of sounds in iOS applications in a simple and easy way

Soundable is a tiny library that uses AVFoundation to manage the playing of sounds in iOS applications in a simple and easy way. You can play

Luis Cárdenas 89 Nov 21, 2022
SwiftySound is a simple library that lets you deal with Swift sounds easily

SwiftySound Overview SwiftySound is a simple library that lets you deal with Swift sounds easily. Static methods Sound.play(file: "dog.wav") Sound.pla

Adam Cichy 1.1k Dec 17, 2022
:musical_keyboard: A simple iOS synthesiser powered by Pure Data. Based on the Korg Monotron Delay.

Monotone Delay A simple iOS Synthesizer based on Pure Data. You can see a short demo of the app on youtube. If you want to buy the app you can find it

Justus Kandzi 17 Oct 16, 2022
SoundManager - A simple framework to load and play sounds in your app.

SoundManager - A simple framework to load and play sounds in your app.

Jonathan Chacón 3 Jan 5, 2022
TuningFork is a simple utility for processing microphone input and interpreting pitch, frequency, amplitude, etc.

Overview TuningFork is a simple utility for processing microphone input and interpreting pitch, frequency, amplitude, etc. TuningFork powers the Parti

Comyar Zaheri 419 Dec 23, 2022
An advanced media player library, simple and reliable

About The SRG Media Player library provides a simple way to add universal audio / video playback support to any application. It provides: A controller

SRG SSR 145 Aug 23, 2022
Simple command line utility for switching audio inputs and outputs on macOS

Switch Audio Simple command line utility for switching audio inputs and outputs

Daniel Hladík 3 Nov 22, 2022
A very simple soundboard that plays the first 5 seconds of the CSI Miami theme (YEAAAAAAAAAA)

MiamiSunglasses This app is a single-sound soundboard that plays the first few seconds of the CSI Miami theme song when you press the sunglasses. Disc

Adrian Edwards 4 Feb 10, 2022