musicplay.py
#!/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:由于近段时间比较忙,所以还有很多功能只是写了开头部分,没有完整实现,而且很多代码都没有优化,等有时间再实现和优化吧。
效果图: