微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

wx.media.MediaCtrl - wx.media.EVT_MEDIA_STOP、wx.media.EVT_MEDIA_FINISHED 和 Load() 的问题

如何解决wx.media.MediaCtrl - wx.media.EVT_MEDIA_STOP、wx.media.EVT_MEDIA_FINISHED 和 Load() 的问题

我正在尝试制作一个播放器,当当前歌曲结束时,它会自动播放列表中的下一首歌曲。无论我做什么,当我在绑定到 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 举报,一经查实,本站将立刻删除。