#!/usr/bin python #-*-coding:utf-8 -*- import wx import ConfigParser import os.path from Operation import OperationPanel from Show import ShowPanel class MainFrame(wx.Frame): def __init__(self,parent,id): wx.Frame.__init__(self,parent,id,title='music player',size=(380,700), style=wx.DEFAULT_FRAME_STYLE&(~wx.MAXIMIZE_BOX)&(~ wx.RESIZE_BORDER)) self.parser = ConfigParser.ConfigParser() self.playlist = None self.musiclist = [] self.musicnames = [] self.initPlayList() self.initMusicList() self.splitter = wx.SplitterWindow(self) self.operationPanel = OperationPanel(self.splitter,wx.NewId(),self.playlist,self.musiclist) self.showPanel = ShowPanel(self.splitter,wx.NewId(),self.musicnames) self.splitter.SplitHorizontally(self.operationPanel,self.showPanel,100) self.splitter.SetMinimumPaneSize(100) self.initMenuBar() def initPlayList(self): self.parser.read('config.conf') self.playlist = str(self.parser.get('PlayList','PlayListDir')) + "/" + str(self.parser.get('PlayList','lastPlayList')) def initMusicList(self): f = open(self.playlist) self.musiclist = [x[:-1] for x in f.readlines()] f.close() self.musicnames = [os.path.basename(x) for x in self.musiclist] def initAddMenu(self): self.addMenu = wx.Menu() self.addFileId = wx.NewId() self.addDirId = wx.NewId() title_list = [u'文件',u'文件夹'] self.appendMenuItem(self.addMenu, [self.addFileId,self.addDirId], title_list) def initDelMenu(self): self.delMenu = wx.Menu() self.delSelId = wx.NewId() self.delDuplicateId = wx.NewId() self.delErrId = wx.NewId() self.delAllId = wx.NewId() self.delPhyicalId = wx.NewId() title_list = [u'选中的文件',u'重复的文件',u'错误的文件','',u'全部删除','',u'物理删除'] self.appendMenuItem(self.delMenu, [self.delSelId,self.delDuplicateId,self.delErrId,'separator',self.delAllId,'separator',self.delPhyicalId], title_list) def initPlayListMenu(self): self.playlistMenu = wx.Menu() self.newPlayListId = wx.NewId() self.addPlayListId = wx.NewId() self.openPlayListId = wx.NewId() self.savePlayListId = wx.NewId() self.delPlayListId = wx.NewId() self.saveAllPlayListId = wx.NewId() title_list = [u'新建列表',u'添加列表',u'打开列表',u'保存列表',u'删除列表','',u'保存所有列表'] self.appendMenuItem(self.playlistMenu, [self.newPlayListId,self.addPlayListId,self.openPlayListId,self.savePlayListId,self.delPlayListId,'separator',self.saveAllPlayListId], title_list) def initSortMenu(self): self.sortMenu = wx.Menu() self.sortByFileNameId = wx.NewId() self.sortByFilePathId = wx.NewId() self.sortByFileTypeId = wx.NewId() title_list = [u'按文件名',u'按文件路径',u'按文件类型'] self.appendMenuItem(self.sortMenu, [self.sortByFileNameId,self.sortByFilePathId,self.sortByFileTypeId], title_list) def initFindMenu(self): self.findMenu = wx.Menu() self.fastLocateId = wx.NewId() self.findMusicId = wx.NewId() title_list = [u'快速定位',u'查找歌曲'] self.appendMenuItem(self.findMenu, [self.fastLocateId,self.findMusicId], title_list) def initModeMenu(self): self.modeMenu = wx.Menu() self.single = wx.NewId() self.singleCycle = wx.NewId() self.sequence = wx.NewId() self.cycle = wx.NewId() self.random = wx.NewId() title_list = [u'单曲播放',u'单曲循环',u'顺序播放',u'循环播放',u'随机播放'] self.appendMenuItem(self.modeMenu, [self.single,self.singleCycle,self.sequence,self.cycle,self.random], title_list) def appendMenuItem(self,menu,id_list,title_list): length = len(id_list) for i in range(length): if id_list[i] == 'separator': menu.AppendSeparator() else: menu.Append(id_list[i],title_list[i]) def append2MenuBar(self,menu_list,title_list): length = len(menu_list) for i in range(length): self.menuBar.Append(menu_list[i],title_list[i]) def initMenu(self): self.initAddMenu() self.initDelMenu() self.initPlayListMenu() self.initSortMenu() self.initFindMenu() self.initModeMenu() def initMenuBar(self): self.initMenu() self.menuBar = wx.MenuBar() self.append2MenuBar( [self.addMenu,self.delMenu,self.playlistMenu,self.sortMenu,self.findMenu,self.modeMenu], [u'添加',u'删除',u'播放列表',u'排序',u'查找',u'播放模式']) self.SetMenuBar(self.menuBar) if __name__ == '__main__': app = wx.PySimpleApp() frame =MainFrame(parent=None,id=wx.NewId()) frame.Show() app.MainLoop()
#!/usr/bin python #-*-coding:utf-8 -*- import wx.media import os import ConfigParser from wx.media import MediaCtrl wildcard = "mp3 file (*.mp3)|*.mp3|" \ "wav file (*.wav)|*.wav|" \ "All file (*.*)|*.*" class CustomPopupWindow(wx.PopupWindow): def __init__(self,parent,text='',style=wx.BORDER_NONE): wx.PopupWindow.__init__(self,parent,style) self.statictext = wx.StaticText(self,label=text) def SetText(self,text): self.statictext.SetLabel(text) class OperationPanel(wx.Panel): def __init__(self,parent,id,playlist,musiclist): wx.Panel.__init__(self,parent,id,size=(380,100), style=wx.SUNKEN_BORDER) self.allfilepath = musiclist self.playlist = playlist self.newfilepaths = [] self.newfilenames = [] self.count = 0 self.preIndex = 0 self.curIndex = 0 self.nextIndex = 0 self.volume = 0.0 self.parser = ConfigParser.ConfigParser() self.initConfig() self.mc = MediaCtrl(self,style=wx.SIMPLE_BORDER,szBackend=wx.media.MEDIABACKEND_WMP10) self.createSlider() self.createButton() self.bindEvents() self.createTimer() self.startPlayMusic() def startPlayMusic(self): self.LoadFile(self.allfilepath[self.curIndex]) def initConfig(self): self.parser.read('config.conf') self.count = int(self.parser.get('Index','count')) self.preIndex = int(self.parser.get('Index', 'preIndex')) self.curIndex = int(self.parser.get('Index', 'curIndex')) self.nextIndex = int(self.parser.get('Index', 'nextIndex')) self.workingdir = self.parser.get('Other','LastOpenDir') self.volume = self.parser.get('Other','volume') self.lastvolume = self.volume def createSlider(self): self.curmusic = wx.StaticText(self,label='test',size=(300,-1),pos=(0,5),style=wx.ALIGN_CENTRE|wx.ST_NO_AUTORESIZE) self.progress = wx.StaticText(self,label='00:00',pos=(140,25)) self.slider = wx.Slider(self,wx.NewId(),pos=(0,40),size=(300,-1)) self.slider.SetToolTipString(u'播放进度') self.volume_slider = wx.Slider(self,wx.NewId(),pos=(320,0),style=wx.SL_VERTICAL|wx.SL_INVERSE) self.volume_slider.SetRange(0,100) self.volume_slider.SetValue(30) self.volume_slider.SetToolTipString(u'音量:%d%%' %self.volume_slider.GetValue()) def createButton(self): self.stop_btn = wx.Button(self,wx.NewId(),label=u'停止',pos=(10,65),size=(45,24)) self.play_btn = wx.Button(self,wx.NewId(),label=u'播放',pos=(60,65),size=(45,24)) self.pause_btn = wx.Button(self,wx.NewId(),label=u'暂停',pos=(110,65),size=(45,24)) self.pre_btn = wx.Button(self,wx.NewId(),label=u'上一首' ,pos=(160,65),size=(45,24)) self.next_btn = wx.Button(self,wx.NewId(),label=u'下一首',pos=(210,65),size=(45,24)) self.open_btn = wx.Button(self,wx.NewId(),label=u'打开',pos=(260,65),size=(45,24)) # self.volume_btn = wx.Button(self,wx.NewId(),label=u'立体声',pos=(260,18),size=(45,20)) def bindEvents(self): self.stop_btn.Bind(wx.EVT_BUTTON,self.OnStop) self.play_btn.Bind(wx.EVT_BUTTON,self.OnPlay) self.pause_btn.Bind(wx.EVT_BUTTON,self.OnPause) self.pre_btn.Bind(wx.EVT_BUTTON,self.OnPre) self.next_btn.Bind(wx.EVT_BUTTON,self.OnNext) self.slider.Bind(wx.EVT_SLIDER, self.OnSeek) self.volume_slider.Bind(wx.EVT_SCROLL,self.ChangeVolume) self.open_btn.Bind(wx.EVT_BUTTON,self.OnOpen) # self.volume_btn.Bind(wx.EVT_BUTTON,self.OnVolume) self.mc.Bind(wx.media.EVT_MEDIA_LOADED,self.OnMediaLoaded) self.mc.Bind(wx.media.EVT_MEDIA_PLAY,self.OnMediaPlay) self.mc.Bind(wx.media.EVT_MEDIA_FINISHED,self.OnMediaFinished) def createTimer(self): self.slider_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.onUpdateSlider,self.slider_timer) self.slider_timer.Start(100) self.text_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.onUpdateText,self.text_timer) #stop the song def OnStop(self,event): self.mc.Stop() #play the song def OnPlay(self,event): self.Play() #pause the song def OnPause(self,event): self.mc.Pause() #play the previous song def OnPre(self,event): self.mc.Stop() self.LoadFileByIndex(self.preIndex) #stop the next song def OnNext(self,event): self.mc.Stop() self.LoadFileByIndex(self.nextIndex) # def OnVolume(self,event): # if self.volume_btn.GetLabel() == u'立体声': # self.volume_slider.SetValue(0) # self.setVolumeAndTip() # self.volume_btn.SetLabel(u'静音') # else: # self.volume_slider.SetValue(self.lastvolume) # self.setVolumeAndTip() # self.volume_btn.SetLabel(u'立体声') # #play the spcified position of the song def OnSeek(self,event): offset = self.slider.GetValue() self.mc.Seek(offset) def OnMediaLoaded(self,event): self.Play() self.curmusic.SetLabel(os.path.basename(self.allfilepath[self.curIndex])[:-4]) self.text_timer.Start(1000) def OnMediaPlay(self,event): showpanel = self.GetParent().GetWindow2() showpanel.setMusicFocus(self.curIndex) def OnMediaFinished(self,event): self.progress.SetLabel('00:00') self.text_timer.Stop() if self.count > 0: self.curIndex = (self.curIndex+1)%self.count self.refreshIndex(0) self.LoadFile(self.allfilepath[self.curIndex]) def OnOpen(self,event): dlg = wx.FileDialog( self,message='Choose a music file...', defaultDir=self.workingdir, defaultFile='', wildcard=wildcard, style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: self.newfilepaths = dlg.GetPaths() self.curIndex = self.count self.count += len(self.newfilepaths) self.refreshIndex(0) self.newfilenames = dlg.GetFilenames() self.refreshMusicList(self.newfilepaths) os.chdir(self.workingdir)#change the working directory to the project self.save2File(self.newfilepaths) self.LoadFile(self.newfilepaths[0]) showpanel = self.Parent.GetWindow2() showpanel.insert2ListCtrl(self.newfilenames) self.newfilepaths = [] self.newfilenames = [] dlg.Destroy() def LoadFile(self,path): if not self.mc.Load(path): wx.MessageBox("Unable to load %s: Unsupported format?" % path, "ERROR", wx.ICON_ERROR | wx.OK) else: self.mc.SetVolume(0.3) def LoadFileByIndex(self,index): self.curIndex = index self.refreshIndex(0) self.LoadFile(self.allfilepath[self.curIndex]) def Play(self): #self.mc.SetPlaybackRate(2) self.mc.Play() self.slider.SetRange(0, self.mc.Length()) def ChangeVolume(self,event): #volume range is 0.0-1.0 self.setVolumeAndTip() #move the silder to show the progress of play music def onUpdateSlider(self, evt): offset = self.mc.Tell() self.slider.SetValue(offset) def onUpdateText(self,evt): offset = self.mc.Tell()/1000 progress_text = '%02d:%02d' %(offset/60,offset%60) self.progress.SetLabel(progress_text) def setVolumeAndTip(self): value = self.volume_slider.GetValue() self.volume = value/100.0 if self.volume != 0: self.lastvolume = self.volume self.mc.SetVolume(self.volume) self.volume_slider.SetToolTipString(u'音量:%d%%' %value) def save2File(self,filepathlist): f = open(self.playlist,'a') for filepath in filepathlist: f.write(filepath+'\n') f.close() def isEmpty(self): f = open(self.mlistfile) text = f.readline() f.close() if not text: return True else: return False def refreshMusicList(self,filepathlist): for filepath in filepathlist: self.allfilepath.append(filepath) def refreshIndex(self,mode): """ mode:the play mode,like recyle,order or random """ if mode == 0: self.refreshIndexInMode0() elif mode == 1: self.refreshIndexInMode1() elif mode == 2: self.refreshIndexInMode2() def refreshIndexInMode0(self): """ mode 0:the recyle mode """ if self.count == 1: self.preIndex = 0 self.curIndex = 0 self.nextIndex = 0 #deal with that the selected item is last one elif self.curIndex+1 == self.count: self.nextIndex = 0 self.preIndex = self.curIndex - 1 #deal with that the selected item is first one elif self.curIndex == 0: self.preIndex = self.count-1 self.nextIndex = self.curIndex + 1 else: self.nextIndex = self.curIndex + 1 self.preIndex = self.curIndex - 1 def refreshIndexInMode1(self): pass def refreshIndexInMode2(self): pass def __del__(self): self.parser.read('Config.conf') self.parser.set('Index', 'count', self.count) self.parser.set('Index','preIndex',self.preIndex) self.parser.set('Index','curIndex',self.curIndex) self.parser.set('Index','nextIndex',self.nextIndex) self.parser.set('Other','LastOpenDir',self.workingdir) self.parser.write(open("Config.conf", "w"))
#!/usr/bin python #-*-coding:utf-8 -*- import wx import wx.lib.mixins.listctrl as listmix class TestListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize,style=wx.LC_REPORT|wx.LC_NO_HEADER|wx.LC_HRULES): wx.ListCtrl.__init__(self, parent, ID, pos, size,style) listmix.ListCtrlAutoWidthMixin.__init__(self) class ShowPanel(wx.Panel): def __init__(self,parent,id,musiclist): wx.Panel.__init__(self,parent,id,size=(380,600), style=wx.SUNKEN_BORDER) self.curIndex = 0 self.preIndex = 0 self.nextIndex = 0 self.itemcount = 0 self.initListCtrl() self.initListCtrlData(musiclist) self.bindEvents() self.lastindex = -1 def initListCtrl(self): self.playlist = TestListCtrl(self,wx.NewId(),size=(100,600)) self.playlist.InsertColumn(0,'test',width=100) self.playlist.InsertStringItem(0,u'默认') self.musiclist =TestListCtrl(self,wx.NewId(),pos=(100,0),size=(270,600)) self.musiclist.InsertColumn(0,'test',width=270) #self.musiclist.SetForegroundColour(wx.Colour(0,150,0)) def initListCtrlData(self,musiclist): self.insert2ListCtrl(musiclist) def insert2ListCtrl(self,data): i = self.itemcount for item in data: self.musiclist.InsertStringItem(i,str(i+1)+'.'+item) self.itemcount += 1 i += 1 def bindEvents(self): # self.musiclist.Bind(wx.EVT_LIST_ITEM_SELECTED,self.OnSelected) self.musiclist.Bind(wx.EVT_LIST_ITEM_ACTIVATED,self.OnDoubleClick) self.musiclist.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK,self.OnRightClickItem) def OnDoubleClick(self,event): index = self.musiclist.GetFirstSelected() operationpanel = self.GetParent().GetWindow1() operationpanel.LoadFileByIndex(index) def OnRightClickItem(self,event): print 'right click' self.createPopMenu() def createPopMenu(self): if not hasattr(self, "popupDel"): self.popupDel = wx.NewId() self.Bind(wx.EVT_MENU, self.OnDelItem, id=self.popupDel) menu = wx.Menu() menu.Append(self.popupDel,'Delete') self.PopupMenu(menu) menu.Destroy() def OnDelItem(self,event): pass def setMusicFocus(self,index): if self.lastindex != -1: self.musiclist.SetItemTextColour(self.lastindex,'black') self.lastindex = index self.musiclist.SetItemTextColour(index,'blue')
config.conf
[PlayList] playlistdir = PlayList lastplaylist = default [Index] count = 9 preindex = 4 curindex = 5 nextindex = 6 [Play_Mode] mode = 0 [Other] volume = 0.0 lastopendir = C:\Users\chenfeibiao\workspace\wxPythonInAction\src\cfb\musicplayer
开发环境:python2.7+wxpython2.8.12.0
功能:
1.播放mp3,wav类型的音乐,能暂停,停止当前播放的音乐,能切换到上一首,下一首
2.能调节音量
3.拖动播放进度的滚动条,即可将音乐拖到相应的进度并播放
4.通过点击打开按钮,可以添加音乐文件到播放列表
ps:由于近段时间比较忙,所以还有很多功能只是写了开头部分,没有完整实现,而且很多代码都没有优化,等有时间再实现和优化吧。
效果图: