├── README.md └── SpotifyControl /README.md: -------------------------------------------------------------------------------- 1 | # Control Spotify at OS X Terminal 2 | 3 | An AppleScript for controlling Spotify through a terminal: 4 | 5 | The scenario for which it was originally designed is controlling Spotify, 6 | which is playing on a Mac, via ssh, while working on a Linux machine 7 | on the other side of the room. 8 | 9 | Currently supported functions are: play/pause, next/previous 10 | track, jumping in time, toggling shuffle/repeat and changing volume. 11 | This pretty much covers everything the AppleScript hooks of Spotify 12 | allow. 13 | 14 | ### Tested Platforms 15 | 16 | * OS X Big Sur (11.5), Spotify 1.1.66.580 17 | 18 | * OS X El Capitan (10.11) 19 | * OS X Yosemite (10.10) 20 | * OS X Mavericks (10.9) 21 | * OS X Mountain Lion (10.8) 22 | * OS X Lion (10.7) 23 | 24 | ## Installation 25 | 26 | The simplest way to install the script is to `clone` the repository, 27 | `cd` into repository's directory, and run the command below 28 | to make a symbolic link into `/usr/local/bin/`: 29 | 30 | ```bash 31 | ln -s $(pwd)/SpotifyControl /usr/local/bin/spotify 32 | ``` 33 | 34 | 35 | ## Usage 36 | 37 | * To start Spotify playback, type `spotify start` or `spotify play`. 38 | If you do this locally and Spotify is not running, it will start. 39 | Remotely, Spotify will not start properly. Optionally, pass a Spotify URI as a second argument. 40 | * To Search for track name and play, type `spotify play track [song name]`. 41 | * To Search for artist name and play, type `spotify play artist [artist name]`. 42 | * To Search for album name and play, type `spotify play album [album name]`. 43 | * To pause Spotify playback, type `spotify stop` or `spotify pause`. 44 | * To toggle playback, type `spotify play/pause`. 45 | * To go to the next track, type `spotify next`. 46 | * To go to the previous track, type `spotify previous` or `spotify 47 | prev`. 48 | * To print information about the currently playing track, 49 | type `spotify info` 50 | * To jump to a particular time in the track, type `spotify jump N`, 51 | where N is the track position in seconds. 52 | * To fast forward, type `spotify forward N` where N is the number of 53 | seconds to jump ahead. 54 | * To rewind, type `spotify rewind N` where N is the number of 55 | seconds to jump backwards. 56 | * To change volume, type `spotify volume N` where N is a number between 57 | 0 and 100. 58 | * To increase volume by 10%, type `spotify volume up`. 59 | * To decrease volume by 10%, type `spotify volume down`. 60 | * Increase volume, type `spotify increasevolume N` where N is a number between 61 | 0 and 100 that you want to increment by. 62 | * Decrease volume, type `spotify decreasevolume N` where N is a number between 63 | 0 and 100 that you want to decrement by. 64 | * To toggle shuffle, type `spotify shuffle [on|off]`. 65 | * To toggle repeat, type `spotify repeat [on|off]`. 66 | * To show a list of these commands, just type `spotify`. 67 | 68 | ### Over SSH 69 | 70 | To enable the SSH server on OS X, go to Sharing in the System Preferences 71 | and enable Remote Login. The Sharing screen will also then tell you the 72 | command to use to connect to your Mac in the local network. 73 | 74 | ## License 75 | 76 | You may use, adapt, modify, and etc. Any way you want. 77 | -------------------------------------------------------------------------------- /SpotifyControl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env osascript 2 | on run argv 3 | 4 | set msg to "Use the following commands:\n" 5 | set msg to msg & " start, play [uri] - Start playback / play uri\n" 6 | set msg to msg & " start, play track [song name] - Search and play track\n" 7 | set msg to msg & " start, play artist [artist name] - Search and play artist\n" 8 | set msg to msg & " start, play album [album name] - Search and play album\n" 9 | set msg to msg & " pause, stop - Stop playback\n" 10 | set msg to msg & " play/pause - Toggle playback\n" 11 | set msg to msg & " next - Next track\n" 12 | set msg to msg & " previous, prev - Previous track\n" 13 | set msg to msg & " info - Print track info\n" 14 | set msg to msg & " jump N - Jump to N seconds in the song\n" 15 | set msg to msg & " forward N - Jump N seconds forwards\n" 16 | set msg to msg & " rewind N - Jump N seconds backwards\n" 17 | set msg to msg & " shuffle - Toggle shuffle\n" 18 | set msg to msg & " repeat - Toggle repeat\n" 19 | set msg to msg & " volume N, up, down - Set Volume to N (0...100)\n" 20 | set msg to msg & " increasevolume N - Increment Volume by N (0...100)\n" 21 | set msg to msg & " decreasevolume N - Decrement Volume by N (0...100)\n" 22 | 23 | set waitFlag to false 24 | 25 | if count of argv is equal to 0 then 26 | return msg 27 | end if 28 | set command to item 1 of argv 29 | using terms from application "Spotify" 30 | set info to "Error." 31 | -- Play 32 | if command is equal to "play" or command is equal to "start" then 33 | if count of argv is equal to 1 then 34 | tell application "Spotify" to play 35 | else 36 | set m_type to item 2 of argv 37 | set uri to m_type 38 | set modes to {"artist", "album", "track"} 39 | if modes contains m_type then 40 | if count of argv is equal to 2 then 41 | return "Search argument is missing..." 42 | else 43 | set q to "" 44 | repeat with myArgv from 3 to (count of argv) 45 | set q to q & item myArgv of argv & " " 46 | end repeat 47 | log "Searching " & m_type & "s for " & q 48 | set spotifySearchAPI to "\"https://api.spotify.com/v1/search\"" 49 | try 50 | set uri to do shell script " curl s -G " & spotifySearchAPI & ¬ 51 | " --data-urlencode \"q=" & q & "\"" & ¬ 52 | " -d \"type=" & m_type & "&limit=1&offset=0\"" & ¬ 53 | " -H \"Accept: application/json\" | grep -E -o \"spotify:" & ¬ 54 | m_type & ":[a-zA-Z0-9]+\" -m 1" 55 | on error 56 | return "No results found for " & q 57 | end try 58 | log q & "is Found!" 59 | set waitFlag to true 60 | end if 61 | end if 62 | tell application "Spotify" to play track uri 63 | end if 64 | -- Play/Pause 65 | else if command is equal to "play/pause" then 66 | tell application "Spotify" to playpause 67 | return "Toggled." 68 | -- Pause 69 | else if command is equal to "pause" or command is equal to "stop" then 70 | tell application "Spotify" to pause 71 | return "Paused." 72 | -- Next 73 | else if command is equal to "next" then 74 | tell application "Spotify" to next track 75 | -- Prev 76 | else if command is equal to "previous" or command is equal to "prev" then 77 | tell application "Spotify" to previous track 78 | -- Jump 79 | else if command is equal to "jump" 80 | set jumpTo to item 2 of argv as real 81 | tell application "Spotify" 82 | set tMax to duration of current track 83 | if jumpTo > tMax 84 | return "Can't jump past end of track." 85 | else if jumpTo < 0 86 | return "Can't jump past start of track." 87 | end if 88 | set nM to round (jumpTo / 60) rounding down 89 | set nS to round (jumpTo mod 60) rounding down 90 | set newTime to nM as text & "min " & nS as text & "s" 91 | set player position to jumpTo 92 | return "Jumped to " & newTime 93 | end tell 94 | -- Forward 95 | else if command is equal to "forward" 96 | set jump to item 2 of argv as real 97 | tell application "Spotify" 98 | set now to player position 99 | set tMax to duration of current track 100 | set jumpTo to now + jump 101 | if jumpTo > tMax 102 | return "Can't jump past end of track." 103 | else if jumpTo < 0 104 | set jumpTo to 0 105 | end if 106 | set nM to round (jumpTo / 60) rounding down 107 | set nS to round (jumpTo mod 60) rounding down 108 | set newTime to nM as text & "min " & nS as text & "s" 109 | set player position to jumpTo 110 | return "Jumped to " & newTime 111 | end tell 112 | -- Rewind 113 | else if command is equal to "rewind" 114 | set jump to item 2 of argv as real 115 | tell application "Spotify" 116 | set now to player position 117 | set tMax to duration of current track 118 | set jumpTo to now - jump 119 | if jumpTo > tMax 120 | return "Can't jump past end of track." 121 | else if jumpTo < 0 122 | set jumpTo to 0 123 | end if 124 | set nM to round (jumpTo / 60) rounding down 125 | set nS to round (jumpTo mod 60) rounding down 126 | set newTime to nM as text & "min " & nS as text & "s" 127 | set player position to jumpTo 128 | return "Jumped to " & newTime 129 | end tell 130 | -- Volume 131 | else if command is equal to "volume" then 132 | tell application "Spotify" to set lastVolume to sound volume 133 | if item 2 of argv as text is equal to "up" then 134 | set newVolume to lastVolume + 10 135 | else if item 2 of argv as text is equal to "down" then 136 | set newVolume to lastVolume - 10 137 | else 138 | set newVolume to item 2 of argv as real 139 | end if 140 | if newVolume < 0 then set newVolume to 0 141 | if newVolume > 100 then set newVolume to 100 142 | tell application "Spotify" 143 | set sound volume to newVolume 144 | end tell 145 | delay 0.1 146 | return "Changed volume to " & newVolume 147 | -- IncreaseVolume 148 | else if command is equal to "increasevolume" then 149 | set volumeInc to item 2 of argv as real 150 | tell application "Spotify" 151 | set currentVolume to sound volume 152 | set newVolume to currentVolume + volumeInc 153 | if newVolume < 0 then set newVolume to 0 154 | if newVolume > 100 then set newVolume to 100 155 | set sound volume to newVolume 156 | end tell 157 | return "Changed volume to " & newVolume 158 | -- Decrease Volume 159 | else if command is equal to "decreasevolume" then 160 | set volumeInc to item 2 of argv as real 161 | tell application "Spotify" 162 | set currentVolume to sound volume 163 | set newVolume to currentVolume - volumeInc 164 | if newVolume < 0 then set newVolume to 0 165 | if newVolume > 100 then set newVolume to 100 166 | set sound volume to newVolume 167 | end tell 168 | return "Changed volume to " & newVolume 169 | -- Shuffle 170 | else if command is equal to "shuffle" then 171 | if count of argv is equal to 2 then 172 | if item 2 of argv is equal to "on" then 173 | tell application "Spotify" 174 | set shuffling to true 175 | delay 0.1 176 | return "Shuffle is now " & shuffling 177 | end tell 178 | else if item 2 of argv is equal to "off" then 179 | tell application "Spotify" 180 | set shuffling to false 181 | delay 0.1 182 | return "Shuffle is now " & shuffling 183 | end tell 184 | end if 185 | else 186 | tell application "Spotify" 187 | set shuffling to not shuffling 188 | delay 0.1 189 | return "Shuffle is now " & shuffling 190 | end tell 191 | end if 192 | 193 | -- Repeat 194 | else if command is equal to "repeat" then 195 | if count of argv is equal to 2 then 196 | if item 2 of argv is equal to "on" then 197 | tell application "Spotify" 198 | set repeating to true 199 | delay 0.1 200 | return "Repeat is now " & repeating 201 | end tell 202 | else if item 2 of argv is equal to "off" then 203 | tell application "Spotify" 204 | set repeating to false 205 | delay 0.1 206 | return "Repeat is now " & repeating 207 | end tell 208 | end if 209 | else 210 | tell application "Spotify" 211 | set repeating to not repeating 212 | delay 0.1 213 | return "Repeat is now " & repeating 214 | end tell 215 | end if 216 | 217 | -- Info 218 | else if command is equal to "info" then 219 | tell application "Spotify" 220 | set myTrack to name of current track 221 | set myArtist to artist of current track 222 | set myAlbum to album of current track 223 | set tM to round ((duration of current track / 1000) / 60) rounding down 224 | set tS to round ((duration of current track / 1000) mod 60) rounding down 225 | set myTime to tM as text & "min " & tS as text & "s" 226 | set nM to round (player position / 60) rounding down 227 | set nS to round (player position mod 60) rounding down 228 | set nowAt to nM as text & "min " & nS as text & "s" 229 | set info to "Current track:" 230 | set info to info & "\n Artist: " & myArtist 231 | set info to info & "\n Track: " & myTrack 232 | set info to info & "\n Album: " & myAlbum 233 | set info to info & "\n URI: " & spotify url of current track 234 | set info to info & "\n Duration: " & mytime & " ("& (round ((duration of current track / 1000)) rounding down) & " seconds)" 235 | set info to info & "\n Now at: " & nowAt 236 | set info to info & "\n Player: " & player state 237 | set info to info & "\n Volume: " & sound volume 238 | if shuffling then set info to info & "\n Shuffle is on." 239 | if repeating then set info to info & "\n Repeat is on." 240 | end tell 241 | return info 242 | else 243 | log "\nCommand not recognized!\n" 244 | return msg 245 | end if 246 | 247 | tell application "Spotify" 248 | delay 0.1 249 | repeat while waitFlag 250 | set nS to round (player position / 1) rounding down 251 | if nS as text is less than 3 then 252 | set waitFlag to false 253 | end if 254 | end repeat 255 | set shuf to "" 256 | set rpt to "" 257 | if shuffling then 258 | set shuf to "\n[shuffle on]" 259 | if repeating then set rpt to "[repeat on]" 260 | else 261 | if repeating then set rpt to "\n[repeat on]" 262 | end if 263 | if player state as text is equal to "playing" 264 | return "Now playing: " & artist of current track & " - " & name of current track & shuf & rpt 265 | end if 266 | end tell 267 | end using terms from 268 | end run 269 | 270 | --------------------------------------------------------------------------------