目录

一、总述

二、文件结构

三、打包方式

四、使用pydub进行音乐播放

main2.py

 all_music.py

show2.py

五、pydub使用中遇到的一些问题

六、新的尝试——pyaudio

mian3.py

all_music3.py

show3.py


一、总述

        这是一个学习笔记。市面上的播放器很多,所以为什么要做这件事呢,一点是希望在做这个软件的过程中学到一些知识,还有是因为像酷狗、QQ音乐这些软件经常在网上被爆出恶意删除本地音频的行为,而groove没办法播放歌词,千千静听算是比较好的一个本地播放设备了,但是总归没有自己写来的自由。

ubuntu平台及win11平台下正常可执行文件封装的几乎全格式音乐播放器(主要是看ffmpeg能支持到什么格式);在win平台下由于pydub的FFmpeg依赖会弹出命令行,由于水平限制,目前仅能实现有命令行窗口的exe封装。(在最近的尝试中,在win11平台下,命令行已经不会弹出,其具体步骤为,把pydub库的所有subprocess.Popen函数加上shell = True,pydub用到subprocess的其他地方也要修改,具体不记得了,可以参考python封装exe可执行文件后屏蔽去除cmd黑色命令框解决方案_呆呆熊的世界的博客-,并且禁止自己代码的print输出)。

win平台下,需要下载ffmpeg并将其exe文件的对应目录加入系统环境变量中,在Linux环境下,需要安装ffmpeg。对于本文的不足,希望各位指教。

python treeview 去掉边框 tkinter去掉边框和标题_python

二、文件结构

总共分为三个文件:

all_music.py 基于pydub,用于获得音乐类,可实现歌曲载入、播放、长度获取、播放时间获取、倍速播放、暂停、终结所有播放进程、播放状态获取等功能

show2.py 基于tkinter,用于播放器界面的可视化,之后预期添加音量加减,喜欢列表等功能。

main2.py 居中调度,用于传递文件路径,获取歌词和歌曲列表等功能。

三、打包方式

        使用pyinstaller -w -F -n 目标名称 文件名称的方式(比如这里是pyinstaller -w -F -n my_music main2.py)进行打包。

python treeview 去掉边框 tkinter去掉边框和标题_命令行_02

笔者经过了很多次的尝试,在网上也找了很多的方法,但都没办法修改这个图标,我看到一篇文章,貌似是因为Ubuntu系统限制,无法修改这个图标,不知道大家有没有什么办法。

        笔者直接在/usr/share/application这儿新建了一个My_Music.desktop 文件链接了这个可执行文件和图片。

My_Music.desktop设置如下:

[Desktop Entry]    #必须要的,告诉系统这是什么
Version=1.0        #可选,显示版本信息
Name=My_Music        #软件名称
Comment=A Music Player    #鼠标放在图标上时显示的文字
Exec=/home/xiaobai/Desktop/my_music/my_music    #可执行文件路径(绝对路径)
Icon=/home/xiaobai/Desktop/my_music/My_Music.jpeg    #希望作为软件图标使用的图片,这张是百度的,最好是正方形,也可以下下来自己裁
Encoding=UTF-8        #可选,编码方式
StartupNotify=true    #现在还不清楚有什么用
Terminal=false        #是否打开命令行
Type=Application    #类型
Categories=Audio;Player    #类别,这里选的是音乐播放器,具体可选值可自行百度

四、使用pydub进行音乐播放

main2.py

from tkinter import filedialog
import show2
import os
import numpy as np
import copy
import all_music
import time
import random
import chardet
import platform
import multiprocessing
list_music=[]
flag_list_music=0
def openfile():
    global list_music,flag_list_music
    filenames=filedialog.askopenfilenames(title = "音乐播放器",\
                    filetypes =[("常见文件",\
                                 ["*.wma","*.wav","*.mp3","*.flac",\
                                  "*.ape","*.mp4","*.m4a","*.ogg",\
                                  "*.flv"]),\
                                ("MP3文件","*.mp3"),\
                                ("FLAC文件","*.flac"),\
                                ("APE文件","*.ape"),\
                                ("WAV文件","*.wav"),\
                                ("MP4文件","*.mp4"),\
                                ("M4A文件","*.m4a"),\
                                ("OGG文件","*.ogg"),\
                                ("FLV文件","*.flv"),\
                                ("AIFF文件","*.aiff"),\
                                ("WMA文件","*.wma"),\
                                ("所有文件","*.*")])
    if filenames:
        for f in filenames:     #将音乐列表导入
            list_music.append(f)
        if (not music.get_busy()) and len(list_music):
            try:
                music.unload()
            except:
                pass
            try:
                music.load(list_music[0])
            except:
                pass
            music.play()
        elif not len(list_music):
            assert False,"未导入任何歌曲"
        flag_list_music=1       #成功导入音乐
def openpath():
    global list_music,flag_list_music
    path=filedialog.askdirectory(title = "音乐播放器")
    if path:        #如果选择了文件
        list_music1=os.listdir(path)#保存选择的音乐列表并修正为绝对路径
        for i in range(len(list_music1)):
            list_music1[i]=path+"/"+list_music1[i]
        list_music2=copy.deepcopy(list_music1)#深拷贝
        for f in list_music2:       #移除不支持的格式的音乐
            extension = os.path.splitext(f)[-1]
            if not (extension==".mp3" or\
               extension==".wma" or\
               extension==".wav" or\
               extension==".ogg" or\
                extension==".flv" or\
                    extension==".mp4" or\
                    extension==".aiff" or\
                    extension==".ape" or\
                    extension==".m4a" or\
               extension==".flac"):
                list_music1.remove(f)
                #print(f+"因为不被支持被移除了")
        list_music=list_music+list_music1
        if (not music.get_busy()) and len(list_music):
            try:
                music.unload()
            except:
                pass
            try:
                music.load(list_music[0])
            except:
                pass
            music.play()
        elif not len(list_music):
            assert False,"未导入任何歌曲"
        flag_list_music=1           #成功导入音乐
def next_music():           #下一首歌
    global list_music,flag_list_music
    music.stop()
    music.unload()
    way=show1.play_way.get()        #获取设定的播放方式
    if way==2:              #列表播放
        list_music.pop(0)
    elif way==1:            #单曲循环
        if len(list_music)>1:
            list_music.pop(0)
        print("单曲循环中")
    elif way==3:            #列表循环
        list_music.append(list_music.pop(0))
    elif way==4:            #随机播放
        random.shuffle(list_music)
    else:
        assert False,"播放方式出错"
    flag_list_music=1               #刷新显示
    if len(list_music):
        music.load(list_music[0])
        music.play()
    else:
        assert False,"没有下一首了"
def stop():                 #停止播放并清空播放列表
    global list_music,flag_list_music
    list_music=[]
    music.stop()
    music.unload()
    flag_list_music=1       #刷新显示
def code(path):    #判断文件的编码方式 
    f = open(path, 'rb')
    f_read = f.read()
    f_charInfo = chardet.detect(f_read)
    return f_charInfo
lrc_dict={}
def get_lrc_geci():
    global lrc_dict,list_music
    if list_music:
        path=copy.deepcopy(list_music[0])#深拷贝
        for i in range(len(path)-1,-1,-1):
            if path[i]==".":
                path=path[:i]+".lrc"
                break
        try:
            file=open(path, "r", encoding=code(path)['encoding'])
            try:
                lrc_list = file.readlines()
            except:
                if code(path)['encoding']==('GB2312' or 'GBK'):
                    file=open(path, "r", encoding='GB18030')
                    lrc_list = file.readlines()
            lrc_dict = {}
            for i in lrc_list:
                lrc_word = i.replace("[", "]").strip().split("]")
                for j in range(len(lrc_word) - 1):
                    if lrc_word[j]:
                        time=0
                        flag=0
                        for k in range(len(lrc_word[j])):
                            try:
                                if lrc_word[j][k]==":":
                                    time=int(lrc_word[j][:k])*60*1000+time
                                    flag=k
                                elif flag!=0 and lrc_word[j][k]==".":
                                    time=int(lrc_word[j][flag+1:k])*1000+time
                                    time=int(lrc_word[j][k+1:])+time
                                    break
                                elif flag!=0 and k==len(lrc_word[j])-1:
                                    time=int(lrc_word[j][flag+1:k+1])*1000+time
                                    break
                            except:
                                time=0
                                break
                        if time in lrc_dict.keys():
                            if flag==0:
                                lrc_dict[time] = lrc_dict[time]+' '+lrc_word[1]
                            else:
                                lrc_dict[time] = lrc_dict[time]+' '+lrc_word[-1]
                        else:
                            if flag==0:
                                lrc_dict[time] = lrc_word[1]
                            else:
                                lrc_dict[time] = lrc_word[-1]
            time_list=list(lrc_dict.keys())
            time_list.sort()
            lrc_dict["time"]=time_list
            print("get_lrc")
            file.close()
        except:
            lrc_dict = {}
now_word=0
def get_word():
    global lrc_dict,now_word
    if lrc_dict and music.get_busy():
        for i in range(len(lrc_dict["time"])):
            if lrc_dict["time"][i]<=get_real_time()*music.speed\
               and ((len(lrc_dict["time"])==lrc_dict["time"].index(lrc_dict["time"][i])+1\
                    or (len(lrc_dict["time"])>lrc_dict["time"].index(lrc_dict["time"][i])+1 \
                        and lrc_dict["time"][i+1]>get_real_time()*music.speed))):
                now_word=lrc_dict["time"][i]
                word=[]
                word.append(lrc_dict[now_word])
                if len(lrc_dict["time"])>=lrc_dict["time"].index(lrc_dict["time"][i])+2:
                    word.append(lrc_dict[lrc_dict["time"][lrc_dict["time"].\
                                                    index(now_word)+1]])
                return word
    elif not lrc_dict:
        return ["暂无歌词"]
    else:
        return []

def get_real_time():
    return music.get_play_time()
