问题描述
我正在尝试制作一个播放器,当当前歌曲结束时,它会自动播放列表中的下一首歌曲。无论我做什么,当我在绑定到 wx.media.EVT_MEDIA_STOP 或 wx.media.EVT_MEDIA_FINISHED 的类的 on_song_end 方法中添加对 Load() 的调用时,它会挂起或无限期地遍历所有项目。 我做错了什么?
import os
import wx
from wx.media import MediaCtrl
from wx.adv import Sound
import wx.lib.mixins.listctrl as listmix
import eyed3
import glob
APP_TITLE = "Crazy ID3 tag editor"
class Window(wx.Frame,listmix.ColumnSorterMixin):
def __init__(self,*args,**kwargs):
super(Window,self).__init__(*args,**kwargs)
self.InitUI()
self.create_menu()
self.update_mp3_listing("D:\\YT")
self.itemDataMap = self.row_data
listmix.ColumnSorterMixin.__init__(self,4)
def InitUI(self):
self.row_data = {}
self.row_obj_dict = {}
self.Now_playing_index = -1
self.panel = wx.Panel(self)
self.panel.SetLabel(APP_TITLE)
self.mp3_list_label = wx.StaticText(self.panel,label="List of mp3's")
self.mp3_list = MyListCtrl(self.panel,id=wx.ID_ANY,size=(-1,-1),style=wx.LC_REPORT)
self.mp3_list.InsertColumn(0,"Artist",width=140)
self.mp3_list.InsertColumn(1,"Title",width=140)
self.mp3_list.InsertColumn(2,"Album",width=200)
self.mp3_list.InsertColumn(3,"Filename",width=200)
# self.mp3_list.InsertColumn(3,"Year",width=200)
self.mp3_list.Bind(wx.EVT_LIST_ITEM_ACTIVATED,self.on_list_item_activate)
self.mp3_list.Bind(wx.EVT_LIST_ITEM_FOCUSED,self.on_item_focused)
self.mp3_list.Bind(wx.EVT_LIST_COL_CLICK,self.on_col_click)
self.edit_button = wx.Button(self.panel,label="&Edit")
self.edit_button.Bind(wx.EVT_BUTTON,self.on_edit)
self.refresh_button = wx.Button(self.panel)
self.refresh_button.Bind(wx.EVT_BUTTON,self.refresh_mp3_listing)
self.refresh_button.Hide()
self.stop_button = wx.Button(self.panel)
self.stop_button.Bind(wx.EVT_BUTTON,self.stop_song)
self.stop_button.Hide()
self.focus_Now_playing_button = wx.Button(self.panel)
self.focus_Now_playing_button.Bind(wx.EVT_BUTTON,self.focus_Now_playing)
self.focus_Now_playing_button.Hide()
self.sizer = wx.GridBagSizer(5,5)
self.sizer.Add(self.mp3_list_label,pos=(0,0),span=(1,2))
self.sizer.Add(self.mp3_list,pos=(1,1),flag=wx.EXPAND|wx.ALL)
self.sizer.Add(self.edit_button,flag=wx.ALL|wx.ALIGN_CENTER_HORIZONTAL)
self.sizer.AddGrowableRow(1)
self.sizer.AddGrowableCol(0,proportion=3)
self.sizer.AddGrowableCol(1,proportion=1)
self.panel.SetSizerAndFit(self.sizer)
self.Fit()
self.Center()
self.accelerator_table = wx.AcceleratorTable([(wx.ACCEL_norMAL,wx.WXK_F5,self.refresh_button.GetId()),(wx.ACCEL_ALT,wx.WXK_CONTROL_S,self.stop_button.GetId()),(wx.ACCEL_norMAL,wx.WXK_MEDIA_STOP,(wx.ACCEL_CTRL,wx.WXK_CONTROL_P,self.focus_Now_playing_button.GetId())])
self.SetAcceleratorTable(self.accelerator_table)
self.Show(True)
def create_menu(self):
self.menu_bar = wx.MenuBar()
self.file_menu = wx.Menu()
self.open_folder_menu_item = self.file_menu.Append(wx.ID_ANY,"Op&en folder","Open a folder with MP3s")
self.menu_bar.Append(self.file_menu,"&File")
self.Bind(wx.EVT_MENU,self.on_open_folder,self.open_folder_menu_item)
self.SetMenuBar(self.menu_bar)
def on_open_folder(self,event):
title = "Choose a directory: "
dlg = wx.DirDialog(self,title,style=wx.DD_DEFAULT_STYLE)
if dlg.ShowModal() == wx.ID_OK:
self.update_mp3_listing(dlg.GetPath())
dlg.Destroy()
def on_edit(self,event):
focused_item = self.mp3_list.GetFocusedItem()
selected_items_count = self.mp3_list.GetSelectedItemCount()
if focused_item >= 0:
if selected_items_count == 1:
if focused_item == self.Now_playing_index:
self.stop_song(event=None)
mp3 = self.row_obj_dict[self.mp3_list.GetItemData(focused_item)]
dlg = EditDialog(mp3)
dlg.ShowModal()
self.update_mp3_listing(self.current_folder_path)
dlg.Destroy()
self.mp3_list.Focus(focused_item)
else:
mp3s_to_edit = []
item = self.mp3_list.GetFirstSelected()
while item != -1:
mp3 = self.row_obj_dict[self.mp3_list.GetItemData(item)]
mp3s_to_edit.append(mp3)
item = self.mp3_list.GetNextSelected(item)
dlg = EditArtistDialog(mp3s_to_edit)
dlg.ShowModal()
self.update_mp3_listing(self.current_folder_path)
dlg.Destroy()
self.mp3_list.Focus(focused_item)
def update_mp3_listing(self,folder_path):
self.current_folder_path = folder_path
self.mp3_list.Clearall()
self.mp3_list.InsertColumn(0,width=200)
self.mp3_list.InsertColumn(2,width=140)
self.mp3_list.InsertColumn(3,width=200)
mp3s = glob.glob(folder_path + "/*.mp3")
mp3_objects = []
index = 0
for mp3 in mp3s:
mp3_object = eyed3.load(mp3)
self.mp3_list.InsertItem(index,mp3_object.tag.artist or " ")
self.mp3_list.SetItem(index,1,mp3_object.tag.title or " ")
self.mp3_list.SetItem(index,2,mp3_object.tag.album or " ")
self.mp3_list.SetItem(index,3,mp3)
self.mp3_list.SetItemData(index,index)
# self.mp3_list.SetItemData(index,[mp3_object.tag.artist or " ",mp3_object.tag.title or " ",mp3_object.tag.album or " ",mp3])
mp3_objects.append(mp3_object)
self.row_data[index] = (mp3_object.tag.artist or " ",mp3_object.tag.file_info.name)
self.row_obj_dict[index] = mp3_object
index += 1
def refresh_mp3_listing(self,event):
self.update_mp3_listing(self.current_folder_path)
def on_loaded(self,event):
self.player.Play()
# self.Now_playing_index = self.mp3_list.GetItemData(self.mp3_list.GetFocusedItem()+1)
def on_list_item_activate(self,event):
focused_item = self.mp3_list.GetFocusedItem()
mp3 = self.row_obj_dict[self.mp3_list.GetItemData(focused_item)]
self.player = MediaCtrl(parent=self,szBackend=wx.media.MEDIABACKEND_WMP10)
self.player.Load(mp3.tag.file_info.name) # tried wx.CallAfter without success
self.player.SetVolume(0.25)
self.Now_playing_index = focused_item
self.Bind(wx.media.EVT_MEDIA_LOADED,self.on_loaded,self.player)
self.Bind(wx.media.EVT_MEDIA_STOP,self.on_song_end,self.player)
if mp3.tag.artist and mp3.tag.title:
self.SetTitle(f"{APP_TITLE + ': ' + mp3.tag.artist + ' - ' + mp3.tag.title}")
else:
self.SetTitle(f"{APP_TITLE + ': ' + os.path.split(os.path.splitext(mp3.tag.file_info.name)[0])[1]} (no tags)")
def on_song_end(self,event):
self.player.Stop()
Now = self.Now_playing_index
if Now < self.mp3_list.GetItemCount()-1:
song = self.row_obj_dict[self.mp3_list.GetItemData(Now+1)]
self.Now_playing_index = Now+1
else:
song = self.row_obj_dict[self.mp3_list.GetItemData(0)]
self.Now_playing_index = 0
print(song.tag.title)
#self.player.Stop()
wx.CallAfter(self.player.Load,song.tag.file_info.name)
"""
if song.tag.artist and song.tag.title:
self.SetTitle(f"{APP_TITLE + ': ' + song.tag.artist + ' - ' + song.tag.title}")
else:
self.SetTitle(f"{APP_TITLE + ': ' + os.path.split(os.path.splitext(song.tag.file_info.name)[0])[1]} (no tags)")
"""
def stop_song(self,event):
self.player.Pause()
self.Now_playing_index = -1
self.SetTitle(APP_TITLE)
def focus_Now_playing(self,event):
if self.Now_playing_index >= 0:
self.mp3_list.Focus(self.Now_playing_index)
self.mp3_list.Select(self.Now_playing_index,on=1)
else:
Sound().PlaySound("c:/windows/media/Windows Ding.wav",wx.adv.soUND_ASYNC)
# mixin methods override
def GetListCtrl(self):
return self.mp3_list
def on_col_click(self,event):
old_order = self.mp3_list.GetColumnsOrder()
self.mp3_list.sortItems(1)
new_order = old_order
clicked_column = new_order.pop(self.mp3_list.GetColumnIndexFromOrder(event.GetColumn()))
new_order.insert(0,clicked_column)
self.mp3_list.SetColumnsOrder(new_order)
self.mp3_list.RefreshItems(0,self.mp3_list.GetItemCount()-1)
# event.Skip()
def on_item_focused(self,event):
# print(self.mp3_list.GetItemData(self.mp3_list.GetFocusedItem()))
pass
class MyListCtrl(wx.ListCtrl,listmix.ListCtrlAutoWidthMixin):
def __init__(self,parent,autoSizeColumn="LAST",itemTextCallable=None,pos=wx.DefaultPosition,size=wx.DefaultSize,style=0):
if itemTextCallable is not None:
if not isinstance(itemTextCallable,Callable):
raise TypeError("itemTextCallable should be None or a callable")
self._itemTextCallable = itemTextCallable
else:
self._itemTextCallable = self._super_itemTextCallable
wx.ListCtrl.__init__(self,id=id,pos=pos,size=size,style=style)
listmix.ListCtrlAutoWidthMixin.__init__(self)
self.setResizeColumn(autoSizeColumn)
self.Bind(wx.EVT_WINDOW_DESTROY,source=self,id=self.GetId,handler=self._onDestroy)
def _onDestroy(self,evt):
evt.Skip()
self._itemTextCallable = None
def _super_itemTextCallable(self,item,column):
return super(MyListCtrl,self).OnGetItemText(item,column)
def OnGetItemText(self,column):
return self._itemTextCallable(item,column)
def sendListItemFocusedEvent(self,index):
evt = wx.ListEvent(wx.wxEVT_LIST_ITEM_FOCUSED,self.Id)
evt.EventObject = self
evt.Index = index
self.ProcessEvent(evt)
app = wx.App()
window = Window(None,title=APP_TITLE)
app.MainLoop()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)