Copybara bot | ca5ce64 | 2024-11-08 17:38:08 +0100 | [diff] [blame^] | 1 | #!/usr/bin/env perl |
| 2 | # Copyright (C) 2014 Tony Crisci <tony@dubstepdish.com> |
| 3 | # Copyright (C) 2015 Thiago Perrotta <perrotta dot thiago at poli dot ufrj dot br> |
| 4 | |
| 5 | # This program is free software: you can redistribute it and/or modify |
| 6 | # it under the terms of the GNU General Public License as published by |
| 7 | # the Free Software Foundation, either version 3 of the License, or |
| 8 | # (at your option) any later version. |
| 9 | |
| 10 | # This program is distributed in the hope that it will be useful, |
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | # GNU General Public License for more details. |
| 14 | |
| 15 | # You should have received a copy of the GNU General Public License |
| 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | |
| 18 | # For all media players except mpd/cmus/rhythmbox, MPRIS support should be |
| 19 | # enabled and the playerctl binary should be in your path. |
| 20 | # See https://github.com/acrisci/playerctl |
| 21 | |
| 22 | # Set instance=NAME in the i3blocks configuration to specify a music player |
| 23 | # (playerctl will attempt to connect to org.mpris.MediaPlayer2.[NAME] on your |
| 24 | # DBus session). If instance is empty, playerctl will connect to the first |
| 25 | # supported media player it finds. |
| 26 | |
| 27 | use Time::HiRes qw(usleep); |
| 28 | use Env qw(BLOCK_INSTANCE); |
| 29 | |
| 30 | use constant DELAY => 50; # Delay in ms to let network-based players (spotify) reflect new data. |
| 31 | use constant SPOTIFY_STR => 'spotify'; |
| 32 | |
| 33 | my @metadata = (); |
| 34 | my $player_arg = ""; |
| 35 | |
| 36 | if ($BLOCK_INSTANCE) { |
| 37 | $player_arg = "--player='$BLOCK_INSTANCE'"; |
| 38 | } |
| 39 | |
| 40 | sub buttons { |
| 41 | my $method = shift; |
| 42 | |
| 43 | if($method eq 'mpd') { |
| 44 | if ($ENV{'BLOCK_BUTTON'} == 1) { |
| 45 | system("mpc prev &>/dev/null"); |
| 46 | } elsif ($ENV{'BLOCK_BUTTON'} == 2) { |
| 47 | system("mpc toggle &>/dev/null"); |
| 48 | } elsif ($ENV{'BLOCK_BUTTON'} == 3) { |
| 49 | system("mpc next &>/dev/null"); |
| 50 | } elsif ($ENV{'BLOCK_BUTTON'} == 4) { |
| 51 | system("mpc volume +10 &>/dev/null"); |
| 52 | } elsif ($ENV{'BLOCK_BUTTON'} == 5) { |
| 53 | system("mpc volume -10 &>/dev/null"); |
| 54 | } |
| 55 | } elsif ($method eq 'cmus') { |
| 56 | if ($ENV{'BLOCK_BUTTON'} == 1) { |
| 57 | system("cmus-remote --prev"); |
| 58 | } elsif ($ENV{'BLOCK_BUTTON'} == 2) { |
| 59 | system("cmus-remote --pause"); |
| 60 | } elsif ($ENV{'BLOCK_BUTTON'} == 3) { |
| 61 | system("cmus-remote --next"); |
| 62 | } |
| 63 | } elsif ($method eq 'playerctl') { |
| 64 | if ($ENV{'BLOCK_BUTTON'} == 1) { |
| 65 | system("playerctl $player_arg previous"); |
| 66 | usleep(DELAY * 1000) if $BLOCK_INSTANCE eq SPOTIFY_STR; |
| 67 | } elsif ($ENV{'BLOCK_BUTTON'} == 2) { |
| 68 | system("playerctl $player_arg play-pause"); |
| 69 | } elsif ($ENV{'BLOCK_BUTTON'} == 3) { |
| 70 | system("playerctl $player_arg next"); |
| 71 | usleep(DELAY * 1000) if $BLOCK_INSTANCE eq SPOTIFY_STR; |
| 72 | } elsif ($ENV{'BLOCK_BUTTON'} == 4) { |
| 73 | system("playerctl $player_arg volume 0.01+"); |
| 74 | } elsif ($ENV{'BLOCK_BUTTON'} == 5) { |
| 75 | system("playerctl $player_arg volume 0.01-"); |
| 76 | } |
| 77 | } elsif ($method eq 'rhythmbox') { |
| 78 | if ($ENV{'BLOCK_BUTTON'} == 1) { |
| 79 | system("rhythmbox-client --previous"); |
| 80 | } elsif ($ENV{'BLOCK_BUTTON'} == 2) { |
| 81 | system("rhythmbox-client --play-pause"); |
| 82 | } elsif ($ENV{'BLOCK_BUTTON'} == 3) { |
| 83 | system("rhythmbox-client --next"); |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | sub cmus { |
| 89 | my @cmus = split /^/, qx(cmus-remote -Q); |
| 90 | if ($? == 0) { |
| 91 | foreach my $line (@cmus) { |
| 92 | my @data = split /\s/, $line; |
| 93 | if (shift @data eq 'tag') { |
| 94 | my $key = shift @data; |
| 95 | my $value = join ' ', @data; |
| 96 | |
| 97 | @metadata[0] = $value if $key eq 'artist'; |
| 98 | @metadata[1] = $value if $key eq 'title'; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | if (@metadata) { |
| 103 | buttons('cmus'); |
| 104 | |
| 105 | # metadata found so we are done |
| 106 | print(join ' - ', @metadata); |
| 107 | print("\n"); |
| 108 | exit 0; |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | sub mpd { |
| 114 | my $data = qx(mpc current); |
| 115 | if (not $data eq '') { |
| 116 | buttons("mpd"); |
| 117 | print($data); |
| 118 | exit 0; |
| 119 | } |
| 120 | } |
| 121 | |
| 122 | sub playerctl { |
| 123 | buttons('playerctl'); |
| 124 | |
| 125 | my $artist = qx(playerctl $player_arg metadata artist 2>/dev/null); |
| 126 | chomp $artist; |
| 127 | # exit status will be nonzero when playerctl cannot find your player |
| 128 | exit(0) if $? || $artist eq '(null)'; |
| 129 | |
| 130 | push(@metadata, $artist) if $artist; |
| 131 | |
| 132 | my $title = qx(playerctl $player_arg metadata title); |
| 133 | exit(0) if $? || $title eq '(null)'; |
| 134 | |
| 135 | push(@metadata, $title) if $title; |
| 136 | |
| 137 | print(join(" - ", @metadata)) if @metadata; |
| 138 | } |
| 139 | |
| 140 | sub rhythmbox { |
| 141 | buttons('rhythmbox'); |
| 142 | |
| 143 | my $data = qx(rhythmbox-client --print-playing --no-start); |
| 144 | print($data); |
| 145 | } |
| 146 | |
| 147 | if ($player_arg =~ /mpd/) { |
| 148 | mpd; |
| 149 | } |
| 150 | elsif ($player_arg =~ /cmus/) { |
| 151 | cmus; |
| 152 | } |
| 153 | elsif ($player_arg =~ /rhythmbox/) { |
| 154 | rhythmbox; |
| 155 | } |
| 156 | else { |
| 157 | playerctl; |
| 158 | } |
| 159 | print("\n"); |