Skip to content

Instantly share code, notes, and snippets.

@son-link
Created March 27, 2012 18:29
Show Gist options
  • Save son-link/2218801 to your computer and use it in GitHub Desktop.
Save son-link/2218801 to your computer and use it in GitHub Desktop.
Systray CD Player
#!/usr/bin/python2
# -*- coding: utf-8 -*-
# Systray CD Player: Reproduce tus CDs de audio desde la bandeja del sistema
# (c) 2012 Alfonso Saavedra "Son Link"
# http://sonlinkblog.blogspot.com.es/p/scripts.html
# Under GPLv3 License
import pygst
pygst.require("0.10")
import gst
import gobject, gtk
import sys, thread, time
from ConfigParser import ConfigParser
from os import system, environ
from os.path import isfile
gobject.threads_init()
configfile = environ['HOME']+'/.scdp'
class Plugin():
def __init__(self):
self.actual_track = 1
self.status = -1
# -1 -> No hace nada, 0 Stop, 1 play, 2 pause
self.if_updates = False
self.is_running = False
self.info = ''
self.cfg = ConfigParser()
self.readconfig()
self.statusicon = gtk.StatusIcon()
self.statusicon.set_from_stock(gtk.STOCK_CDROM)
self.statusicon.connect("popup-menu", self.show_menu)
#Init the thread for check update packages
self.thread = thread.start_new_thread(self.play, ())
#self.play(1)
def show_menu(self, icon, button, time):
menu = gtk.Menu()
# Play
self.play_button = gtk.ImageMenuItem(stock_id=gtk.STOCK_MEDIA_PLAY)
self.play_button.connect('activate', self.play)
menu.append(self.play_button)
# Next
about = gtk.ImageMenuItem(stock_id=gtk.STOCK_MEDIA_NEXT)
about.connect('activate', self.next)
menu.append(about)
# Previous
config = gtk.ImageMenuItem(stock_id=gtk.STOCK_MEDIA_PREVIOUS)
config.connect('activate', self.prev)
menu.append(config)
stop = gtk.ImageMenuItem(stock_id=gtk.STOCK_MEDIA_STOP)
stop.connect('activate', self.stop)
menu.append(stop)
eject = gtk.MenuItem(label='Expulsar')
eject.connect('activate', self.eject)
menu.append(eject)
sep = gtk.SeparatorMenuItem()
menu.append(sep)
config = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES)
config.connect('activate', self.configure)
menu.append(config)
salir = gtk.ImageMenuItem(stock_id=gtk.STOCK_QUIT)
salir.connect('activate', self.quit)
menu.append(salir)
menu.show_all()
menu.popup(None, None, gtk.status_icon_position_menu, button, time, self.statusicon)
def play(self, *args):
if self.status == 1:
self.pipeline.set_state(gst.STATE_PAUSED)
self.play_button = gtk.ImageMenuItem(stock_id=gtk.STOCK_MEDIA_PLAY)
self.status = 2
elif self.status == 2:
self.play_button = gtk.ImageMenuItem(stock_id=gtk.STOCK_MEDIA_PAUSE)
self.pipeline.set_state(gst.STATE_PLAYING)
self.status = 1
else:
self.create_pipeline()
self.pipeline.set_state(gst.STATE_PLAYING)
self.status = 1
def prev(self, w, *args):
if self.actual_track > 1:
self.actual_track -= 1
self.pipeline.set_state(gst.STATE_READY)
self.pipeline.get_by_name("cdda").set_property("track", self.actual_track)
self.pipeline.set_state(gst.STATE_PLAYING)
self.update_info()
def stop(self, *args):
try:
self.pipeline.set_state(gst.STATE_NULL)
except:
pass
self.status = 0
def next(self, w, *args):
if self.actual_track < self.file_tags['track-count']:
self.actual_track += 1
else:
self.actual_track = 1
self.pipeline.set_state(gst.STATE_READY)
self.pipeline.get_by_name("cdda").set_property("track", self.actual_track)
self.pipeline.set_state(gst.STATE_PLAYING)
self.update_info()
def eject(self, w, *args):
self.stop()
system('eject '+ device)
def create_pipeline(self):
cdsrc = 'cdparanoiasrc device=%s track=%i name=cdda ! audioconvert ! volume name=volume ! alsasink' % (self.device, self.actual_track)
self.pipeline = gst.parse_launch(cdsrc)
bus = self.pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message::tag", self.bus_message_tag)
bus.connect("message::error", self.bus_message_error)
bus.connect("message::eos", self.next)
def bus_message_error(self, bus, message):
e, d = message.parse_error()
self.statusicon.set_tooltip_text("ERROR: "+ str(e))
def bus_message_tag(self, bus, message):
"""Esta es la función encargada de recoger los datos del bus de Gstreamer, principalmente los tags de los ficheros de audio"""
self.file_tags = {}
taglist = message.parse_tag()
for key in taglist.keys():
try:
self.file_tags[key] = taglist[key]
except:
return False
self.update_info()
def update_info(self):
if self.actual_track < 10:
track = '0'+str(self.actual_track)
else:
track = str(self.actual_track)
if self.file_tags['track-count'] < 10:
total_tracks = '0'+str(self.file_tags['track-count'])
else:
total_tracks = str(self.file_tags['track-count'])
self.statusicon.set_tooltip_text('Pista ' + track + ' de ' + total_tracks)
def readconfig(self):
if not isfile(configfile):
f = open(configfile, 'w')
f.write("[scdp]\ndevice=/dev/sr0")
self.cfg.read([configfile])
self.device = self.cfg.get('scdp', 'device')
def configure(self, w):
configwin = gtk.Dialog("Configuración Systray CD Player", buttons=(gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
def __saveconfig(w, res):
# Destroy the configuratión dialog
if res == gtk.RESPONSE_ACCEPT:
# If press Accept, save the new configuration
cfg = ConfigParser()
cfg.read([configfile])
cfg.set('scdp', 'device', self.device_entry.get_text())
f = open(configfile, "w")
cfg.write(f)
f.close()
self.stop()
self.actual_track = 1
self.status = -1
self.device = self.device_entry.get_text()
self.play()
w.destroy()
hbox = gtk.HBox()
configwin.vbox.add(hbox)
label = gtk.Label(str='Dispositivo')
label.set_alignment(0, 0)
label.set_padding(5, 5)
hbox.pack_start(label, False, False, 0)
self.device_entry = gtk.Entry()
self.device_entry.set_text(self.device)
hbox.pack_start(self.device_entry, False, False, 0)
configwin.connect("response", __saveconfig)
configwin.show_all()
def quit(self, w):
exit()
if __name__ == '__main__':
Plugin()
gtk.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment