Advertisement
s4ros

sp

Jan 19th, 2019
28,055
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.97 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. #
  4. # This is sp, the command-line Spotify controller. It talks to a running
  5. # instance of the Spotify Linux client over dbus, providing an interface not
  6. # unlike mpc.
  7. #
  8. # Put differently, it allows you to control Spotify without leaving the comfort
  9. # of your command line, and without a custom client or Premium subscription.
  10. #
  11. # As an added bonus, it also works with ssh, at and cron.
  12. #
  13. # Example:
  14. # $ sp weather girls raining men
  15. # $ sp current
  16. # Album   100 Hits Of The '80s
  17. # Artist  The Weather Girls
  18. # Title   It's Raining Men
  19. # $ sp pause
  20. #
  21. # Alarm clock example:
  22. # $ at 7:45 <<< 'sp bangarang'
  23. #
  24. # Remote example:
  25. # $ ssh vader@prod02.nomoon.ta 'sp imperial march'
  26. #
  27. #
  28. # Copyright (C) 2013 Wander Nauta
  29. #
  30. # Permission is hereby granted, free of charge, to any person obtaining a copy
  31. # of this software, to deal in the Software without restriction, including
  32. # without limitation the rights to use, copy, modify, merge, publish,
  33. # distribute, sublicense, and/or sell copies of the Software, and to permit
  34. # persons to whom the Software is furnished to do so, subject to the following
  35. # conditions:
  36. #
  37. # The above copyright notice and this permission notice shall be included in
  38. # all copies or substantial portions of the Software.
  39. #
  40. # The software is provided "as is", without warranty of any kind, express or
  41. # implied, including but not limited to the warranties of merchantability,
  42. # fitness for a particular purpose and noninfringement. In no event shall the
  43. # authors or copyright holders be liable for any claim, damages or other
  44. # liability, whether in an action of contract, tort or otherwise, arising from,
  45. # out of or in connection with the software or the use or other dealings in the
  46. # software.
  47. #
  48.  
  49. # CONSTANTS
  50.  
  51. SP_VERSION="0.1"
  52. SP_DEST="org.mpris.MediaPlayer2.spotify"
  53. SP_PATH="/org/mpris/MediaPlayer2"
  54. SP_MEMB="org.mpris.MediaPlayer2.Player"
  55.  
  56. # SHELL OPTIONS
  57.  
  58. shopt -s expand_aliases
  59.  
  60. # UTILITY FUNCTIONS
  61.  
  62. function require {
  63.   hash $1 2>/dev/null || {
  64.     echo >&2 "Error: '$1' is required, but was not found."; exit 1;
  65.   }
  66. }
  67.  
  68. # COMMON REQUIRED BINARIES
  69.  
  70. # We need dbus-send to talk to Spotify.
  71. require dbus-send
  72.  
  73. # Assert standard Unix utilities are available.
  74. require grep
  75. require sed
  76. require cut
  77. require tr
  78.  
  79. # 'SPECIAL' (NON-DBUS-ALIAS) COMMANDS
  80.  
  81. function sp-dbus {
  82.   # Sends the given method to Spotify over dbus.
  83.   dbus-send --print-reply --dest=$SP_DEST $SP_PATH $SP_MEMB.$1 ${*:2} > /dev/null
  84. }
  85.  
  86. function sp-open {
  87.   # Opens the given spotify: URI in Spotify.
  88.   sp-dbus OpenUri string:$1
  89. }
  90.  
  91. function sp-metadata {
  92.   # Prints the currently playing track in a parseable format.
  93.  
  94.   dbus-send                                                                   \
  95.   --print-reply                                  `# We need the reply.`       \
  96.   --dest=$SP_DEST                                                             \
  97.   $SP_PATH                                                                    \
  98.   org.freedesktop.DBus.Properties.Get                                         \
  99.   string:"$SP_MEMB" string:'Metadata'                                         \
  100.   | grep -Ev "^method"                           `# Ignore the first line.`   \
  101.   | grep -Eo '("(.*)")|(\b[0-9][a-zA-Z0-9.]*\b)' `# Filter interesting fiels.`\
  102.   | sed -E '2~2 a|'                              `# Mark odd fields.`         \
  103.   | tr -d '\n'                                   `# Remove all newlines.`     \
  104.   | sed -E 's/\|/\n/g'                           `# Restore newlines.`        \
  105.   | sed -E 's/(xesam:)|(mpris:)//'               `# Remove ns prefixes.`      \
  106.   | sed -E 's/^"//'                              `# Strip leading...`         \
  107.   | sed -E 's/"$//'                              `# ...and trailing quotes.`  \
  108.   | sed -E 's/"+/|/'                             `# Regard "" as seperator.`  \
  109.   | sed -E 's/ +/ /g'                            `# Merge consecutive spaces.`
  110. }
  111.  
  112. function sp-current {
  113.   # Prints the currently playing track in a friendly format.
  114.   require column
  115.  
  116.   sp-metadata \
  117.   | grep --color=never -E "(title)|(album)|(artist)" \
  118.   | sed 's/^\(.\)/\U\1/' \
  119.   | column -t -s'|'
  120. }
  121.  
  122. function sp-eval {
  123.   # Prints the currently playing track as shell variables, ready to be eval'ed
  124.   require sort
  125.  
  126.   sp-metadata \
  127.   | grep --color=never -E "(title)|(album)|(artist)|(trackid)|(trackNumber)" \
  128.   | sort -r \
  129.   | sed 's/^\([^|]*\)\|/\U\1/' \
  130.   | sed -E 's/\|/="/' \
  131.   | sed -E 's/$/"/' \
  132.   | sed -E 's/^/SPOTIFY_/'
  133. }
  134.  
  135. function sp-art {
  136.   # Prints the artUrl.
  137.  
  138.   sp-metadata | grep "artUrl" | cut -d'|' -f2
  139. }
  140.  
  141. function sp-display {
  142.   # Calls display on the artUrl.
  143.  
  144.   require display
  145.   display $(sp-art)
  146. }
  147.  
  148. function sp-feh {
  149.   # Calls feh on the artURl.
  150.  
  151.   require feh
  152.   feh $(sp-art)
  153. }
  154.  
  155. function sp-url {
  156.   # Prints the HTTP url.
  157.  
  158.   TRACK=$(sp-metadata | grep "url" | cut -d'|' -f2 | cut -d':' -f3)
  159.   echo "http://open.spotify.com/track/$TRACK"
  160. }
  161.  
  162. function sp-clip {
  163.   # Copies the HTTP url.
  164.  
  165.   require xclip
  166.   sp-url | xclip
  167. }
  168.  
  169. function sp-http {
  170.   # xdg-opens the HTTP url.
  171.  
  172.   require xdg-open
  173.   xdg-open $(sp-url)
  174. }
  175.  
  176. function sp-help {
  177.   # Prints usage information.
  178.  
  179.   echo "Usage: sp [command]"
  180.   echo "Control a running Spotify instance from the command line."
  181.   echo ""
  182.   echo "  sp play       - Play/pause Spotify"
  183.   echo "  sp pause      - Pause Spotify"
  184.   echo "  sp next       - Go to next track"
  185.   echo "  sp prev       - Go to previous track"
  186.   echo ""
  187.   echo "  sp current    - Format the currently playing track"
  188.   echo "  sp metadata   - Dump the current track's metadata"
  189.   echo "  sp eval       - Return the metadata as a shell script"
  190.   echo ""
  191.   echo "  sp art        - Print the URL to the current track's album artwork"
  192.   echo "  sp display    - Display the current album artwork with \`display\`"
  193.   echo "  sp feh        - Display the current album artwork with \`feh\`"
  194.   echo ""
  195.   echo "  sp url        - Print the HTTP URL for the currently playing track"
  196.   echo "  sp clip       - Copy the HTTP URL to the X clipboard"
  197.   echo "  sp http       - Open the HTTP URL in a web browser"
  198.   echo ""
  199.   echo "  sp open <uri> - Open a spotify: uri"
  200.   echo "  sp search <q> - Start playing the best search result for the given query"
  201.   echo ""
  202.   echo "  sp version    - Show version information"
  203.   echo "  sp help       - Show this information"
  204.   echo ""
  205.   echo "Any other argument will start a search (i.e. 'sp foo' will search for foo)."
  206. }
  207.  
  208. function sp-search {
  209.   # Searches for tracks, plays the first result.
  210.  
  211.   require curl
  212.  
  213.   Q="$@"
  214.   SPTFY_URI=$( \
  215.     curl -s -G  --data-urlencode "q=$Q" ws.spotify.com/search/1/track \
  216.     | grep -E -o "spotify:track:[a-zA-Z0-9]+" -m 1 \
  217.   )
  218.  
  219.   sp-open $SPTFY_URI
  220. }
  221.  
  222. function sp-version {
  223.   # Prints version information.
  224.  
  225.   echo "sp $SP_VERSION"
  226.   echo "Copyright (C) 2013 Wander Nauta"
  227.   echo "License MIT"
  228. }
  229.  
  230. # 'SIMPLE' (DBUS-ALIAS) COMMANDS
  231.  
  232. alias sp-play="  sp-dbus PlayPause"
  233. alias sp-pause=" sp-dbus Pause"
  234. alias sp-next="  sp-dbus Next"
  235. alias sp-prev="  sp-dbus Previous"
  236.  
  237. # DISPATCHER
  238.  
  239. # First, we connect to the dbus session spotify is on. This isn't really needed
  240. # when running locally, but is crucial when we don't have an X display handy
  241. # (for instance, when running sp over ssh.)
  242.  
  243. SPOTIFY_PID="$(pidof -s spotify)"
  244.  
  245. if [[ -z "$SPOTIFY_PID" ]]; then
  246.   echo "Error: Spotify is not running."
  247.   exit 1
  248. fi
  249.  
  250. QUERY_ENVIRON="$(cat /proc/${SPOTIFY_PID}/environ | tr '\0' '\n' | grep "DBUS_SESSION_BUS_ADDRESS" | cut -d "=" -f 2-)"
  251. if [[ "${QUERY_ENVIRON}" != "" ]]; then
  252.   export DBUS_SESSION_BUS_ADDRESS="${QUERY_ENVIRON}"
  253. fi
  254.  
  255. # Then we dispatch the command.
  256.  
  257. subcommand="$1"
  258.  
  259. if [[ -z "$subcommand" ]]; then
  260.   # No arguments given, print help.
  261.   sp-help
  262. else
  263.   # Arguments given, check if it's a command.
  264.   if $(type sp-$subcommand > /dev/null 2> /dev/null); then
  265.     # It is. Run it.
  266.     shift
  267.     eval "sp-$subcommand $@"
  268.   else
  269.     # It's not. Try a search.
  270.     eval "sp-search $@"
  271.   fi
  272. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement