利用wxPython制作一个音乐播放器

最近学习python,打算做一个小demo入门,于是利用wxPython GUI组件做了一个音乐播放器,遇到很多问题(每次切换歌曲都会卡一下,求大佬指教~~~~~~)

界面图:


image.png

代码如下

# 程序的界面设置类
import os

import wx
from wx.media import MediaCtrl

from MusicThread import MusicThread


class MusicPlayerGUI:
    app = None
    window = None
    panel = None

    # 音量滑块组件
    sld = None
    # 播放按钮
    btn_play = None
    # 下一首按钮
    btn_next = None
    # 上一首按钮
    btn_pre = None

    # 当前状态 默认为暂停状态 False : 暂停  True : 播放
    status = False

    # 播放组件
    mc = None
    # music 扫描路径
    scanpath = "E:\music\\"
    # 扫描组件页面组件框
    scanpath_text = None
    # load歌曲库按钮
    btn_load = None
    # 文件列表的数组
    fileList = []
    # 歌曲列表展示
    lbl = None

    # 当前歌曲播放下标
    playindex = -1
    # 播放线程
    musicthread = None

    first = True

    def __init__(self):
        self.InitView()
        self.BindEvent()
        self.LoadView()

    # 初始化视图组件
    def InitView(self):
        self.app = wx.App()
        self.window = wx.Frame(None, title="music player", size=(450, 700))
        self.panel = wx.Panel(self.window)
        self.btn_play = wx.Button(self.panel, label="播放")
        self.btn_load = wx.Button(self.panel, label="load")
        self.sld = wx.Slider(self.panel, value=50, minValue=1, maxValue=100, style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        self.mc = MediaCtrl(parent=self.panel, style=wx.SIMPLE_BORDER, szBackend=wx.media.MEDIABACKEND_WMP10)
        self.btn_next = wx.Button(self.panel, label="下一首")
        self.btn_pre = wx.Button(self.panel, label="上一首")

    # 绑定事件
    def BindEvent(self):
        self.btn_play.Bind(wx.EVT_BUTTON, self.OnClicked)
        self.sld.Bind(wx.EVT_SLIDER, self.OnSliderScroll)
        self.btn_load.Bind(wx.EVT_BUTTON, self.LoadMusic)
        self.btn_pre.Bind(wx.EVT_BUTTON, self.Pre)
        self.btn_next.Bind(wx.EVT_BUTTON, self.Next)
        self.mc.Bind(wx.media.EVT_MEDIA_LOADED, self.OnMediaLoaded)
        self.mc.Bind(wx.media.EVT_MEDIA_PLAY, self.onPlay)
        self.mc.Bind(wx.media.EVT_MEDIA_PAUSE, self.onPause)

    # 组装视图
    def LoadView(self):
        boxSizer = wx.BoxSizer(wx.VERTICAL)
        boxSizerH1 = wx.BoxSizer(wx.HORIZONTAL)
        boxSizerH = wx.BoxSizer(wx.HORIZONTAL)
        scanlbl = wx.StaticText(self.panel, -1, style=wx.ALIGN_CENTER)
        scanlbl.SetLabel("输入歌曲库地址  : ")
        self.scanpath_text = wx.TextCtrl(self.panel, value=self.scanpath)
        boxSizerH1.Add(scanlbl)
        boxSizerH1.Add(self.scanpath_text)
        boxSizerH1.Add(self.btn_load)
        boxSizerH.Add(self.btn_pre)
        boxSizerH.Add(self.btn_play)
        boxSizerH.Add(self.btn_next)
        boxSizerH.Add(self.sld)
        boxSizer.Add(boxSizerH1)
        boxSizer.Add(boxSizerH)
        boxSizerV = wx.BoxSizer(wx.VERTICAL)
        self.lbl = wx.StaticText(self.panel, -1, style=wx.ALIGN_CENTER)
        font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL)
        self.lbl.SetFont(font)
        # self.lbl.SetLabel("")
        boxSizerV.Add(self.lbl)
        boxSizer.Add(boxSizerV)
        self.panel.SetSizer(boxSizer)

    # 上一首
    def Pre(self, event):
        # 我的歌单里有歌曲
        if len(self.fileList) != 0 and self.playindex != -1:
            # 如果当前是第一首
            if self.playindex <= 0:
                self.playindex = len(self.fileList) - 1
            else:
                self.playindex = self.playindex - 1
            # self.musicthread.SetFileName(self.fileList[self.playindex])
            self.musicthread.SetMessage(3)
            print(self.mc.Load(self.fileList[self.playindex]))

    # 下一首
    def Next(self, event):
        # 我的歌单里有歌曲
        if len(self.fileList) != 0 and self.playindex != -1:
            print(self.playindex)
            # 如果当前是最后
            if self.playindex >= len(self.fileList)-1:
                self.playindex = 0
            else:
                self.playindex = self.playindex + 1
            # self.musicthread.SetFileName(self.fileList[self.playindex])
            self.musicthread.SetMessage(3)
            print(self.mc.Load(self.fileList[self.playindex]))
            print( self.playindex)

    # 播放按钮点击事件的方法
    def OnClicked(self, event):
        print("play btn")
        # 如果当前是播放状态
        if self.status:
            print("播放状态变成暂停")
            self.status = False
            self.btn_play.SetLabel("播放")
            # self.mc.Pause()
            if self.musicthread is not None:
                self.musicthread.SetMessage(2)

        else:
            # 当前还未有播放下标
            if self.playindex == -1 and len(self.fileList) >= 1:
                self.playindex = 0
            if self.playindex != -1:
                # _thread.start_new_thread(self.MyPlayMusic, ())
                if self.first:
                    print(self.mc.Load(self.fileList[self.playindex]))
                    self.first = False
                else:
                    self.musicthread.SetMessage(1)

                # self.MyPlayMusic()
                print("暂停状态变成播放")
                self.status = True
                self.btn_play.SetLabel("暂停")
            else:
                self.MyPlayMusic()

            # self.onPlay2()

    # 子线程播放音乐
    def MyPlayMusic(self):
        print("子线程启动播放音乐")
        print(self.mc)
        if self.playindex != -1:
            filename = self.fileList[self.playindex]
            self.musicthread = MusicThread(self.mc, filename)
            self.musicthread.SetMessage(1)
            self.musicthread.start()

        # print(self.mc.Load(self.fileList[self.playindex]))

    # 音量的滑动触发方法
    def OnSliderScroll(self, e):
        obj = e.GetEventObject()
        val = obj.GetValue()
        # print(val)
        self.mc.SetVolume(val/100)

    def OnMediaLoaded(self, event):
        print("onLoad event")
        # print(self.mc.SetVolume(0.5))
        self.MyPlayMusic()
        # print(self.mc.Play())

    # 播放音乐的方法
    def onPlay(self, event):
        print("play event ")

    # 音乐暂停
    def onPause(self, event):
        print("pause event")

    # 遍历文件下的所有歌曲
    def listAllMusicInDir(self, filePath):
        fileList = []
        splitStr = []
        for top, dirs, nondirs in os.walk(filePath):
            for item in nondirs:
                splitStr = item.split(".")
                # 默认只需要mp3格式的文件名字
                if "mp3" == splitStr[1]:
                    fileList.append(os.path.join(top, item))
        return fileList

    # 根据文件路径加载歌曲列表
    def LoadMusic(self, event):
        filePath = self.scanpath_text.GetValue()
        self.fileList = self.listAllMusicInDir(filePath)
        musicStr = ""
        for item in self.fileList:
            musicStr += item.split(".")[0].replace(filePath, "")
            musicStr += "\n"
        self.lbl.SetLabel(musicStr)

    # 启动的方法
    def start(self):
        self.window.Show(True)
        self.app.MainLoop()


if __name__ == '__main__':
    musicPlayer = MusicPlayerGUI()
    musicPlayer.start()

import threading

import wx
import time


class MusicThread(threading.Thread):
    # 音乐播放组件
    mc = None
    # 音乐文件路径
    filename = None
    # 线程指令
    message = 0

    def __init__(self, mc, filename):
        threading.Thread.__init__(self)
        self.mc = mc
        self.filename = filename

    def SetMessage(self, message):
        self.message = message

    def SetFileName(self, filename):
        self.filename = filename

    def run(self):
        try:
            while True:
                # 播放
                if self.message == 1:
                    self.mc.Play()
                # 暂停
                elif self.message == 2:
                    self.mc.Pause()
                # 切歌
                elif self.message == 3:
                    self.mc.Stop()
                    break
            print("歌曲结束")
        except:
            print("exit")

你可能感兴趣的:(利用wxPython制作一个音乐播放器)