Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

How can I add a Unity "quicklist" for Spotify (installed from their website), so that when I right-click on the icon on my dock, I get: "Next, Previous, Stop, Play" and so on?

share|improve this question
add comment

4 Answers

up vote 5 down vote accepted
+50

spotify (native linux client)

Since spotify includes an indicator to control some of its functions, this allows us to use dbus to send events.

There is a great script on ubuntuforums that covers this.

First install a prerequisite:

sudo apt-get install libnet-dbus-perl

Now copy and paste the script into a text file called spcmd and save this to your home folder.

Give it execute rights:

chmod +x ~/spcmd

Lets move this to a more useful folder:

mv ~/spcmd /usr/local/bin

Now, lets create a quick list.

First copy the spotify desktop file to your home folder:

mkdir -p ~/.local/share/applications
cp /usr/share/applications/spotify.desktop ~/.local/share/applications

Open the file and copy and paste the quick list to the end of the file. Save it.

gedit ~/.local/share/applications/spotify.desktop

end result

enter image description here

quicklist

X-Ayatana-Desktop-Shortcuts=PlayPause;Next;Previous;Stop;

[PlayPause Shortcut Group]
Name=PlayPause
Exec=spcmd playpause
TargetEnvironment=Unity

[Next Shortcut Group]
Name=Next
Exec=spcmd next
TargetEnvironment=Unity

[Previous Shortcut Group]
Name=Previous
Exec=spcmd previous
TargetEnvironment=Unity

[Stop Shortcut Group]
Name=Stop
Exec=spcmd stop
TargetEnvironment=Unity

spcmd

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use File::Basename;
use Net::DBus;

# Figure out some dbus stuff
unless ( defined $ENV{'DBUS_SESSION_BUS_ADDRESS'} ) {
&set_DBUS_SESSION_BUS_ADDRESS;
#die "Don't know which dbus to attach to.\nMake sure environment variable DBUS_SESSION_BUS_ADDRESS is set.";
}
#my $bus = Net::DBus->find;
my $bus = Net::DBus->session;
my $spotify = $bus->get_service("org.mpris.MediaPlayer2.spotify");
my $player = $spotify->get_object("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player");
my $application = $spotify->get_object("/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2");
my $getorset = $spotify->get_object("/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties");

# Handle command line argument
if (scalar @ARGV == 0) { &print_help; }
given ($ARGV[0]) {
# when ('play') { $player->Play(); } #Does not work for some reason.
when ('pause') { $player->Pause(); }
when ('playpause') { $player->PlayPause(); }
when ('next') { $player->Next(); }
when ('previous') { $player->Previous(); }
when ('stop') { $player->Stop(); }
when ('playstatus') { print $getorset->Get("org.mpris.MediaPlayer2.Player", "PlaybackStatus") . "\n"; }
when (m/\bspotify:(artist|album|track):[0-9a-zA-z]{22}\b/) { $player->OpenUri($_); }
when ('metadata-debug') { &print_debug_metadata; }
default { &print_help; }
}


# Print the help text
sub print_help {
print "USAGE: " . basename($0) . " {pause|playpause|next|previous|stop|playstatus|met adata-debug|<spotify URI>}\n\n";
print "\t" . "pause" . "\t\t" . "Causes spotify to pause current playback." . "\n";
print "\t" . "playpause" . "\t" . "Causes spotify to pause or play current playback." . "\n";
print "\t" . "next" . "\t\t" . "Goes to next song." . "\n";
print "\t" . "previous" . "\t" . "Goes to previous song." . "\n";
print "\t" . "stop" . "\t\t" . "Stops playback." . "\n";
print "\t" . "playstatus" . "\t" . "Prints current playstatus (Playing/Paused)." . "\n";
print "\t" . "<spotify URI>" . "\t" . "Starts playing supplied URI." . "\n";
print "\t" . "metadata-debug" . "\t" . "Shows available data on currently playing song." . "\n";
print "\t" . "\t\t" . "Fairly unformatted, thus \"debug\" data." . "\n";
print "\n";
print "EXAMPLES:\t" . basename($0) . " playpause" . "\n";
print "\t\t" . basename($0) . " spotify:track:5XXAq1r5r73ZyBS0XAiGw0" . "\n";

exit;
}

