#!/usr/bin/env python """A simple CD player using wxPython and cdcd. Requirements: - wxPython. - You need cdcd installed. cdcd is a command line or console based CD player it supports CDDB lookups and all. You can get it here: http://libcdaudio.sourceforge.net/ Features: - terribly simple. - supports CDDB lookups. Bugs: Since it depends on CDCD it AFAIK it wont work on Win32. License: Python License. Author: Prabhu Ramachandran """ #from wxPython.wx import * import wx import os, operator, string def cd_command(cmd, ret=0): if ret: return os.popen(cmd) else: os.system(cmd) def get_seconds(str): """Returns number of seconds given a string of form hh:mm:ss""" f = str.split(':') sec = 0 for i in f: try: v = int(i) except ValueError: # oops! Wrong arg. return 0 else: sec = 60*sec + v return sec def get_time_string(sec): """Returns a string of form mm:ss given seconds""" s = int(sec) return "%02d:%02d"%(s/60, s%60) class CDTimer(wx.Timer): def __init__(self, master): wx.Timer.__init__(self) self.master = master def Start(self, dt): """dt here is in seconds.""" dt = dt*1000 # milliseconds to seconds if self.IsRunning(): pass else: wx.Timer.Start(self, dt) def Notify(self): self.master.UpdateTime() class CDPlayerControls(wx.Panel): STOP=0 PLAY=1 PAUSE=2 def __init__(self, parent, id): wx.Panel.__init__(self, parent, id) self.status = self.STOP self.timer = CDTimer(self) self.count = None self.tot_count = 0 self.update_time = 1 # seconds self.cd_info = "" self.tool_txt = "" self._setup_gui() self.GetStatus() self.UpdateText() if self.status == self.PLAY: self.timer.Start(self.update_time) def _setup_gui(self): sizer = wx.BoxSizer(wx.VERTICAL) self.info = wx.TextCtrl(self, -1, "Playing: ", style=wx.TE_READONLY) sizer.Add(self.info, 1, wx.EXPAND|wx.ALIGN_LEFT, 5) self.info.SetToolTip(wx.ToolTip("")) wx.EVT_CHAR(self.info, self.EvtChar) # The player buttons buttons = self._setup_buttons() sizer.Add(buttons, 1, wx.EXPAND | wx.ALIGN_CENTER, 20) self.SetAutoLayout(1) self.SetSizer(sizer) sizer.Fit(self) sizer.SetSizeHints(self) def _setup_buttons(self): sizer = wx.BoxSizer(wx.HORIZONTAL) # player buttons. ID = wx.NewId() but = wx.Button(self, ID, "<<", size=(5,30)) but.SetToolTip(wx.ToolTip("Previous Track")) wx.EVT_BUTTON(self, ID, self.EvtPrev) wx.EVT_CHAR(but, self.EvtChar) sizer.Add(but, 1, wx.ALL, 0) ID = wx.NewId() but = wx.Button(self, ID, "->", size=(5,30)) but.SetToolTip(wx.ToolTip("Play")) wx.EVT_BUTTON(self, ID, self.EvtPlay) wx.EVT_CHAR(but, self.EvtChar) sizer.Add(but, 1, wx.ALL, 0) ID = wx.NewId() but = wx.Button(self, ID, "||", size=(5,30)) but.SetToolTip(wx.ToolTip("Pause/Resume")) wx.EVT_BUTTON(self, ID, self.EvtPause) wx.EVT_CHAR(but, self.EvtChar) sizer.Add(but, 1, wx.ALL, 0) ID = wx.NewId() but = wx.Button(self, ID, "#", size=(5,30)) but.SetToolTip(wx.ToolTip("Stop")) wx.EVT_BUTTON(self, ID, self.EvtStop) wx.EVT_CHAR(but, self.EvtChar) sizer.Add(but, 1, wx.ALL, 0) ID = wx.NewId() but = wx.Button(self, ID, ">>", size=(5,30)) but.SetToolTip(wx.ToolTip("Next Track")) wx.EVT_BUTTON(self, ID, self.EvtNext) wx.EVT_CHAR(but, self.EvtChar) sizer.Add(but, 1, wx.ALL, 0) ID = wx.NewId() but = wx.Button(self, ID, "?", size=(5,30)) but.SetToolTip(wx.ToolTip("Update")) wx.EVT_BUTTON(self, ID, self.EvtUpdate) wx.EVT_CHAR(but, self.EvtChar) sizer.Add(but, 1, wx.ALL, 0) return sizer def SetToolText(self): if len(self.tool_txt) > 0: self.tool_txt[-1] = " ".join(self.cd_info) txt = reduce(operator.add, self.tool_txt) self.info.GetToolTip().SetTip(txt) def GetCDInfo(self): a = cd_command('cdcd info', 1).readlines() self.tool_txt = a #self.tool_txt = map(string.strip, a) self.cd_info = a[-1].split() if self.cd_info: self.tot_count = get_seconds(self.cd_info[-1]) def GetStatus(self): self.GetCDInfo() mode = self.cd_info[0] if mode == 'Paused:': status = self.PAUSE elif mode == 'Stopped': status = self.STOP elif mode == 'Playing:': status = self.PLAY else: status = self.STOP if self.status != status: if status == self.PLAY: self.timer.Start(self.update_time) elif status in [self.STOP, self.PAUSE]: self.timer.Stop() self.status = status def UpdateText(self): if self.status == self.STOP: self.info.SetValue("Stopped: ") else: self.GetCDInfo() if self.status != self.STOP: self.count = get_seconds(self.cd_info[-3]) self.info.SetValue(" ".join(self.cd_info)) self.SetToolText() def UpdateTime(self): if self.status == self.PLAY: self.count = self.count + self.update_time if self.count > self.tot_count: self.GetStatus() self.SetToolText() if self.status == self.STOP: self.timer.Stop() else: self.count = get_seconds(self.cd_info[-3]) if self.status == self.PLAY: # status may have changed. self.cd_info[-3] = get_time_string(self.count) self.info.SetValue(" ".join(self.cd_info)) def EvtUpdate(self, event): self.GetStatus() self.UpdateText() def EvtPlay(self, event): if self.status == self.STOP: cd_command('cdcd play') self.status = self.PLAY self.UpdateText() self.timer.Start(self.update_time) elif self.status == self.PAUSE: cd_command('cdcd resume') self.status = self.PLAY self.UpdateText() self.timer.Start(self.update_time) def EvtPause(self, event): if self.status == self.PLAY: cd_command('cdcd pause') self.timer.Stop() self.status = self.PAUSE self.UpdateText() elif self.status == self.PAUSE: cd_command('cdcd resume') self.status = self.PLAY self.UpdateText() self.timer.Start(self.update_time) def EvtNext(self, event): cd_command('cdcd next') self.status = self.PLAY self.timer.Stop() self.UpdateText() self.timer.Start(self.update_time) def EvtPrev(self, event): cd_command('cdcd prev') self.status = self.PLAY self.timer.Stop() self.UpdateText() self.timer.Start(self.update_time) def EvtStop(self, event): cd_command('cdcd stop') self.status = self.STOP self.timer.Stop() self.UpdateText() def EvtChar(self, event): if event.GetKeyCode() == ord('z'): self.EvtPrev(event) if event.GetKeyCode() == ord('x'): self.EvtPlay(event) if event.GetKeyCode() == ord('c'): self.EvtPause(event) if event.GetKeyCode() == ord('v'): self.EvtStop(event) if event.GetKeyCode() == ord('b'): self.EvtNext(event) if event.GetKeyCode() in (ord('n'), ord('?')): self.EvtUpdate(event) class wxCDPlayer(wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent, -1, "wxCDPlayer", size=(350,55)) panel = CDPlayerControls(self, -1) self.Show(1) panel.UpdateText() if __name__ == "__main__": app = wx.PySimpleApp() frame = wxCDPlayer(None) frame.Show(1) app.MainLoop()