changeset 3212:59b84ca1b09c trunk

Added my g15composer-based Python script for displaying Now Playing info on the LCD of the Logitech G15 Gaming Keyboard.
author ssokolow@localhost.localdomain
date Wed, 01 Aug 2007 22:04:59 -0400
parents f571be95b0b6
children faf6daa29d5c
files contrib/g15_audacious.py
diffstat 1 files changed, 129 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/g15_audacious.py	Wed Aug 01 22:04:59 2007 -0400
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+"""g15_audacious.py
+By: Stephan Sokolow (deitarion/SSokolow)
+
+Audacious Media Player Monitor applet for the Logitech G15 Gaming Keyboard's LCD (via g15composer)
+
+Requires Audacious 1.4 or newer. (Uses the D-Bus API)
+
+TODO: 
+- Every second update should skip the D-Bus calls. They are the biggest CPU drain.
+  (I also only use a half-second update interval for the scroller. Feel free to 
+   turn it off and use a 1-second interval.
+- Clean up this quick hack of a script.
+
+Notes for people hacking this script:
+- The LCD is 160px wide and 43px tall
+- The Large  (2 or L) font is 7 pixels tall.
+- The Medium (1 or M) font is 6 pixels tall.
+- The Small  (0 or S) font is 5 pixels tall.
+- When using the small font, the screen is 40 characters wide.
+"""
+
+control_pipe = "/var/run/g15composer"
+
+ICON_DIMS = (7,7)
+ICN_STOP = "1" * ICON_DIMS[0] * ICON_DIMS[1]
+ICN_PAUSE = "0110110" * ICON_DIMS[1]
+ICN_PLAY = (
+"0100000" +
+"0110000" +
+"0111000" +
+"0111100" +
+"0111000" +
+"0110000" +
+"0100000" )
+
+# I prefer no icon when it's playing, so overwrite the play icon with a blank.
+ICN_PLAY = '0' * ICON_DIMS[0] * ICON_DIMS[1]
+
+
+import os, sys, time
+from dbus import Bus, DBusException
+
+message_pipe = os.path.join(os.environ["HOME"], ".g15_audacious_pipe")
+
+def get_aud():
+	try: return session_bus.get_object('org.atheme.audacious', '/org/atheme/audacious')
+	except DBusException: return None
+
+def draw_state(icon):
+	msg_handle.write('PO 0 0 %d %d "%s"\n' % (ICON_DIMS[0], ICON_DIMS[1], icon))
+
+session_bus = Bus(Bus.TYPE_SESSION)
+
+if not os.path.exists(control_pipe) and not (os.path.isfile(control_pipe) and os.path.isdir(control_pipe)):
+	print "ERROR: Not a g15composer control pipe: %s" % control_pipe
+	sys.exit(1)
+
+if os.path.exists(message_pipe) and not (os.path.isfile(control_pipe) and os.path.isdir(control_pipe)):
+	os.remove(message_pipe)
+
+try:
+	file(control_pipe, 'w').write('SN "%s"\n' % message_pipe)
+	time.sleep(0.5)
+	msg_handle = file(message_pipe,'w')
+
+	oldTitleString = ''
+	while True:
+		aud = get_aud()
+		if aud:
+			pos = aud.Position()
+
+			lengthSecs = aud.SongLength(pos)
+			length = (lengthSecs > 0) and ("%d:%02d" % (lengthSecs / 60, lengthSecs % 60)) or "stream"
+
+			songTitle = aud.SongTitle(pos).encode("latin1", "replace")
+			titleString = "%d. %s" % (pos, songTitle)
+
+			playSecs = aud.Time() / 1000
+			played = "%d:%02d" % (playSecs / 60, playSecs % 60)
+
+			volume = aud.Volume()
+
+			# Cache changes until I'm done making them
+			msg_handle.write('MC 1\n')
+
+			# Set up the static elements
+			msg_handle.write('TO 0 0 2 1 "Now Playing"\n')
+			msg_handle.write('TO 0 26 0 0 "Volume:"\n')
+
+			# State Indicator
+			if aud.Paused():
+				draw_state(ICN_PAUSE)
+			elif aud.Playing(): 
+				draw_state(ICN_PLAY)
+			else:
+				draw_state(ICN_STOP)
+
+			# Scroll the title string
+			if len(titleString) > 40 and oldTitleString == titleString:
+				tsTemp = titleString + '   '
+				titleString = tsTemp[scrollPivot:] + tsTemp[:scrollPivot]
+				scrollPivot = (scrollPivot < len(tsTemp)) and (scrollPivot + 1) or 0
+			else:
+				scrollPivot = 0
+				oldTitleString = titleString
+
+			# Title
+			msg_handle.write('PB 0 9 160 14 0 1 1\n') # Wipe away any remnants of the old title that wouldn't be overwritten.
+			msg_handle.write('TO 0 9 0 0 "%s"\n' % titleString)
+
+			# Volume bar
+			msg_handle.write('DB 29 28 159 29 1 %d 100 1\n' % ((volume[0] + volume[1])/2))
+
+			# Progress Bar
+			msg_handle.write('DB 0 33 159 41 1 %d %d 1\n' % (playSecs, lengthSecs))	# Progress Bar
+			msg_handle.write('MX 1\n')
+			msg_handle.write('TO 0 34 2 1 "Position: %s/%s"\n' % (played, length)) # Progress Text
+			msg_handle.write('MX 0\n')
+
+			# Push changes to the display and sleep for a second.
+			msg_handle.write('MC 0\n')
+			msg_handle.flush()
+			time.sleep(0.5)
+		else:
+			msg_handle.write('PC 0\nTL "D-Bus Exception:" "Can\'t find Audacious"\n"')
+finally:
+	msg_handle.write("SC\n")
+	msg_handle.close()