# Print some raw metadata
sub print_debug_metadata {
# Dereference the metadata hashref by copying it to a local hash
my %metadata = %{ $getorset->Get("org.mpris.MediaPlayer2.Player", "Metadata") };

# Print all metadata
print "Now Playing:\n";
for (keys %metadata) {
print $_ . ":\t" . $metadata{$_} . "\n" unless ($_ eq 'xesam:artist');
}

# Dereference the artist arrayref by copying it to local array
my @artistarray = @{ $metadata{'xesam:artist'} };

# Print all artists.
foreach my $artist (@artistarray) {
print "artist: \t" . $artist . "\n";
}
}

sub set_DBUS_SESSION_BUS_ADDRESS {
my $curruser = `whoami`; chomp $curruser;
my $procname = 'spotify';
my $pid = `pgrep -o -u $curruser $procname`; chomp $pid;
my $environ = '/proc/' . $pid . '/environ';
my $dbussession = `grep -z DBUS_SESSION_BUS_ADDRESS $environ`; $dbussession =~ s/^DBUS_SESSION_BUS_ADDRESS=//;

$ENV{'DBUS_SESSION_BUS_ADDRESS'} = $dbussession;
}
share|improve this answer
add comment

Spotify will have a icon on the panel. Just click on that, and you get play, stop, pause, next etc (don't remember all). Not sure if that answers your question.

share|improve this answer
2  
This question is asking how to put that functionality into Spotify's icon in the Unity launcher also. –  Eliah Kagan Jun 3 '12 at 7:03
    
Ok, just me that misunderstood his question. –  user66987 Jun 3 '12 at 15:37
add comment

spotify_cmd is a tool to control a running instance of Spotify under wine, it should work on Windows as well but have not been tested.

Download spotifycmd. Copy to Desktop. then

cd ~/Desktop/
tar -xvjf spotifycmd-0.5.tar.bz2 
sudo cp -r spotifycmd /usr/bin/

now use Exec=/usr/bin/spotifycmd/spotify_cmd.exe XXXX while creating quicklist.

Here XXXX is playpause, next, prev, stop, voldown, volup, etc.

for guide to create quicklist look at my answer

share|improve this answer
    
This answer is excellent!!!! I'm having problems with spotify_cmd.exe working though. It returns Can not find spotify, is it running? in terminal. This is the right track though! –  Ryan McClure Jun 7 '12 at 21:02
    
Oof, is there a native way? –  Syzygy Jun 8 '12 at 3:39
    
@Syzygy I didn't find one. :( –  virpara Jun 8 '12 at 4:22
    
hmmm - given the error - maybe you have to run the windows version of spotify under wine for this wine-based spotify_cmd to work. –  fossfreedom Jun 9 '12 at 13:07
    
@fossfreedom you are right. just checked source. it includes windows.h a library which provides Win32 API. –  virpara Jun 9 '12 at 13:30
add comment

I think the answers given so far are a bit over-complicating things. There is no separate script required, the relevant DBus commands can be sent directly via dbus-send. Just make sure that the dbus package is installed and in the command line issue the following commands:

mkdir -p ~/.local/share/applications
cp /usr/share/applications/spotify.desktop ~/.local/share/applications/

Edit the file ~/.local/share/applications/spotify.desktop to read:

[Desktop Entry]
Name=Spotify
GenericName=Music Player
Comment=Listen to music using Spotify
Icon=spotify-client
Exec=spotify %U
TryExec=spotify
Terminal=false
Type=Application
Categories=Qt;Audio;Music;Player;AudioVideo
MimeType=x-scheme-handler/spotify
# ====> MODIFICATIONS START HERE <=====
Actions=PlayPause;Next;Previous

[Desktop Action PlayPause]
Name=Play/Pause
Exec=dbus-send --print-reply=literal --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.PlayPause
OnlyShowIn=Messaging Menu;Unity;

[Desktop Action Next]
Name=Next
Exec=dbus-send --print-reply=literal --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Next
OnlyShowIn=Messaging Menu;Unity;

[Desktop Action Previous]
Name=Previous
Exec=dbus-send --print-reply=literal --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Previous
OnlyShowIn=Messaging Menu;Unity;

And you're done.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.