def my_mainloop():
    global list_music,flag_list_music
    global event1,now_word
    word=get_word()
    if word:
        show1.get_word(lrc_word=word)
    event1=music.pop_event()
    if event1:          #仅当歌曲正常结束时,event1事件触发
        print("over")
        flag_list_music=1       #载入新歌歌词
        if len(list_music):     #如果还有歌
            show1.set_time=0
            way=show1.play_way.get()#获取设定的播放方式
            if way==2:      #列表播放
                list_music.pop(0)
            elif way==1:    #单曲循环
                print("单曲循环中")
            elif way==3:    #列表播放
                list_music.append(list_music.pop(0))
            elif way==4:    #随机播放
                random.shuffle(list_music)
            else:
                assert False,"播放方式出错"
            print("pop")
            if len(list_music):
                if way==1:
                    music.replay()
                else:
                    music.unload()
                    music.load(list_music[0])
                    music.play()
            else:
                print("歌单空了")
    if flag_list_music:         #如果需要读入歌单
        now_word=0
        get_lrc_geci()          #获得歌词
        list_music_change=copy.deepcopy(list_music)#深拷贝
        path=""
        for j in range(len(list_music_change)): #得到歌曲名称
            f=list_music_change[j]
            x=-1
            for i in range(len(f)):
                if f[i]=="/":
                    x=i
            if x>=0:
                path=list_music_change[j][:x+1]
                list_music_change[j]=list_music_change[j][x+1:]
        show1.get_music_list(path=path,list_music=list_music_change)
        flag_list_music=0
    if get_real_time()>=0:
        if ((get_real_time()!=show1.music_time_scale.get()))and \
            not show1.mouse_left_click1:
            #print("set_time2")
            show1.set_length_and_now_time(now_time=get_real_time())
            show1.music_time_scale.set(get_real_time())
    show1.win.after(100,my_mainloop)
def main():
    global show1
    global music
    music=all_music.all_music()
    music.set_event(event=1)
    show1=show2.show()
    show1.get_music(music=music,\
                    openfile=openfile,openpath=openpath,\
                    next_music=next_music,stop=stop)
    event1=False
    show1.win.after(100,my_mainloop)
    show2.mainloop()
    try:
        music.stop()
    except:
        pass
if __name__ == '__main__':
    if('Windows'==platform.system()):#防止在win平台下打包出现多窗口
        multiprocessing.freeze_support()
    main()

 all_music.py

from pydub import AudioSegment
from pydub.playback import play
import multiprocessing
import time
import psutil
import copy
def terminate(process_pid):
	process=psutil.Process(process_pid)
	p_child=process.children() # 子进程列表
	for p_c in p_child:
		p_c.kill()
		p_c.join()
	process.kill()
	process.join()
def suspend(process):
	p_child=process.children() # 子进程列表
	for p_c in p_child:
		p_c.suspend()
	process.suspend()
def resume(process):
	p_child=process.children() # 子进程列表
	for p_c in p_child:
		p_c.resume()
	process.resume()
class all_music():
    def __init__(self):
        self.volume=100
        self.song_path=[]
        self.song=[]                    #绝对
        self.song1=[]                   #相对
        self.process1=[]
        self.suffix=[]
        self.now_time=-1        #当前播放歌曲的时长
        self.start_time=-1      #计时器开始计时的时间
        self.excursion_time=0
        self.length=-1
        self.load_flag=0
        self.busy=0         #0:空闲;1:播放中;2:暂停中;3:暂停准备继续播放
        self.event=0
        self.speed=1
        self.volume_limuit=20
    def set_event(self,event):      #设置事件返回值,触发时返回event,未触发返回0
        self.event=event
    def pop_event(self):            #查看当前事件状态
        try:
            result=self.q.get(block=False)
            self.busy=0
            return result
        except:
            return 0
    def pydub_play(self):           #播放音乐并在结束时触发事件
        play(self.song1)
        self.q.put(self.event,block=True)
    def get_busy(self):             #查看是否忙碌     
        return self.busy
    def get_length(self):           #得到歌曲长度
        return self.length
    def pos_set(self,time):         #设置歌曲播放位置
        if self.load_flag:
            self.stop()
            self.play(start=time)
        else:
            assert False,"未载入歌曲"
    def get_play_time(self):        #获得当前歌曲播放到的位置
        if self.start_time!=-1:
            if self.busy==1:    #判断是否在暂停状态
                #当前歌曲播放了多少毫秒
                self.now_time=self.excursion_time+int((time.time()-self.start_time)*1000)
                return self.now_time
            else:
                return self.now_time
        else:
            return -1
    def load(self,file_path):       #获得路径
        if not self.load_flag:   #判断是否已经加载了歌曲
            if file_path:   #判断路径是否为空
                self.song_path=file_path    #将歌曲路径给到self
                for i in range(len(self.song_path)-1,-1,-1):    #寻找文件后缀
                    if self.song_path[i]==".":
                        break
                if self.song_path[i]==".":                      #将歌曲后缀给到self
                    self.suffix=self.song_path[i+1:]
                    self.load_flag=1
                else:
                    assert False,"未发现文件后缀"
            else:
                assert False,"load(file_path)需要一个歌曲路径"
        else:
            assert False,"已经加载了一个歌曲"
    def unload(self):           #解除加载状态
        if self.load_flag:   #判断是否已经加载了歌曲
            self.load_flag=0
            self.song_path=[]
            self.suffix=[]
        else:
            assert False,"未加载歌曲"
    def set_speed(self,speed):
        self.speed=speed
    def set_volume(self,volume):
        self.volume=volume
    def get_volume(self):
        return self.volume    
    def replay(self,start=0):
        if self.busy:   #判断歌曲是否在播放或者暂停状态
            try:
                terminate(self.process1.pid)    #终结歌曲进程
            except:
                pass 
            self.process1=[]
            self.now_time=-1
            self.start_time=-1
            self.excursion_time=0
            self.length=-1
            self.busy=0
        #判断歌曲是否在播放或者暂停状态
        if (self.busy==0 or self.busy==3)and self.load_flag:
            self.song1=copy.deepcopy(self.song)
            if self.volume==0:
                self.song1=self.song1-100
            else:
                self.song1=self.song1-self.volume_limuit*(1.0-self.volume/100)
            if self.speed!=1:
                self.song1 = self.song1._spawn(self.song1.raw_data, \
                                    overrides={"frame_rate": int(self.song1.frame_rate * self.speed)})\
                                    .set_frame_rate(self.song1.frame_rate)
            if start>len(self.song1):
                assert False,"设置的时间超过歌曲的时长"
            self.excursion_time=start         #设置偏移时间归零
            self.now_time=self.excursion_time#设置播放时间归零
            print(self.now_time)
            self.busy=1
            self.length=len(self.song1)   #设置歌曲时长
            print(self.length)
            if self.now_time:
                self.song1=self.song1[self.now_time:]
            print(len(self.song1))
            self.q = multiprocessing.Queue(maxsize=1)
            self.process1 = multiprocessing.Process(target =self.pydub_play,name="my_process1")
            self.process1.start()
            self.start_time=time.time()
        else:
            assert False,"歌曲未载入或占用中,请先load或stop"
    def play(self,start=0):                 #播放歌曲
        #判断歌曲是否在播放或者暂停状态
        if (self.busy==0 or self.busy==3)and self.load_flag:
            if self.suffix:#是否有下标
                if self.suffix=="mp3":      #导入mp3歌曲
                    self.song = AudioSegment.from_mp3(self.song_path) 
                elif self.suffix=="ogg":    #导入ogg歌曲
                    self.song = AudioSegment.from_ogg(self.song_path) 
                elif self.suffix=="flv":    #导入flv歌曲
                    self.song = AudioSegment.from_flv(self.song_path) 
                else:#导入其他支持的格式的歌曲
                    try:
                        self.song = AudioSegment.from_file(self.song_path,self.suffix)
                    except:
                        assert False,"不支持的文件或不存在此文件"
                self.song1=copy.deepcopy(self.song)
                if self.volume==0:
                    self.song1=self.song1-100
                else:
                    self.song1=self.song1-self.volume_limuit*(1-self.volume/100)
                if self.speed!=1:
                    self.song1 = self.song1._spawn(self.song1.raw_data, \
                                        overrides={"frame_rate": int(self.song1.frame_rate * self.speed)})\
                                        .set_frame_rate(self.song1.frame_rate)
                if start>len(self.song1):
                    assert False,"设置的时间超过歌曲的时长"
                self.excursion_time=start         #设置偏移时间归零
                self.now_time=self.excursion_time#设置播放时间归零
                self.busy=1
                self.length=len(self.song1)   #设置歌曲时长
                if self.now_time:
                    self.song1=self.song1[self.now_time:]
                self.q = multiprocessing.Queue(maxsize=1)
                self.process1 = multiprocessing.Process(target =self.pydub_play,name="my_process1")
                self.process1.start()
                self.start_time=time.time()
                
            else:
                assert False,"未载入任何歌曲"
        else:
            assert False,"歌曲未载入或占用中,请先load或stop"
    def stop(self):     #结束播放但不unload
        if self.busy:   #判断歌曲是否在播放或者暂停状态
            try:
                terminate(self.process1.pid)    #终结歌曲进程
            except:
                pass
            self.song=[]
            self.process1=[]
            self.now_time=-1
            self.start_time=-1
            self.excursion_time=0
            self.length=-1
            self.busy=0
        else:
            assert False,"歌曲不在播放或暂停状态"
    def pause(self):    #暂停播放
        if self.busy==1:   #判断歌曲是否在播放状态
            self.get_play_time()        #获得当前时间
            p=psutil.Process(self.process1.pid)
            suspend(p)
            self.busy=2
        else:
            assert False,"无歌曲正在播放"
    def unpause(self):  #继续暂停的播放
        if self.busy==2:   #判断歌曲是否在播放状态
            self.busy=3
            p=psutil.Process(self.process1.pid)
            resume(p)
            self.excursion_time=self.now_time   #设置偏移时间归零
            self.start_time=time.time()
            self.busy=1
            #self.play(start=self.now_time)
        else:
            assert False,"歌曲不在暂停状态"

show2.py

from tkinter import *
from PIL import Image
import tkinter.font as tkFont
from tkinter import ttk
import platform
def color(color_255):
    color_16=0x0
    color_16=color_16+0x10000*(color_255[0])
    color_16=color_16+0x100*(color_255[1])
    color_16=color_16+0x1*(color_255[2])
    if color_16>0xFFFFF:
        return '#%0x'%color_16
    elif color_16>0xFFFF:
        return '#0%0x'%color_16
    elif color_16>0xFFF:
        return '#00%0x'%color_16
    elif color_16>0xFF:
        return '#000%0x'%color_16
    elif color_16>0xF:
        return '#0000%0x'%color_16
    else:
        return '#00000%0x'%color_16
openfiles=[]
openpaths=[]
next_musics=[]
stop=[]
typeface=u"华文行楷"

if(platform.system()=='Windows'):
    size_word_win='1000x80'
elif(platform.system()=='Linux'):
    size_word_win='1000x100'
else:
    assert False,'暂未支持Windows和Linux之外的系统'
    
class show():
    def __init__(self): 
        #主窗口
        self.mouse_left_click1=0#鼠标左键点击时间轴状态
        self.mouse_left_click2=0#鼠标左键点击音量状态
        self.set_time=0
        self.flag_replay=0
        self.win = Tk()
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.win.title(u"我的音乐")
        self.win.bind("<Key>",self.key_event)
        self.screenwidth=self.win.winfo_screenwidth()
        self.screenheight=self.win.winfo_screenheight()
        self.win.resizable(width=False,height=False)#False表示不可以缩放,True表示可以缩放
        try:
            self.win.iconphoto(True, PhotoImage(file='/home/xiaobai/Desktop/my_music/My_Music_tk.png'))
        except:
            pass
        self.frame= Frame (self.win, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,heigh=600,width=1280,cursor='arrow')
        self.frame.pack(side=TOP, fill=BOTH, ipadx=0, ipady=0, expand=1)
        #音乐列表frame
        self.frame2= Frame (self.frame, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,cursor='arrow')
        self.frame2.pack(side=TOP,fill=X,ipadx=0,ipady=0,expand=1)
        self.frame21= Frame (self.frame2,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame21.pack(side=BOTTOM,fill=X,ipadx=0,ipady=0,expand=1)
        self.frame22= Frame (self.frame2,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame22.pack(side=TOP,fill=X,ipadx=0,ipady=0,expand=1)
        #按钮frame
        self.frame1= Frame (self.frame, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,cursor='arrow')
        self.frame1.pack(side=TOP,fill=X,ipadx=0,ipady=0,expand=1)
        
        #歌词frame
        self.frame3= Frame (self.frame, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,cursor='arrow')
        self.frame3.pack(side=BOTTOM,fill=X,ipadx=0,ipady=0,expand=0)
        #按钮
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"暂停",command =self.pause)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"播放",command =self.play)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"重新播放",command =self.replay)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"下一首",command =self.next_music)\
                .pack (side=LEFT, padx=13, pady=13)
        self.frame11= Frame (self.frame1,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame11.pack(side=LEFT,fill=Y,ipadx=20,ipady=0,expand=0)
        Button (self.frame1,font=ft,bg=color([59,210,61])\
                ,activebackground="white",\
                text=u"清空",command =self.stop)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([242,203,46])\
                ,activebackground="white",\
                text=u"文件夹",command =self.openpath)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([242,169,0])\
                ,activebackground="white",\
                text=u"文件",command =self.openfile)\
                .pack (side=LEFT, padx=13, pady=13)
        
        #一些文本显示
        #显示“播放列表”文本
        ft = tkFont.Font(family=typeface, size=20, weight=tkFont.BOLD)
        self.frame221= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame221.pack(side=LEFT)
        Label(self.frame221,font=ft,\
              text=u"播",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"放",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"列",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"表",bg=color([135,206,250])).pack(anchor='w')
        #显示“倍速”文本
        ft = tkFont.Font(family=typeface, size=10, weight=tkFont.BOLD)
        self.frame222= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame222.pack(anchor='w')
        Label_b=Label(self.frame222,font=ft,\
              text=u"   倍速",bg=color([135,206,250]))
        Label_b.pack(side=LEFT)
        #倍速设置
        self.set_comvalue=StringVar()#窗体自带的文本,新建一个值
        self.set_templist=ttk.Combobox(self.frame222,font=ft,\
                                       textvariable=self.set_comvalue,\
                                       state='readonly',\
                                       width=3) #初始化    
        self.set_templist["values"]=("0.8","0.9","1","1.2","1.4")
        self.set_templist.current(2) #选择第一个
        self.set_templist['state'] = 'readonly'#只读
        self.set_templist.bind("<<ComboboxSelected>>",self.music_speed) #绑定事件,(下拉列表框被选中时,绑定go()函数)
        self.set_templist.pack(side=LEFT)
        #列表
        #音乐列表
        self.frame224= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame224.pack(side="left")
        self.list_music1_sb = Scrollbar(self.frame224)
        self.list_music1_sb.pack(side="right", fill="y")
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.list_music1=Listbox(self.frame224,bg=color([255,255,255]),\
                            cursor='plus',font=ft,\
                            fg=color([0,0,0]),height=5,width=40,\
                            yscrollcommand= self.list_music1_sb.set)
        self.list_music1.pack(side="left", fill="both")
        self.list_music1_sb.config(command=self.list_music1.yview)
        #播放模式设置
        self.frame222= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame222.pack(side=LEFT)
        WAY_SET = [("单曲循环", 1),("列表播放", 2),("列表循环", 3),("随机播放", 4)]
        self.play_way = IntVar()
        self.play_way.set(2)
        for way, num in WAY_SET:
            Radiobutton(self.frame222, text=way, variable=self.play_way,\
                    indicatoron=False, value=num,\
                    font=ft,bg=color([135,206,250]),\
                    activebackground=color([255,192,203]),\
                    cursor='circle',selectcolor=color([192,192,192]),\
                    ).pack(anchor="w")
        #音量
        self.frame223= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame223.pack(side=LEFT,padx=5)
        Label_c=Label(self.frame223,font=ft,\
              text=u"音量",bg=color([135,206,250]))
        Label_c.pack(anchor="w")
        self.volume_text = IntVar()
        self.volume_text.set(100)
        self.music_volume=Scale(self.frame223,from_=100, to=0, \
              length=100, \
              orient="vertical",\
              activebackground=color([128,128,128]),\
              bg=color([200,200,200]),font=ft,\
              bd=0,sliderrelief="ridge",sliderlength=20,\
              showvalue=False,variable=self.volume_text)
        self.music_volume.pack(after=Label_c,padx=10)
        if(platform.system()=='Windows'):
            self.music_volume.bind("<MouseWheel>",self.mouse_middle_motion_volume)
        elif(platform.system()=='Linux'):
            self.music_volume.bind("<Button-4>",self.mouse_middle_motion_volume)
            self.music_volume.bind("<Button-5>",self.mouse_middle_motion_volume)
        else:
            assert False,'暂未支持Windows和Linux之外的系统'
        self.music_volume.bind("<Button-1>",self.mouse_left_click_volume)
        self.music_volume.bind("<ButtonRelease-1>",self.mouse_left_release_volume)
        
        Label(self.frame223,font=ft,textvariable=self.volume_text,\
              bg=color([135,206,250])).pack(after=self.music_volume)
        #当前时间
        self.now_time_text = StringVar()
        self.now_time_text.set("0"+":"+"00")
        ft = tkFont.Font(family=u"微软雅黑", size=10, weight=tkFont.BOLD)
        Label(self.frame21,font=ft,textvariable=self.now_time_text,\
              bg=color([135,206,250])).pack(side=LEFT, padx=0, pady=5)
        #歌曲进度
        self.music_time_scale_length=600
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.frame211= Frame (self.frame21,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame211.pack(side=LEFT)
        self.music_time_scale=Scale(self.frame211,from_=0, to=180000, \
              length=self.music_time_scale_length, cursor="circle",\
              orient="horizontal",\
              activebackground=color([128,128,128]),\
              bg=color([200,200,200]),font=ft,\
              bd=0,sliderrelief="ridge",sliderlength=20,\
              showvalue=False)
        self.music_time_scale.pack(side=LEFT,padx=5, pady=0)
        self.music_time_scale.bind("<Button-1>",self.mouse_left_click_fun)
        self.music_time_scale.bind("<ButtonRelease-1>",self.mouse_left_release_fun)
        #总时间
        self.length_text = StringVar()
        self.length_text.set("0"+":"+"00")
        ft = tkFont.Font(family=u"微软雅黑", size=10, weight=tkFont.BOLD)
        Label(self.frame21,font=ft,textvariable=self.length_text,\
              bg=color([135,206,250])).pack(side=LEFT, padx=0, pady=5)
        #歌词
        '''
        self.lrc_word_length=40
        ft = tkFont.Font(family=u"宋体", size=25, weight=tkFont.BOLD)
        self.lrc_word=Listbox(self.frame3,bg=color([255,255,255]),\
                            cursor='plus',font=ft,\
                            fg=color([0,0,0]),height=2,width=self.lrc_word_length)
        self.lrc_word.pack(side=BOTTOM,fill=Y,ipadx=0,ipady=0,expand=0)
        '''
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.son_win=Toplevel(master=self.win)      #子窗口
        self.son_win.title("我的歌词")
        self.son_win.geometry(size_word_win+'+'+str(self.screenwidth//2-500)+'+'+str(self.screenheight-120))     
        #大小和位置
        self.son_win.wm_attributes('-topmost',1)    #置顶
        self.son_win.overrideredirect(boolean=True)#去掉边框和按钮
        if platform.system()=='Linux':
            self.son_win.wait_visibility(self.son_win)
        self.son_win.attributes('-alpha',0.9)       #整体透明
        
        self.son_win.bind("<B1-Motion>", self.move)
        self.son_win.bind("<Button-1>", self.get_point)
        '''
        --将回调函数func与相应的规则name绑定

        --name参数可以是“WM_DELETE_WINDOW”:窗口被关闭的时候

        --name参数可以是“WM_SAVE_YOURSELF”:窗口被保存的时候

        --name参数可以是“WM_TAKE_FOCUS”:窗口获得焦点的时候

        '''
        #withdraw()#将窗口从屏幕上移除(并没有销毁)
        '''
        --需要重新显示窗口,使用deiconify()方法

        --该方法会使得state()返回"withdraw"
        '''
        self.frame_son_win= Frame (self.son_win,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame_son_win.pack(fill=BOTH,expand=1)
        self.lrc_word_length=40
        ft = tkFont.Font(family=typeface, size=20, weight=tkFont.BOLD)
        self.lrc_word=Text(self.frame_son_win,font=ft,\
                               relief='flat',width=self.lrc_word_length,\
                               bg=color([135,206,250]),height=2)
        self.lrc_word.tag_config("tag_1", backgroun="yellow", foreground="red")
        self.lrc_word.pack()
        self.lrc_word.config(state=DISABLED)
        self.word_win_state = IntVar()
        self.word_win_state_button=Checkbutton(self.frame1,font=ft,bg=color([135,206,250]),\
                text=u"词",variable=self.word_win_state,\
                command=self.show_or_hide_word,indicatoron=False,\
                activebackground=color([255,192,203]),\
                selectcolor=color([192,192,192]))
        self.word_win_state_button.pack (side=LEFT, padx=13, pady=13)
        self.word_win_state_button.select()
    def key_event(self,event):
        key=event.keysym
        if key=='space':
            if self.music.get_busy()==1:
                self.pause()
            elif self.music.get_busy()==2:
                self.play()
        elif key=='Up':
            self.mouse_middle_motion_volume([],1)
        elif key=='Down':
            self.mouse_middle_motion_volume([],-1)
    def show_or_hide_word(self):
        if self.word_win_state.get():
            self.son_win.deiconify()
        else:
            self.son_win.withdraw()
        #print(self.word_win_state.get())
    def get_point(self, event):
        """获取当前窗口位置并保存"""
        self.x, self.y = event.x, event.y
    def move(self, event):
        """窗口移动事件"""
        new_x = (event.x - self.x) + self.son_win.winfo_x()
        new_y = (event.y - self.y) + self.son_win.winfo_y()
        s = size_word_win+f"+{new_x}+{new_y}"     
        self.son_win.geometry(s)
    def mouse_middle_motion_volume(self,event,key=None):
        if(platform.system()=='Windows'):
            x=120
            if key==None:
                flag=event.delta//x
                
        elif(platform.system()=='Linux'):
            x=4
            if key==None:
                if(event.num==x):
                    flag=1
                elif event.num==x+1:
                    flag=-1
                else:
                    assert False,'Linux下事件错误'
        else:
            assert False,'暂未支持Windows和Linux之外的系统'
        if key!=None:
            if key==1:
                flag=1
            elif key==-1:
                flag=-1
            else:
                assert False,'key输入错误'
        if flag>0:
            print("volume="+str(self.music.get_volume())+"dB")
            if self.music.get_volume()!=120:
                if 100==self.music_volume.get():
                    volume=self.music.get_volume()+10*flag
                    self.volume_text.set(volume)
                else:
                    volume=self.music_volume.get()+10*flag
                    self.music_volume.set(volume)
                    self.volume_text.set(volume)
                self.music.set_volume(volume)
                self.win.update()       #强制刷新
                self.set_time=self.music.get_play_time()
                self.music.replay(start=self.set_time)
                self.win.update()       #强制刷新
        else:
            if self.music.get_volume()!=0:
                if 100<self.music.get_volume():
                    volume=self.music.get_volume()+10*flag
                    self.volume_text.set(volume)
                else:
                    volume=self.music_volume.get()+10*flag
                    if volume<0:
                        volume=0
                    self.music_volume.set(volume)
                    self.volume_text.set(volume)
                self.music.set_volume(volume)
                self.win.update()       #强制刷新
                self.set_time=self.music.get_play_time()
                self.music.replay(start=self.set_time)
                self.win.update()       #强制刷新
    def mouse_left_click_volume(self,event):
        state=self.music_volume.identify(event.x,event.y)
        if state!='slider':
            volume=100-event.y
            self.music_volume.set(volume)
            self.volume_text.set(volume)
            self.win.update()       #强制刷新
            self.mouse_left_click2=1
            print("mouse_set_volume")
        else:
            self.mouse_left_click2=1
            print("slide_scale")
    def mouse_left_release_volume(self,event):
        if self.mouse_left_click2==1:
            volume=self.music_volume.get()
            self.volume_text.set(volume)
            self.music_volume.set(volume)
            self.music.set_volume(volume)
            self.set_time=self.music.get_play_time()
            self.win.update()       #强制刷新
            self.music.replay(start=self.set_time)
            self.win.update()       #强制刷新
            print("slide_scale_set_volume")
        self.mouse_left_click2=0
    def music_speed(self,*args):
        speed=float(self.set_templist.get())
        self.set_time=int(self.music.get_play_time()*self.music.speed/speed)
        self.music.set_speed(speed)
        #self.music.stop()
        self.music.replay(start=self.set_time)
        self.music_time_scale.pack_forget()     #时间进度条重画
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.music_time_scale=Scale(self.frame211,from_=0, \
                                        to=self.music.get_length(), \
                length=self.music_time_scale_length, cursor="circle",\
                orient="horizontal",\
                activebackground=color([128,128,128]),\
                bg=color([200,200,200]),font=ft,\
                bd=0,sliderrelief="ridge",sliderlength=20,\
                showvalue=False)
        self.music_time_scale.pack(side=LEFT,padx=5, pady=0)
        self.music_time_scale.bind("<Button-1>",self.mouse_left_click_fun)
        self.music_time_scale.bind("<ButtonRelease-1>",self.mouse_left_release_fun)
        self.music_time_scale.set(self.set_time)
        self.set_length_and_now_time(now_time=self.set_time,music_length=self.music.get_length())
        self.win.update()       #强制刷新
    def set_length_and_now_time(self,now_time,music_length=None):
        if music_length!=None:
            self.length_text.set(str(int(music_length*self.music.speed//(1000*60))).zfill(1)\
                                 +":"+str(int(music_length*self.music.speed//1000%60)).zfill(2))
        time=int(now_time*self.music.speed)
        self.now_time_text.set(str(time//(1000*60)).zfill(1)\
                                 +":"+str(time//1000%60).zfill(2))
    def mouse_left_click_fun(self,event):
        state=self.music_time_scale.identify(event.x,event.y)
        if state!='slider':
            self.set_time=int(event.x/self.music_time_scale_length*self.music.get_length())
            self.music_time_scale.set(self.set_time)
            self.win.update()       #强制刷新
            #self.music.stop()
            self.music.replay(start=self.set_time)
            self.mouse_left_click1=2
            print("mouse_set_time")
        else:
            self.mouse_left_click1=1
            print("slide_scale")
    def mouse_left_release_fun(self,event):
        if self.mouse_left_click1==1:
            if event.x<0:
                event_x=0
            elif event.x>self.music_time_scale_length:
                event_x=self.music_time_scale_length
            else:
                event_x=event.x
            self.set_time=int(event_x/self.music_time_scale_length*self.music.get_length())
            self.music_time_scale.set(self.set_time)
            self.win.update()       #强制刷新
            #self.music.stop()
            self.music.replay(start=self.set_time)
            print("slide_scale_set_time")
        self.mouse_left_click1=0
    def get_music(self,music,openfile,openpath,next_music,stop):
        self.music=music
        global openfiles
        openfiles=openfile
        global openpaths
        openpaths=openpath
        global next_musics
        next_musics=next_music
        global stop1
        stop1=stop
    def get_music_list(self,path,list_music):
        self.list_music1.delete(0,"end")
        for item in list_music:
            self.list_music1.insert("end", item)
        self.music_time_scale.pack_forget()
        if path:
            ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
            self.music_time_scale=Scale(self.frame211,from_=0, \
                                        to=self.music.get_length(), \
                  length=self.music_time_scale_length, cursor="circle",\
                  orient="horizontal",\
                  activebackground=color([128,128,128]),\
                  bg=color([200,200,200]),font=ft,\
                  bd=0,sliderrelief="ridge",sliderlength=20,\
                  showvalue=False)
            self.music_time_scale.pack(side=LEFT,padx=5, pady=0)
            self.music_time_scale.bind("<Button-1>",self.mouse_left_click_fun)
            self.music_time_scale.bind("<ButtonRelease-1>",self.mouse_left_release_fun)
            self.set_length_and_now_time(now_time=self.set_time,music_length=self.music.get_length())
    def get_word(self,lrc_word):
        self.lrc_word.config(state=NORMAL)
        try:
            self.lrc_word.delete(1.0,"end")
        except:
            pass
        length=0
        length1=0
        if len(lrc_word)==1 or lrc_word[1]=='':
            for ch in lrc_word[0]:
                if u'\u4e00'<=ch<=u'\u9fff':
                    length=length+2.8
                else:
                    length=length+1
            length=int(length)
        else:
            for i in range(len(lrc_word)):
                if i:
                    length1=round(length/2)
                    length=length1
                    for ch in lrc_word[i]:
                        if u'\u4e00'<=ch<=u'\u9fff':
                            length=length+2.8
                        else:
                            length=length+1
                else:
                    for ch in lrc_word[i]:
                        if u'\u4e00'<=ch<=u'\u9fff':
                            length=length+2.8
                        else:
                            length=length+1
                length=int(length)
        if self.lrc_word_length!=length:
            self.lrc_word.pack_forget()
            self.lrc_word_length=int(length)
            ft = tkFont.Font(family=typeface, size=25, weight=tkFont.BOLD)
            self.lrc_word=Text(self.frame_son_win,font=ft,\
                               relief='flat',width=self.lrc_word_length,\
                               bg=color([135,206,250]),height=2)
            self.lrc_word.pack()
            self.lrc_word.tag_config("tag_1", backgroun="yellow", foreground="red")
        for i in range(len(lrc_word)):
            if i:
                self.lrc_word.insert("end", " "*length1+lrc_word[i])
            else:
                self.lrc_word.insert("end", lrc_word[i],"tag_1")
                self.lrc_word.insert("end", '\n')
        self.lrc_word.config(state=DISABLED)
    def pause(self):
        self.music.pause()
        print("pause")
    def stop(self):
        self.set_time=0
        stop1()
        print("stop")
    def play(self):
        self.music.unpause()
        print("play")
    def replay(self):
        self.set_time=0
        self.music_time_scale.set(0)
        self.music.replay()
        print("replay")
    def openfile(self):
        self.set_time=0
        openfiles()
        print("openfile")
    def set_times(self):
        time=self.music_time_scale.get()
        print(time)
        self.set_time=time
        self.music.replay(start=time)
        print("set_time")
    def openpath(self):
        self.set_time=0
        openpaths()
        print("openpath")
    def next_music(self):
        self.set_time=0
        next_musics()
        print("next_music")

五、pydub使用中遇到的一些问题

播放24位的flac音乐时,会出现播放没有声音的情况(只是偶尔有一两声尖锐的声音),后来我又尝试使用pyaudio库进行播放,发现还是有这个问题,但是查看pydub读取到的数据是正常的。

pyaudio.py文件的return paFloat32这一句似乎有问题,因为上面几句都是Int,只有这个是Float,结果改完后,pydub和pyaudio库都播放正常了,就无语。。。

pydub库不好控制播放和暂停点(可能是我不会),我又使用了pyaudio库进行了尝试,效果还挺好,就是Ubuntu 20.04的pyaudio太难装了。。。

路径字符串没有双引号且有&,命令行那边会直接报错,我自己用命令行调用ffmpeg,加上""就能正常跑,但是我去改pydub的底层,给字符串加"",也会报找不到路径的错,就很。。。不知道大家有什么别的办法不,欢迎大家交流。

       这里再贴一下使用pyaudio进行播放的代码。

六、新的尝试——pyaudio

mian3.py

from tkinter import filedialog
import show3 as show
import os
import sys
import numpy as np
import copy
import all_music3 as all_music
import time
import random
import chardet
import platform
import multiprocessing
import warnings
list_music=[]
flag_list_music=0
event2 = 0
def get_event2():
    global event2
    if event2:
        event2 = 0
        return 1
    return 0
def which(program):#别人的源码这里用来判断ffmpeg是否存在
    """
    Mimics behavior of UNIX which command.
    """
    # Add .exe program extension for windows support
    if os.name == "nt" and not program.endswith(".exe"):
        program += ".exe"

    envdir_list = [os.curdir] + os.environ["PATH"].split(os.pathsep)

    for envdir in envdir_list:
        program_path = os.path.join(envdir, program)
        if os.path.isfile(program_path) and os.access(program_path, os.X_OK):
            return program_path
if not which("ffmpeg"):
    if ('Windows'==platform.system()):
        assert False,"This program need ffmpeg to run! \nPlease download ffmpeg and put it on the same path of the program or set a Windows system path to your ffmpeg path."
    if ('Linux'==platform.system()):
        assert False,"This program need ffmpeg to run! \nPlease update ffmpeg!"
    else:
        assert False,"This system is nonsupport!"

def openfile():
    global list_music,flag_list_music
    filenames=filedialog.askopenfilenames(title = "音乐播放器",\
                    filetypes =[("常见文件",\
                                 ["*.wma","*.wav","*.mp3","*.flac",\
                                  "*.ape","*.mp4","*.m4a","*.ogg",\
                                  "*.flv"]),\
                                ("MP3文件","*.mp3"),\
                                ("FLAC文件","*.flac"),\
                                ("APE文件","*.ape"),\
                                ("WAV文件","*.wav"),\
                                ("MP4文件","*.mp4"),\
                                ("M4A文件","*.m4a"),\
                                ("OGG文件","*.ogg"),\
                                ("FLV文件","*.flv"),\
                                ("AIFF文件","*.aiff"),\
                                ("WMA文件","*.wma"),\
                                ("所有文件","*.*")])
    if filenames:
        for f in filenames:     #将音乐列表导入
            list_music.append(f)
        if (not music.get_busy()) and len(list_music):
            #music.play(list_music[0])
            play_song(list_music[0])
        elif not len(list_music):
            assert False,"未导入任何歌曲"
        flag_list_music=1       #成功导入音乐
        list_music1_num_set()
def openpath(key=None):
    global list_music,flag_list_music
    path=filedialog.askdirectory(title = "音乐播放器")
    if path:        #如果选择了文件
        #非递归查找
        #list_music1=os.listdir(path)#保存选择的音乐列表并修正为绝对路径
        #for i in range(len(list_music1)):
        #    list_music1[i]=path+"/"+list_music1[i]
        list_music1=[]  #递归查找
        for dirpath, dirnames, filenames in os.walk(path):
            for filename in filenames:
                list_music1.append(os.path.join(dirpath, filename))
        list_music2=copy.deepcopy(list_music1)#深拷贝
        for f in list_music2:       #移除不支持的格式的音乐
            extension = os.path.splitext(f)[-1]
            if not (extension==".mp3" or\
               extension==".wma" or\
               extension==".wav" or\
               extension==".ogg" or\
                extension==".flv" or\
                    extension==".mp4" or\
                    extension==".aiff" or\
                    extension==".ape" or\
                    extension==".m4a" or\
               extension==".flac"):
                list_music1.remove(f)
                #print(f+"因为不被支持被移除了")
        list_music=list_music+list_music1
        if (not music.get_busy()) and len(list_music):
            #music.play(list_music[0])
            play_song(list_music[0])
        elif not len(list_music):
            assert False,"未导入任何歌曲"
        flag_list_music=1           #成功导入音乐
        list_music1_num_set()
        
def list_music1_num_set():
        print("\nnum="+str(len(list_music)))
        show1.list_music1_num_text.set(len(list_music))
        
def next_music():           #下一首歌
    music.stop()

def play_song(song_path):
    global event2
    try:
        music.play(song_path)
    except:
        warnings.warn("The song could not be play")
        event2 = 1
        pass
    
def stop():                 #停止播放并清空播放列表
    global list_music,flag_list_music
    list_music=[]
    
    flag_list_music=1       #刷新显示
    list_music1_num_set()
    try:
        music.stop()
    except:
        pass
    
def code(path):    #判断文件的编码方式 
    f = open(path, "rb")
    f_read = f.read()
    f_charInfo = chardet.detect(f_read)
    return f_charInfo
lrc_dict={}
def get_lrc_geci():
    global lrc_dict,list_music
    if list_music:
        path=copy.deepcopy(list_music[0])#深拷贝
        for i in range(len(path)-1,-1,-1):
            if path[i]==".":
                path=path[:i]+".lrc"
                break
        try:
            file=open(path, "r", encoding=code(path)["encoding"])
            try:
                lrc_list = file.readlines()
            except:
                if code(path)["encoding"]==("GB2312" or "GBK"):
                    file=open(path, "r", encoding="GB18030")
                    lrc_list = file.readlines()
            lrc_dict = {}
            for i in lrc_list:
                lrc_word = i.replace("[", "]").strip().split("]")
                for j in range(len(lrc_word) - 1):
                    if lrc_word[j]:
                        time=0
                        flag=0
                        for k in range(len(lrc_word[j])):
                            try:
                                if lrc_word[j][k]==":":
                                    time=int(lrc_word[j][:k])*60*1000+time
                                    flag=k
                                elif flag!=0 and lrc_word[j][k]==".":
                                    time=int(lrc_word[j][flag+1:k])*1000+time
                                    time=int(lrc_word[j][k+1:])+time
                                    break
                                elif flag!=0 and k==len(lrc_word[j])-1:
                                    time=int(lrc_word[j][flag+1:k+1])*1000+time
                                    break
                            except:
                                time=0
                                break
                        if time in lrc_dict.keys():
                            if flag==0:
                                lrc_dict[time] = lrc_dict[time]+" "+lrc_word[1]
                            else:
                                lrc_dict[time] = lrc_dict[time]+" "+lrc_word[-1]
                        else:
                            if flag==0:
                                lrc_dict[time] = lrc_word[1]
                            else:
                                lrc_dict[time] = lrc_word[-1]
            time_list=list(lrc_dict.keys())
            time_list.sort()
            lrc_dict["time"]=time_list
            print("get_lrc")
            file.close()
        except:
            lrc_dict = {}
now_word=0
def get_word():
    global lrc_dict,now_word
    if lrc_dict and music.get_busy():
        for i in range(len(lrc_dict["time"])):
            if lrc_dict["time"][i]<=get_real_time()*music.speed\
               and ((len(lrc_dict["time"])==lrc_dict["time"].index(lrc_dict["time"][i])+1\
                    or (len(lrc_dict["time"])>lrc_dict["time"].index(lrc_dict["time"][i])+1 \
                        and lrc_dict["time"][i+1]>get_real_time()*music.speed))):
                now_word=lrc_dict["time"][i]
                word=[]
                word.append(lrc_dict[now_word])
                if len(lrc_dict["time"])>=lrc_dict["time"].index(lrc_dict["time"][i])+2:
                    word.append(lrc_dict[lrc_dict["time"][lrc_dict["time"].\
                                                    index(now_word)+1]])
                return word
    elif not lrc_dict:
        return ["暂无歌词"]
    else:
        return []

def get_real_time():
    return music.get_play_time()
def my_mainloop():
    global list_music,flag_list_music
    global now_word
    word=get_word()
    if word:
        show1.get_word(lrc_word=word)
    event1 = music.end_event()
    if get_event2():    #如果歌曲播放异常
        list_music.pop(0)
        print("list="+str(list_music))
        event1 = 1
        
    if event1:          #当歌曲结束时,event1事件触发
        print("over")
        flag_list_music=1       #载入新歌歌词
        if len(list_music):     #如果还有歌
            show1.set_time=0
            way=show1.play_way.get()#获取设定的播放方式
            if way==2:      #列表播放
                list_music.pop(0)
            elif way==1:    #单曲循环
                print("单曲循环中")
            elif way==3:    #列表循环
                list_music.append(list_music.pop(0))
            elif way==4:    #随机播放
                random.shuffle(list_music)
            else:
                assert False,"播放方式出错"
            print("pop")
            if len(list_music):
                #music.play(list_music[0])
                play_song(list_music[0])
            else:
                print("歌单空了")
    if flag_list_music:         #如果需要读入歌单
        now_word=0
        get_lrc_geci()          #获得歌词
        list_music_change=copy.deepcopy(list_music)#深拷贝
        path=""
        for j in range(len(list_music_change)): #得到歌曲名称
            f=list_music_change[j]
            x=-1
            for i in range(len(f)):
                if f[i]=="/":
                    x=i
            if x>=0:
                path=list_music_change[j][:x+1]
                list_music_change[j]=list_music_change[j][x+1:]
        show1.get_music_list(path=path,list_music=list_music_change)
        flag_list_music=0
    if get_real_time()>=0:
        if ((get_real_time()!=show1.music_time_scale.get()))and \
            not show1.mouse_left_click1:
            #print("set_time2")
            show1.set_length_and_now_time(now_time=get_real_time())
            show1.music_time_scale.set(get_real_time())
    show1.win.after(100,my_mainloop)
def main():
    global show1
    global music
    
    music=all_music.all_music()
    show1=show.show()
    show1.get_music(music=music,\
                    openfile=openfile,openpath=openpath,\
                    next_music=next_music,stop=stop)
    show1.win.after(100,my_mainloop)
    '''
    #The other computer set
    try:
        openpath(True)#载入默认目录
        show1.pause()
    except:
        pass
    '''
    show.mainloop()
    try:
        music.stop()
    except:
        pass
    try:
        wait_times = 0
        while(not music.end_event()):
            all_music.time.sleep(0.5)
            music.play_flag = music.flag_enum[3]
            wait_times += 1
            if (wait_times > 120):
                break
    except:
        pass
if __name__ == '__main__':
    sys.stdout = open(os.devnull, "w")
    if('Windows'==platform.system()):
        multiprocessing.freeze_support()  
    main()

all_music3.py

from pydub import AudioSegment
import pyaudio
#import multiprocessing
from threading import Thread
import time
#import psutil
import copy
import platform
class all_music():
    def __init__(self):
        self.volume=100
        self.song_path = []
        self.song = []                    #绝对
        self.song1 = []   
        self.process1 = []
        self.suffix = []
        self.now_time = -1        #当前播放歌曲的时长
        self.pos_time_set = -1  #歌曲点击播放的位置
        self.plat_form = platform.system()
        self.length = -1
        self.now_state = 1
        self.len_frame = 0
        self.busy = 0         #0:空闲;1:播放中;2:暂停中;3:暂停准备继续播放
        self.flag_end = 0
        self.speed = 1
        self.volume_limit = 20
        self.flag_enum=[0b0000,0b0001,0b0010,0b0011,0b0100,0b0101,0b0111]
        self.play_flag=self.flag_enum[0]
    def end_event(self):
            if self.flag_end == 0:
                return self.flag_end
            else:
                self.flag_end = 0
                return 1
    def get_busy(self):             #查看是否忙碌     
        return self.busy
    def get_length(self):           #得到歌曲长度
        return self.length
    def pos_set(self,time):         #设置歌曲播放位置
        self.pos_time_set = int(time / self.length * self.len_frame)
        self.play_flag = self.flag_enum[2]
    def get_play_time(self):        #获得当前歌曲播放到的位置
        if self.len_frame == 0:
            return 0
        else:
            return int(self.length * self.now_time / self.len_frame)

    def set_speed(self,speed):
        self.speed=speed
        self.play_flag = self.flag_enum[5]
    def set_volume(self,volume):
        self.volume=volume
        self.play_flag = self.flag_enum[6]
    def get_volume(self):
        return self.volume    
    def replay(self):
        if self.busy:   #判断歌曲是否在播放或者暂停状态
            self.play_flag = self.flag_enum[4]
            self.busy=1
        else:
            assert False,"歌曲未载入或占用中,请先load或stop"
            
    def play_song(self):
            self.now_state = 0
            print("play_song")
            print(self.song_path)
            p = pyaudio.PyAudio()
            
            
            if self.volume == 0:
                self.song1 = self.song - 255
            else:
                self.song1 = self.song - self.volume_limit * ( 1.0 - self.volume / 100 )
            # 读取音频帧并进行播放

            
            if "Windows" == self.plat_form:#其实windows也可以用下面的raw方式播放,这一段其实有没有都行
                index = 0
                stream = p.open(format = p.get_format_from_width(self.song1.sample_width),
                             channels = self.song1.channels,
                             rate = int(self.song1.frame_rate*self.speed),
                             output = True)
                self.len_frame = int(self.song1.frame_count())
                while(index <= self.len_frame):
                    stream.write(self.song1.get_frame(index))
                    self.now_time = index
                    if(self.play_flag >0):
                            print(2)
                            if self.play_flag == self.flag_enum[1]:#暂停
                                    print(3)
                                    while(1):
                                            time.sleep(0.5)
                                            if self.play_flag != self.flag_enum[1]:
                                                    break
                            if self.play_flag == self.flag_enum[2]:#点击播放
                                    print(4)
                                    index = self.pos_time_set
                                    self.play_flag = self.flag_enum[0]
                            if self.play_flag == self.flag_enum[3]:#终止播放
                                    print(5)
                                    index = self.len_frame
                                    self.play_flag = self.flag_enum[0]
                                    break
                            if self.play_flag == self.flag_enum[4]:#重新播放
                                    print(6)
                                    index = 0
                                    self.now_time = 0
                                    self.play_flag = self.flag_enum[0]
                            if self.play_flag == self.flag_enum[5]:#速度变化
                                    print(7)
                                    #stream.stop_stream()
                                    #stream.close()
                                    stream = p.open(format = p.get_format_from_width(self.song1.sample_width),
                                            channels = self.song1.channels,
                                            rate = int(self.song1.frame_rate*self.speed),
                                            output = True)
                                    self.play_flag = self.flag_enum[0]
                            if self.play_flag == self.flag_enum[6]:#音量变化
                                    print(8)
                                    if self.volume == 0:
                                            self.song1 = self.song - 255
                                    else:
                                            self.song1 = self.song - self.volume_limit * ( 1.0 - self.volume / 100 )
                                    self.play_flag = self.flag_enum[0]
                    index += 1
                
            else:#对于某些系统,如ubuntu,似乎只能用raw方式播放
                frames_per_buffer = 1024
                stream = p.open(format = p.get_format_from_width(self.song1.sample_width),
                             channels = self.song1.channels,
                             rate = int(self.song1.frame_rate*self.speed),
                             output = True,
                             frames_per_buffer = frames_per_buffer)
                self.len_frame = int(len(self.song1.raw_data))
                per_index = 0
                index = frames_per_buffer
                while(index <= self.len_frame):
                    stream.write(self.song1.raw_data[per_index:index])
                    self.now_time = index
                    per_index = index
                    if(self.play_flag >0):
                            print(2)
                            if self.play_flag == self.flag_enum[1]:#暂停
                                    print(3)
                                    while(1):
                                            time.sleep(0.5)
                                            if self.play_flag != self.flag_enum[1]:
                                                    break
                            if self.play_flag == self.flag_enum[2]:#点击播放
                                    print(4)
                                    index = self.pos_time_set
                                    if index % 2 :
                                        index -= 1
                                    per_index = index - frames_per_buffer
                                    if per_index < 0:
                                        per_index = 0
                                        index = frames_per_buffer
                                    self.play_flag = self.flag_enum[0]
                            if self.play_flag == self.flag_enum[3]:#终止播放
                                    print(5)
                                    index = self.len_frame
                                    self.play_flag = self.flag_enum[0]
                                    break
                            if self.play_flag == self.flag_enum[4]:#重新播放
                                    print(6)
                                    index = frames_per_buffer
                                    per_index = 0
                                    self.now_time = 0
                                    self.play_flag = self.flag_enum[0]
                            if self.play_flag == self.flag_enum[5]:#速度变化
                                    print(7)
                                    #stream.stop_stream()
                                    #stream.close()
                                    stream = p.open(format = p.get_format_from_width(self.song1.sample_width),
                                            channels = self.song1.channels,
                                            rate = int(self.song1.frame_rate*self.speed),
                                            output = True,
                                            frames_per_buffer = frames_per_buffer)
                                    self.play_flag = self.flag_enum[0]
                            if self.play_flag == self.flag_enum[6]:#音量变化
                                    print(8)
                                    if self.volume == 0:
                                            self.song1 = self.song - 255
                                    else:
                                            self.song1 = self.song - self.volume_limit * ( 1.0 - self.volume / 100 )
                                    self.play_flag = self.flag_enum[0]
                    index += frames_per_buffer
                if self.len_frame > index:
                    stream = p.open(format = p.get_format_from_width(self.song1.sample_width),
                        channels = self.song1.channels,
                        rate = int(self.song1.frame_rate*self.speed),
                        output = True,
                        frames_per_buffer = self.len_frame - index)
                    stream.write(self.song1.raw_data[index:])
            
            print(9)
            print(index)
            print(self.len_frame)
            self.busy = 0
            # 停止数据流
            stream.stop_stream()
            stream.close()
            
            # 关闭 PyAudio
            p.terminate()
            self.flag_end = 1
            while(0 != self.flag_end):
                time.sleep(1)
            self.now_state = 1
    
    def play(self, file_path):                 #播放歌曲
        #判断歌曲是否在播放或者暂停状态
        if ( self.busy == 0 ):
            if file_path:   #判断路径是否为空
                self.song_path = file_path    #将歌曲路径给到self
                for i in range(len(self.song_path)-1,-1,-1):    #寻找文件后缀
                    if self.song_path[i] == ".":
                        break
                if self.song_path[i]==".":                      #将歌曲后缀给到self
                    self.suffix=self.song_path[i+1:]
                else:
                    assert False,"未发现文件后缀"
            else:
                assert False,"load(file_path)需要一个歌曲路径"
            if self.suffix:#是否有下标
                if self.suffix=="mp3":      #导入mp3歌曲
                        try:
                            self.song = AudioSegment.from_mp3(self.song_path)
                        except:
                            assert False,"不支持的文件或不存在此文件:"+self.song_path
                elif self.suffix=="ogg":    #导入ogg歌曲
                        try:
                            self.song = AudioSegment.from_ogg(self.song_path)
                        except:
                            assert False,"不支持的文件或不存在此文件:"+self.song_path
                elif self.suffix=="flv":    #导入flv歌曲
                        try:
                            self.song = AudioSegment.from_flv(self.song_path)
                        except:
                            assert False,"不支持的文件或不存在此文件:"+self.song_path
                elif self.suffix=="wav":    #导入wav歌曲
                        try:
                            self.song = AudioSegment.from_wav(self.song_path)
                        except:
                            assert False,"不支持的文件或不存在此文件:"+self.song_path 
                else:                       #导入其他支持的格式的歌曲
                    try:
                        self.song = AudioSegment.from_file(self.song_path,self.suffix)
                    except:
                        assert False,"不支持的文件或不存在此文件:"+self.song_path
                self.song1=copy.deepcopy(self.song)
                self.busy = 1
                self.length=len(self.song1)   #设置歌曲时长
                self.process1 = Thread(target =self.play_song,name="my_process1")
                self.process1.start()
                
            else:
                assert False,"未载入任何歌曲"
        else:
            assert False,"歌曲未载入或占用中,请先load或stop"
    def stop(self):     
        if self.busy:   #判断歌曲是否在播放或者暂停状态
            self.play_flag = self.flag_enum[3]
            self.process1 = []
            self.now_time = 0
            self.pos_time_set = 0
            self.length = 0
        else:
            assert False,"歌曲不在播放或暂停状态"
    def pause(self):    #暂停播放
        if 1 == self.busy:   #判断歌曲是否在播放状态
            
            self.play_flag = self.flag_enum[1]
            self.busy = 2
            
        else:
            assert False,"无歌曲正在播放"
    def unpause(self):  #继续暂停的播放
        if 2 == self.busy:   #判断歌曲是否在播放状态
            self.busy=3
            self.play_flag = self.flag_enum[0]
            self.busy = 1
        else:
            assert False,"歌曲不在暂停状态"

show3.py

from tkinter import *
from PIL import Image
import tkinter.font as tkFont
from tkinter import ttk
import platform
def color(color_255):
    color_16=0x0
    color_16=color_16+0x10000*(color_255[0])
    color_16=color_16+0x100*(color_255[1])
    color_16=color_16+0x1*(color_255[2])
    if color_16>0xFFFFF:
        return '#%0x'%color_16
    elif color_16>0xFFFF:
        return '#0%0x'%color_16
    elif color_16>0xFFF:
        return '#00%0x'%color_16
    elif color_16>0xFF:
        return '#000%0x'%color_16
    elif color_16>0xF:
        return '#0000%0x'%color_16
    else:
        return '#00000%0x'%color_16
openfiles=[]
openpaths=[]
next_musics=[]
stop=[]
typeface=u"华文行楷"

if(platform.system()=='Windows'):
    size_word_win='1000x80'
elif(platform.system()=='Linux'):
    size_word_win='1000x100'
else:
    assert False,'暂未支持Windows和Linux之外的系统'
    
class show():
    def __init__(self): 
        #主窗口
        #anchor must be n, ne, e, se, s, sw, w, nw, or center
        self.mouse_left_click1=0#鼠标左键点击时间轴状态
        self.mouse_left_click2=0#鼠标左键点击音量状态
        self.set_time=0
        self.flag_replay=0
        self.win = Tk()
        self.volume_limit = 120
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.win.title(u"我的音乐")
        try:
            self.win.iconbitmap('My_Music_tk.ico') # 更改窗口图标
        except:
            pass
        self.win.bind("<Key>",self.key_event)
        self.screenwidth=self.win.winfo_screenwidth()
        self.screenheight=self.win.winfo_screenheight()
        self.win.resizable(width=False,height=False)#False表示不可以缩放,True表示可以缩放
        try:
            self.win.iconphoto(True, PhotoImage(file='/home/xiaobai/Desktop/my_music/My_Music_tk.png'))
        except:
            pass
        self.frame= Frame (self.win, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,heigh=600,width=1280,cursor='arrow')
        self.frame.pack(side=TOP, fill=BOTH, ipadx=0, ipady=0, expand=1)
        #音乐列表frame
        self.frame2= Frame (self.frame, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,cursor='arrow')
        self.frame2.pack(side=TOP,fill=X,ipadx=0,ipady=0,expand=1)
        self.frame21= Frame (self.frame2,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame21.pack(side=BOTTOM,fill=X,ipadx=0,ipady=0,expand=1)
        self.frame22= Frame (self.frame2,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame22.pack(side=TOP,fill=X,ipadx=0,ipady=0,expand=1)
        #按钮frame
        self.frame1= Frame (self.frame, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,cursor='arrow')
        self.frame1.pack(side=TOP,fill=X,ipadx=0,ipady=0,expand=1)
        
        #歌词frame
        self.frame3= Frame (self.frame, relief=RAISED, bg=color([135,206,250]),\
                           borderwidth=2,cursor='arrow')
        self.frame3.pack(side=BOTTOM,fill=X,ipadx=0,ipady=0,expand=0)
        #按钮
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"暂停",command =self.pause)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"播放",command =self.play)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"重新播放",command =self.replay)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"下一首",command =self.next_music)\
                .pack (side=LEFT, padx=13, pady=13)
        self.frame11= Frame (self.frame1,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame11.pack(side=LEFT,fill=Y,ipadx=20,ipady=0,expand=0)
        Button (self.frame1,font=ft,bg=color([59,210,61])\
                ,activebackground="white",\
                text=u"清空",command =self.stop)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([242,203,46])\
                ,activebackground="white",\
                text=u"文件夹",command =self.openpath)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([242,169,0])\
                ,activebackground="white",\
                text=u"文件",command =self.openfile)\
                .pack (side=LEFT, padx=13, pady=13)
        
        #一些文本显示
        #显示“播放列表”文本
        ft = tkFont.Font(family=typeface, size=20, weight=tkFont.BOLD)
        self.frame221= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame221.pack(side=LEFT)
        Label(self.frame221,font=ft,\
              text=u"播",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"放",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"列",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"表",bg=color([135,206,250])).pack(anchor='w')
        #显示“倍速”文本
        ft = tkFont.Font(family=typeface, size=10, weight=tkFont.BOLD)
        self.frame222= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame222.pack(anchor='w')
        Label_b=Label(self.frame222,font=ft,\
              text=u"   倍速",bg=color([135,206,250]))
        Label_b.pack(side=LEFT)
        #倍速设置
        self.set_comvalue=StringVar()#窗体自带的文本,新建一个值
        self.set_templist=ttk.Combobox(self.frame222,font=ft,\
                                       textvariable=self.set_comvalue,\
                                       state='readonly',\
                                       width=3) #初始化    
        self.set_templist["values"]=("0.8","0.9","1","1.2","1.4")
        self.set_templist.current(2) #选择第一个
        self.set_templist['state'] = 'readonly'#只读
        self.set_templist.bind("<<ComboboxSelected>>",self.music_speed) #绑定事件,(下拉列表框被选中时,绑定go()函数)
        self.set_templist.pack(side=LEFT,padx=10)
        #列表
        #音乐列表
        self.frame224= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame224.pack(side="left")
        self.list_music1_sb = Scrollbar(self.frame224)
        self.list_music1_sb.pack(side="right", fill="y")
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.list_music1=Listbox(self.frame224,bg=color([255,255,255]),\
                            cursor='plus',font=ft,\
                            fg=color([0,0,0]),height=5,width=40,\
                            yscrollcommand= self.list_music1_sb.set)
        self.list_music1.pack(side="left", fill="both")
        self.list_music1_sb.config(command=self.list_music1.yview)
        ft = tkFont.Font(family=typeface, size=10, weight=tkFont.BOLD)
        self.list_music1_num_text = IntVar()
        self.list_music1_num_text.set(0)
        Label_c=Label(self.frame222,font=ft,\
              text=u"歌曲总数:",bg=color([135,206,250]))\
              .pack(side=LEFT)
        Label(self.frame222,font=ft,textvariable=self.list_music1_num_text,\
              bg=color([135,206,250])).pack(side=LEFT)
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        #播放模式设置
        self.frame222= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame222.pack(side=LEFT)
        WAY_SET = [("单曲循环", 1),("列表播放", 2),("列表循环", 3),("随机播放", 4)]
        self.play_way = IntVar()
        self.play_way.set(2)
        for way, num in WAY_SET:
            Radiobutton(self.frame222, text=way, variable=self.play_way,\
                    indicatoron=False, value=num,\
                    font=ft,bg=color([135,206,250]),\
                    activebackground=color([255,192,203]),\
                    cursor='circle',selectcolor=color([192,192,192]),\
                    ).pack(anchor="w")
        #音量
        self.frame223= Frame (self.frame22,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame223.pack(side=LEFT,padx=5)
        Label_c=Label(self.frame223,font=ft,\
              text=u"音量",bg=color([135,206,250]))
        Label_c.pack(anchor="w")
        self.volume_text = IntVar()
        self.volume_text.set(100)
        self.music_volume=Scale(self.frame223,from_=100, to=0, \
              length=100, \
              orient="vertical",\
              activebackground=color([128,128,128]),\
              bg=color([200,200,200]),font=ft,\
              bd=0,sliderrelief="ridge",sliderlength=20,\
              showvalue=False,variable=self.volume_text)
        self.music_volume.pack(after=Label_c,padx=10)
        if(platform.system()=='Windows'):
            self.music_volume.bind("<MouseWheel>",self.mouse_middle_motion_volume)
        elif(platform.system()=='Linux'):
            self.music_volume.bind("<Button-4>",self.mouse_middle_motion_volume)
            self.music_volume.bind("<Button-5>",self.mouse_middle_motion_volume)
        else:
            assert False,'暂未支持Windows和Linux之外的系统'
        self.music_volume.bind("<Button-1>",self.mouse_left_click_volume)
        self.music_volume.bind("<ButtonRelease-1>",self.mouse_left_release_volume)
        
        Label(self.frame223,font=ft,textvariable=self.volume_text,\
              bg=color([135,206,250])).pack(after=self.music_volume)
        #当前时间
        self.now_time_text = StringVar()
        self.now_time_text.set("0"+":"+"00")
        ft = tkFont.Font(family=u"微软雅黑", size=10, weight=tkFont.BOLD)
        Label(self.frame21,font=ft,textvariable=self.now_time_text,\
              bg=color([135,206,250])).pack(side=LEFT, padx=0, pady=5)
        #歌曲进度
        self.music_time_scale_length=600
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.frame211= Frame (self.frame21,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame211.pack(side=LEFT)
        self.music_time_scale=Scale(self.frame211,from_=0, to=180000, \
              length=self.music_time_scale_length, cursor="circle",\
              orient="horizontal",\
              activebackground=color([128,128,128]),\
              bg=color([200,200,200]),font=ft,\
              bd=0,sliderrelief="ridge",sliderlength=20,\
              showvalue=False)
        self.music_time_scale.pack(side=LEFT,padx=5, pady=0)
        self.music_time_scale.bind("<Button-1>",self.mouse_left_click_fun)
        self.music_time_scale.bind("<ButtonRelease-1>",self.mouse_left_release_fun)
        #总时间
        self.length_text = StringVar()
        self.length_text.set("0"+":"+"00")
        ft = tkFont.Font(family=u"微软雅黑", size=10, weight=tkFont.BOLD)
        Label(self.frame21,font=ft,textvariable=self.length_text,\
              bg=color([135,206,250])).pack(side=LEFT, padx=0, pady=5)
        #歌词
        '''
        self.lrc_word_length=40
        ft = tkFont.Font(family=u"宋体", size=25, weight=tkFont.BOLD)
        self.lrc_word=Listbox(self.frame3,bg=color([255,255,255]),\
                            cursor='plus',font=ft,\
                            fg=color([0,0,0]),height=2,width=self.lrc_word_length)
        self.lrc_word.pack(side=BOTTOM,fill=Y,ipadx=0,ipady=0,expand=0)
        '''
        ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
        self.son_win=Toplevel(master=self.win)      #子窗口
        self.son_win.title("我的歌词")
        self.son_win.geometry(size_word_win+'+'+str(self.screenwidth//2-500)+'+'+str(self.screenheight-120))     
        #大小和位置
        self.son_win.wm_attributes('-topmost',1)    #置顶
        self.son_win.overrideredirect(boolean=True)#去掉边框和按钮
        if platform.system()=='Linux':
            self.son_win.wait_visibility(self.son_win)
        self.son_win.attributes('-alpha',0.9)       #整体透明
        #self.son_win.attributes("-transparentcolor","white")#此处将white颜色设置为透明,可以替换不同的颜色。
        #self.son_win.attributes("-transparentcolor",color([135,206,250]))#此处将white颜色设置为透明,可以替换不同的颜色。
        
        self.son_win.bind("<B1-Motion>", self.move)
        self.son_win.bind("<Button-1>", self.get_point)
        #self.son_win.attributes("-toolwindow", True)#实现menu点击虚线(tearoff)后的窗口效果
        #protocol(name=None, func=None)#指定窗口关闭时调用的函数
        '''
        --将回调函数func与相应的规则name绑定

        --name参数可以是“WM_DELETE_WINDOW”:窗口被关闭的时候

        --name参数可以是“WM_SAVE_YOURSELF”:窗口被保存的时候

        --name参数可以是“WM_TAKE_FOCUS”:窗口获得焦点的时候

        '''
        #withdraw()#将窗口从屏幕上移除(并没有销毁)
        '''
        --需要重新显示窗口,使用deiconify()方法

        --该方法会使得state()返回"withdraw"
        '''
        self.frame_son_win= Frame (self.son_win,relief=RAISED, \
                             bg=color([135,206,250]),\
                           borderwidth=0)
        self.frame_son_win.pack(fill=BOTH,expand=1)
        self.lrc_word_length=40
        ft = tkFont.Font(family=typeface, size=20, weight=tkFont.BOLD)
        self.lrc_word=Text(self.frame_son_win,font=ft,\
                               relief='flat',width=self.lrc_word_length,\
                               bg=color([135,206,250]),height=2)
        self.lrc_word.tag_config("tag_1", backgroun="yellow", foreground="red")
        self.lrc_word.pack()
        self.lrc_word.config(state=DISABLED)
        self.word_win_state = IntVar()
        self.word_win_state_button=Checkbutton(self.frame1,font=ft,bg=color([135,206,250]),\
                text=u"词",variable=self.word_win_state,\
                command=self.show_or_hide_word,indicatoron=False,\
                activebackground=color([255,192,203]),\
                selectcolor=color([192,192,192]))
        self.word_win_state_button.pack (side=LEFT, padx=13, pady=13)
        self.word_win_state_button.select()
    def key_event(self,event):
        key=event.keysym
        if key=='space':
            if self.music.get_busy()==1:
                self.pause()
            elif self.music.get_busy()==2:
                self.play()
        elif key=='Up':
            self.mouse_middle_motion_volume([],1)
        elif key=='Down':
            self.mouse_middle_motion_volume([],-1)
    def show_or_hide_word(self):
        if self.word_win_state.get():
            self.son_win.deiconify()
        else:
            self.son_win.withdraw()
        #print(self.word_win_state.get())
    def get_point(self, event):
        """获取当前窗口位置并保存"""
        self.x, self.y = event.x, event.y
    def move(self, event):
        """窗口移动事件"""
        new_x = (event.x - self.x) + self.son_win.winfo_x()
        new_y = (event.y - self.y) + self.son_win.winfo_y()
        s = size_word_win+f"+{new_x}+{new_y}"     
        self.son_win.geometry(s)
    def mouse_middle_motion_volume(self,event,key=None):
        if('Windows'==platform.system()):
            x=120
            if key==None:
                flag = event.delta//x
                
        elif('Linux'==platform.system()):
            x=4
            if key==None:
                if(event.num==x):
                    flag=1
                elif event.num==x+1:
                    flag=-1
                else:
                    assert False,'Linux下事件错误'
        else:
            assert False,'暂未支持Windows和Linux之外的系统'
        if key!=None:
            if key==1:
                flag=1
            elif key==-1:
                flag=-1
            else:
                assert False,'key输入错误'
        if flag>0:
            print("get_volume="+str(self.music.get_volume())+"dB")
            if self.music.get_volume() < self.volume_limit:
                if 100 == self.music_volume.get():
                    volume=self.music.get_volume()+10*flag
                    self.volume_text.set(volume)
                else:
                    volume = self.music_volume.get() + 10 * flag
                    self.music_volume.set(volume)
                    self.volume_text.set(volume)
                if volume > self.volume_limit:      #防止win系统flag轰炸
                    volume = self.volume_limit
                self.music.set_volume(volume)
                self.win.update()       #强制刷新
        else:
            if self.music.get_volume()!=0:
                if 100<self.music.get_volume():
                    volume=self.music.get_volume()+10*flag
                    self.volume_text.set(volume)
                else:
                    volume=self.music_volume.get()+10*flag
                    if volume<0:
                        volume=0
                    self.music_volume.set(volume)
                    self.volume_text.set(volume)
                self.music.set_volume(volume)
                self.win.update()       #强制刷新
    def mouse_left_click_volume(self,event):
        state=self.music_volume.identify(event.x,event.y)
        if state!='slider':
            volume=100-event.y
            #self.music.set_volume(volume)
            self.music_volume.set(volume)
            self.volume_text.set(volume)
            self.win.update()       #强制刷新
            self.mouse_left_click2 = 1
            print("mouse_set_volume")
        else:
            self.mouse_left_click2=1
            print("slide_scale")
    def mouse_left_release_volume(self,event):
        if self.mouse_left_click2==1:
            volume=self.music_volume.get()
            self.volume_text.set(volume)
            self.music_volume.set(volume)
            self.music.set_volume(volume)
            self.set_time=self.music.get_play_time()
            
            self.win.update()       #强制刷新
            print("slide_scale_set_volume")
        self.mouse_left_click2=0
    def music_speed(self,*args):
        speed=float(self.set_templist.get())
        self.set_time=self.music.get_play_time()
        self.music.set_speed(speed) 
        self.win.update()       #强制刷新
    def set_length_and_now_time(self,now_time,music_length=None):
        if music_length!=None:
            #self.length_text.set(str(int(music_length*self.music.speed//(1000*60))).zfill(1)\
            #                     +":"+str(int(music_length*self.music.speed//1000%60)).zfill(2))
            self.length_text.set(str(int(music_length//(1000*60))).zfill(1)\
                                 +":"+str(int(music_length//1000%60)).zfill(2))
        #time=int(now_time*self.music.speed)
        time=int(now_time)
        self.now_time_text.set(str(time//(1000*60)).zfill(1)\
                                 +":"+str(time//1000%60).zfill(2))
    def mouse_left_click_fun(self,event):
        state=self.music_time_scale.identify(event.x,event.y)
        if state!='slider':
            self.set_time=int(event.x/self.music_time_scale_length*self.music.get_length())
            self.music_time_scale.set(self.set_time)
            self.win.update()       #强制刷新
            #self.music.stop()
            self.music.pos_set(self.set_time)
            self.mouse_left_click1=2
            print("mouse_set_time")
        else:
            self.mouse_left_click1=1
            print("slide_scale")
        #print(f"鼠标左键点击了一次坐标是:x={event.x},y={event.y}")
    def mouse_left_release_fun(self,event):
        if self.mouse_left_click1==1:
            if event.x<0:
                event_x=0
            elif event.x>self.music_time_scale_length:
                event_x=self.music_time_scale_length
            else:
                event_x=event.x
            self.set_time=int(event_x/self.music_time_scale_length*self.music.get_length())
            self.music_time_scale.set(self.set_time)
            self.win.update()       #强制刷新
            #self.music.stop()
            
            self.music.pos_set(self.set_time)
            print("slide_scale_set_time")
        self.mouse_left_click1=0
        #print(f"鼠标左键释放坐标是:x={event.x},y={event.y}")
    def get_music(self,music,openfile,openpath,next_music,stop):
        self.music=music
        global openfiles
        openfiles=openfile
        global openpaths
        openpaths=openpath
        global next_musics
        next_musics=next_music
        global stop1
        stop1=stop
    def get_music_list(self,path,list_music):
        self.list_music1.delete(0,"end")
        for item in list_music:
            self.list_music1.insert("end", item)
        self.music_time_scale.pack_forget()
        if path:
            ft = tkFont.Font(family=typeface, size=15, weight=tkFont.BOLD)
            self.music_time_scale=Scale(self.frame211,from_=0, \
                                        to=self.music.get_length(), \
                  length=self.music_time_scale_length, cursor="circle",\
                  orient="horizontal",\
                  activebackground=color([128,128,128]),\
                  bg=color([200,200,200]),font=ft,\
                  bd=0,sliderrelief="ridge",sliderlength=20,\
                  showvalue=False)
            self.music_time_scale.pack(side=LEFT,padx=5, pady=0)
            self.music_time_scale.bind("<Button-1>",self.mouse_left_click_fun)
            self.music_time_scale.bind("<ButtonRelease-1>",self.mouse_left_release_fun)
            self.set_length_and_now_time(now_time=self.set_time,music_length=self.music.get_length())
    def get_word(self,lrc_word):
        self.lrc_word.config(state=NORMAL)
        try:
            self.lrc_word.delete(1.0,"end")
        except:
            pass
        length=0
        length1=0
        if len(lrc_word)==1 or lrc_word[1]=='':
            for ch in lrc_word[0]:
                if u'\u4e00'<=ch<=u'\u9fff':
                    length=length+2.8
                else:
                    length=length+1
            length=int(length)
        else:
            for i in range(len(lrc_word)):
                if i:
                    length1=round(length/2)
                    length=length1
                    for ch in lrc_word[i]:
                        if u'\u4e00'<=ch<=u'\u9fff':
                            length=length+2.8
                        else:
                            length=length+1
                else:
                    for ch in lrc_word[i]:
                        if u'\u4e00'<=ch<=u'\u9fff':
                            length=length+2.8
                        else:
                            length=length+1
                length=int(length)
        if self.lrc_word_length!=length:
            self.lrc_word.pack_forget()
            self.lrc_word_length=int(length)
            ft = tkFont.Font(family=typeface, size=25, weight=tkFont.BOLD)
            self.lrc_word=Text(self.frame_son_win,font=ft,\
                               relief='flat',width=self.lrc_word_length,\
                               bg=color([135,206,250]),height=2)
            self.lrc_word.pack()
            self.lrc_word.tag_config("tag_1", backgroun="yellow", foreground="red")
        for i in range(len(lrc_word)):
            if i:
                self.lrc_word.insert("end", " "*length1+lrc_word[i])
            else:
                self.lrc_word.insert("end", lrc_word[i],"tag_1")
                self.lrc_word.insert("end", '\n')
        self.lrc_word.config(state=DISABLED)
    def pause(self):
        self.music.pause()
        print("pause")
    def stop(self):
        self.set_time=0
        stop1()
        print("stop")
    def play(self):
        self.music.unpause()
        print("play")
    def replay(self):
        self.set_time=0
        self.music_time_scale.set(0)
        #self.music.stop()
        self.music.replay()
        print("replay")
    def openfile(self):
        self.set_time=0
        openfiles()
        print("openfile")
    def set_times(self):
        time=self.music_time_scale.get()
        print(time)
        self.set_time=time
        #self.music.stop()
        self.music.pos_set(time)
        print("set_time")
    def openpath(self):
        self.set_time=0
        openpaths()
        print("openpath")
    def next_music(self):
        self.set_time=0
        next_musics()
        print("next_music")
#show1=show()
#mainloop()

就先到这吧,想到什么再写,有什么问题欢迎留言。