Tag Archives: conky

Control Pulseaudio from Shell

As you know I mainly use Fluxbox on a minimal Ubuntu installation without access to all the every-day functionality provided by panel applets in Gnome, including volume control. Therefore, I have been using pavucontrol for controlling Pulseaudio. It is a really nice application that gives you very finegrained control, for instance over which application should be how loud. Lately I have been annoyed with opening a whole application just for the sake of adjusting volume a little bit, so I set out to find a way to control it via shell. Turns out there is no convenient interface to pulseaudio at all, leaving me to script something together, this time in Ruby. It uses a very unwieldy interface to Pulseaudio named pacmd, contained in Ubuntu package pulseaudio-utils.

#!/usr/bin/ruby
def current
  c = IO::popen("pacmd \"list-sinks\" | grep volume | head -1").readlines[0]
  return c.split(" ").last.sub("%", "").strip.to_i
end

def max
  c = IO::popen("pacmd \"list-sinks\" | grep \"volume steps\" | head -1").readlines[0]
  return c.split(" ").last.strip.to_i - 1
end

def index
  c = IO::popen("pacmd \"list-sinks\" | grep index | head -1").readlines[0]
  return c.split(" ").last.strip.to_i
end

def set(v)
  IO::popen("pacmd \"set-sink-volume #{index} #{v}\"").readlines
end

def muted
  c = IO::popen("pacmd \"list-sinks\" | grep muted | head -1").readlines[0]
  return c.split(" ").last.strip == "yes"
end

def toggle
  t = 1
  if ( muted )
    t = 0
  end
  IO::popen("pacmd \"set-sink-mute #{index} #{t}\"").readlines
end

interval = 5

if ( ARGV.size == 0 )
  puts current
elsif (ARGV[0] == "?" )
  puts muted
elsif ( ARGV[0] == "+" )
  set([current + interval, 100].min * (max / 100.0).round)
elsif ( ARGV[0] == "-" )
  set([current - interval, 0].max * (max / 100.0).round)
elsif ( ARGV[0] == "!" )
  toggle
end

This is certainly not the most efficient way to do it, retrieving all the info multiple times, but it works and I do not perceive any delays. Note that the script will just use the first sink that pacmd prints, so if you have a setup with multiple sinks you will have to be more clever.

Of course, the obligatory Fluxbox key bindings

None XF86AudioLowerVolume :execCommand pavol -
None XF86AudioRaiseVolume :execCommand pavol +
None XF86AudioMute :execCommand pavol !

and conky volume display:

Vol: ${exec if [ `pavol ?` != 'true' ]; then echo `pavol`%; else echo 'Muted'; fi}

Update: The script now has a home on GitHub.

Cover Art With conky And mpd

After one year of using mpd on my Fluxbox machine I have started to sift through my music collection, fixing tags and adding album covers. Since there is no need for having album art if you do not show it, I set out to make conky show the images on my disk. I was lucky to find script in the depth of some forum (reference lost) that inspired the following piece of bash code.

#!/bin/bash
IFS=$'\t' mpd_array=( $(MPD_HOST=localhost MPD_PORT=6600 \
          mpc --format "\t%artist%\t%album%\t%file%\t") );

filename="conky_cover.png";
placeholder="/path/to/placeholder.png"

if [[ ! -f /tmp/"${mpd_array[1]}".album ]] ; then
  rm -f /tmp/*.album &> /dev/null;
  >/tmp/"${mpd_array[1]}".album;

  album=`dirname "/path/to/music/${mpd_array[2]}"`;
  cover=$album"/"`ls $album | egrep "jpeg|jpg|png|gif" | head -n 1`;

  if [[ ! -f $cover ]]; then
    cp $placeholder /tmp/$filename;
  else
    convert $cover -resize "130>x" -alpha On -channel A \
                   -evaluate set 25% /tmp/$filename;
  fi
fi

When this script is run, the currently playing album’s artist and name are retrieved and the corresponding image — or a dummy — is copied to /tmp for conky to pick up. Note that always the first image in the album’s folder is chosen and then manipulated with imagemagick; you might have to do a little coding yourself if you store your music or covers differently. Note that all time consuming stuff is done only once per album run.

On the conky side, life is easy now. Just add something like this to your .conkyrc:

${if_running mpd}
MPD: ${alignr}${mpd_status}${if_mpd_playing}
 ${mpd_artist 25}
 ${mpd_album 25}
 ${mpd_title 25}
 ${mpd_bar 3,130}
 ${exec ~/bin/conky_mpd_art}${image /tmp/conky_cover.png -p 3,772 -s 130x130 -n}
${endif}
${endif}

You have to adapt the visual thingies to your liking, of course.

[PLR] Spezialanwendungen

conky in Aktion

Außer den üblichen Stücken Software habe ich noch etwas speziellere Dinge installiert. Zum einen conky, um stets gewisse Systemparameter im Auge halten zu können, und unison sowie synergy, um der besonderen Mehrrechnersituation am Schreibtisch gerecht zu werden.

conky

conky ist ein Programm, das dem Anwender Output von zahlreichen Sensoren und Prozessen visuell aufbereitet anbietet. Es ist hochgradig an die jeweiligen Bedürfnisse anpassbar und wird über eine Textdatei eingestellt. conky sucht zuerst nach ~/.conkyrc. Positionierung, Auswahl der anzuzeigenden Daten und Darstellung mit Fonts und Farben lassen sich mit einer mehr oder weniger eingängigen Syntax konfigurieren. Eine komplette Übersicht über die möglichen Parameter und Variablen gibt es hier, eine Reihe von Beispielen inklusive der zugehörigen Konfigurationsdateien hier. Mein eigenes Setup basiert auf einem der dort angegebenen Beispiele. Erwähnenswert finde ich, dass man Teile optional einbinden kann: nur, wenn eine Partition eingebunden ist, zeige ihren freien Platz an, und nur, wenn mpd auch läuft, frage den aktuellen laufenden Titel ab. Dies ist einerseits nützlich, andererseits auch angebracht, da sonst unter Umständen Fehler erzeugt werden. conky ist unter diesen Namen in den Repositories von Ubuntu verfügbar und läuft bei Bedarf als Daemon.

synergy

Für leistungshungrige Anwendungen und Spiele unter Windows habe ich weiterhin meinen alten Desktoprechner unterm Schreibtisch stehen. Da er nur selten läuft und Schreibtischplatz obligatorisch knapp ist, wollte ich möglichst wenig Peripherie doppeln. Über einen Freund hatte ich schon vor Jahren von synergy gehört, das in Software Eingabegeräte in einer Sterntopologie multiplext. Man erklärt einen Rechner zum Server; an diesen ist die Hardware angeschlossen, in meinem Fall Tastatur, Maus und Fernbedienung. Sound- und Videogeräte kann synergy noch nicht verteilen. Der Server muss das komplette Setup kennen. So legt man fest, welcher Client auf welcher Seite des Servers liegt. Clients identifizieren sich über einen Namen, der folgerichtig eindeutig für einen Stern sein muss. Ist ein Client verbunden, schiebt man die Maus über die entsprechende Bildschirmkante und landet auf dem Schirm des Clients. Zurück gelangt man natürlich genauso. Übrigens wird die Zwischenablage der verbundenen Rechner gekoppelt. Es ist also möglich, auf Rechner A etwas zu kopieren und auf Rechner B einzufügen. Ich fand das schon öfter sehr praktisch. In meinem Fall benutzen natürlich beide Rechner den gleichen Monitor, den ich also stets umschalten muss, wenn ich zwischen den Rechnern wechsle. Erwähnenswert ist noch, dass synergy für Linux, Mac OS und Windows zur Verfügung steht und gemischte Setups explizit unterstützt. Die in den Repositories von Ubuntu verfügbare Version wird anscheinend nicht länger vom Originalautor weiterentwickelt; ich habe mit ihr bisher keinerlei Probleme gehabt. Für Leute, bei denen sich Bugs manifestieren oder die neugieriger als ich sind, gibt es einen Ableger, der aktiv verbessert wird.

Auf dem Server habe ich folgende Konfigurationsdatei erstellt:

# ~/.synergyconf
section: screens
  Bob:
  Charly:
end

section: links
  Bob:
        up      =       Charly
  Charly:
        down    =       Bob
end

section: options
  switchDelay = 500
end

Charly ist also oberhalb von Bob zu finden. Die einsame Option in Zeile 14 sorgt dafür, dass mir etwas Zeit am Bildschirmrand bleibt, bevor der Rechner gewechselt wird. Es gibt eine ganze Fülle an weiteren Optionen, die ich allesamt nicht vermisse. Nun meldet sich der Serverrechner selbst auch als Client an, sodass auf ich folgende zwei Befehle nach dem Login ausführe:

synergys --daemon -c ~/.synergyconf
synergyc --daemon -n Charly localhost

Zu beachten ist, dass der Server einen Moment zum Starten braucht, der Client also nicht sofort gestartet werden sollte, da sein Anmeldeversuch sonst ins Leere läuft. Ich habe das Problem umgangen, in dem ich zwischen den beiden Aufrufen weitere Programme starte.

Da der Desktoprechner Ubuntu und Windows booten kann, habe ich unter beiden Systemen synergy installieren müssen. Unter Windows war das sehr unkompliziert; in der übersichtlichen Konfigurationsoberfläche kann man direkt einstellen, dass das Programm als Dienst laufen und beim Boot gestartet werden soll, also insbesondere in der Loginmaske. Unter Ubuntu war das wesentlich komplizierter, zumindest wenn man wie ich unsauber arbeitet und kein Skript in init.d anlegt. Erschwerend kommt hinzu, dass der Loginschirm von root ausgeführt wird, die Session selbst natürlich vom User. Ich habe eine Lösung gefunden, die ich nicht als schön empfinde, aber die funktioniert. Hierfür folgende Zeilen in die genannten Dateien einfügen:

# /etc/gdm/Init/Default
killall synergyc
sleep 1
synergyc --daemon -n Bob 192.0.0.1
# /etc/gdm/PostLogin/Default
killall synergyc

Nun muss natürlich nach dem Login der Client neu gestartet werden, etwa über den entsprechenden Konfigurationsdialog von Ubuntu. Zu beachten ist noch, dass die Instanz von synergyc, die im Loginschirm läuft, root gehört. Ich hatte hier Probleme mit dem Tastaturlayout, da root bei mir amerikanisches Layout hatte, sonst alle Rechner und Nutzer natürlich deutsches. Auch kann man im Loginschirm von gdm das Layout setzen. Nachdem ich überall deutsches Tastaturlayout eingestellt hatte, lief alles rund.

unison

unison dient zur Synchonisation von Daten zwischen zwei Verzeichnissen auf einem oder verschiedenen Rechnern. Es arbeitet dabei symmetrisch, Änderungen beider Seiten werden also gleichberechtigt übertragen, wobei Konflikte bearbeitet werden. Ein ausführliches Handbuch gibt es beim Schöpfer, das man durchaus einmal querlesen sollte. Dadurch, dass kein Rechner als ausgezeichneter Server dient, kann man unison sehr flexibel einsetzen; ich habe mich trotzdem für eine Sterntopologie entschieden, um weniger Potential für Konflikte und veraltete Kopien zu haben. Das Tool legt eine Datenbank der zu synchronisierenden Daten an, um die einzelnen Abgleiche schnell ausführen zu können. Das erstmalige Erstellen dieser Datenbank kann für große Datenmengen schon mal einige Stunden dauern, dafür liegen die Abgleichzeiten später deutlich unter einer Minute, Übertragungszeiten nicht mitgerechnet. Ich übertrage mit SSH, was vergleichsweise langsam, dafür aber sicher ist. Im lokalen Netzwerk kann man direkt Sockets ansprechen, was die Übertragungsgeschwindkeit deutlich erhöhen sollte. Dafür kann dann stets nur ein Clientprozess bedient werden. Eine Konfigurationsdatei sieht etwa so aus:

# ~/.unison/daten
mountpoint = .
batch = true

root = /media/data/Daten
root = ssh://raphael@192.0.0.1//media/data/Daten

Besonders wichtig ist die Option mountpoint; durch sie wird geprüft, ob die angegebenen Verzeichnisse überhaupt existieren. Dies verhindert, dass eine nicht eingebundene Partition als Löschung interpretiert und die verfügbare Kopie komplett gelöscht wird.  Die Option batch unterbindet Zwischenfragen bei Änderungen und synchronisiert, ohne nachzufragen. Auch hier gibt es viel mehr Optionen, die komplizierte Szenarien abbildbar machen. Ausgeführt wird eine Synchronisierung dann durch Eingabe von

unison daten

Update: Habe das Layout von conky etwas gefälliger und ordentlicher gestaltet.