Learning notes: music player based on Tkinter and pydub under UBUNTU platform

1, Summary

        This is a study note. There are many players on the market, so why do you want to do this? One thing is to learn some knowledge in the process of making this software. Another is that software such as cool dog and QQ music are often exposed to malicious deletion of local audio on the Internet, and groove can't play lyrics. Thousands of listening is a better local playback device, But I don't have the freedom to write by myself.

         This paper implements an almost full format music player encapsulated by normal executable files on ubuntu platform; On the win platform, the command line will pop up due to the FFmpeg dependency of pydub. Due to horizontal restrictions, at present, only exe encapsulation with command line window can be realized. For the shortcomings of this article, I hope you can give me some advice.

 

  2, File structure

It is divided into three documents:

all_music.py is based on pydub and is used to obtain music. It can realize the functions of song loading, playback, length acquisition, playback time acquisition, double speed playback, pause, end all playback processes, playback status acquisition, etc

show2.py is based on tkinter and is used to visualize the player interface. It is expected to add functions such as volume increase and decrease and favorite list.

main2.py central scheduling, used to transfer file path, get the song and song list functions.

3, Packaging method

         Package using pyinstaller -w -F -n target name and file name (for example, pyinstaller -w -F -n my_music main2.py).

         The author has tried many times and found many methods on the Internet, but I can't modify this icon. I saw an article. It seems that this icon can't be modified because of Ubuntu system restrictions. I don't know if you have any way.

         The author directly created a new my in / usr/share/application_ The music.desktop file links the executable file and picture, so it has the following effects:

 

My_Music.desktop is set as follows:

[Desktop Entry]    #You have to tell the system what this is
Version=1.0        #Optional, display version information
Name=My_Music        #Software name
Comment=A Music Player    #The text displayed when the mouse is over the icon
Exec=/home/xiaobai/Desktop/my_music/my_music    #Executable path (absolute path)
Icon=/home/xiaobai/Desktop/my_music/My_Music.jpeg    #I hope to use the picture as a software icon. This one is Baidu's, preferably a square. You can also cut it yourself
Encoding=UTF-8        #Optional, encoding method
StartupNotify=true    #It's not clear what the use is
Terminal=false        #Open command line
Type=Application    #type
Categories=Audio;Player    #Category. The music player is selected here. The specific optional values can be determined by Baidu

  4, main2.py

from tkinter import filedialog
import show2
import os
import numpy as np
import copy
import all_music
import time
import random
list_music=[]
flag_list_music=0
def openfile():    #Open a file
    global list_music,flag_list_music
    filenames=filedialog.askopenfilenames(title = "music player ",\
                    filetypes =[("Common files",\
                                 ["*.wma","*.wav","*.mp3","*.flac",\
                                  "*.ape","*.mp4","*.m4a","*.ogg",\
                                  "*.flv"]),\
                                ("MP3 file","*.mp3"),\
                                ("FLAC file","*.flac"),\
                                ("APE file","*.ape"),\
                                ("WAV file","*.wav"),\
                                ("MP4 file","*.mp4"),\
                                ("M4A file","*.m4a"),\
                                ("OGG file","*.ogg"),\
                                ("FLV file","*.flv"),\
                                ("AIFF file","*.aiff"),\
                                ("WMA file","*.wma"),\
                                ("All documents","*.*")])
    if filenames:
        for f in filenames:     #Import music list into
            list_music.append(f)
        if (not music.get_busy()) and len(list_music):
            try:
                music.load(list_music[0])
            except:
                pass
            music.play()
        elif not len(list_music):
            assert False,"No songs were imported"
        flag_list_music=1       #Successfully imported music
def openpath():        #Import common music files in a directory, excluding files in subdirectories
    global list_music,flag_list_music
    path=filedialog.askdirectory(title = "music player ")
    if path:        #If a file is selected
        list_music1=os.listdir(path)#Save the selected music list and fix it to an absolute path
        for i in range(len(list_music1)):
            list_music1[i]=path+"/"+list_music1[i]
        list_music2=copy.deepcopy(list_music1)#Deep copy
        for f in list_music2:       #Remove music in unsupported formats
            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+"Removed because it is not supported")
        list_music=list_music+list_music1
        if (not music.get_busy()) and len(list_music):
            try:
                music.load(list_music[0])
            except:
                pass
            music.play()
        elif not len(list_music):
            assert False,"No songs were imported"
        flag_list_music=1           #Successfully imported music
def next_music():           #Next song
    global list_music,flag_list_music
    music.stop()
    music.unload()
    way=show1.play_way.get()        #Get the set playback mode
    if way==2:              #List play
        list_music.pop(0)
    elif way==1:            #Single tune circulation
        if len(list_music)>1:
            list_music.pop(0)
        print("Single cycle")
    elif way==3:            #List loop
        list_music.append(list_music.pop(0))
    elif way==4:            #Random play
        random.shuffle(list_music)
    else:
        assert False,"Error in playback mode"
    flag_list_music=1               #Refresh display
    if len(list_music):
        music.load(list_music[0])
        music.play()
    else:
        assert False,"There's no next song"
def stop():                 #Stop playing and empty the playlist
    global list_music,flag_list_music
    list_music=[]
    music.stop()
    music.unload()
    flag_list_music=1       #Refresh display
lrc_dict={}
def get_lrc_geci():        #Try opening the song lyrics file
    global lrc_dict,list_music
    if list_music:
        path=copy.deepcopy(list_music[0])#Deep copy
        for i in range(len(path)-1,-1,-1):
            if path[i]==".":
                path=path[:i]+".lrc"
        try:
            file=open(path, "r", encoding="utf-8")
            
            lrc_list = file.readlines()
            
            # '[01:48.00], [00:24.00], floating in the distance with a cooled heart'
            # Create a dictionary to store lyrics and time. key represents time and value represents lyrics
            lrc_dict = {}
            # Traverse all elements and eliminate square brackets
            for i in lrc_list:
                # Take out the square brackets and cut the lyrics string
                lrc_word = i.replace("[", "]").strip().split("]")
                
                # Results obtained: LRC_ Word = ['','01:40.00 ',' ','00:16.00', 'I watched the snow drift in the cold night today']
                for j in range(len(lrc_word) - 1):
                    if lrc_word[j]:
                        time=0
                        for k in range(len(lrc_word[j])):
                            try:
                                if lrc_word[j][k]==":":
                                    time=int(lrc_word[j][:k])*60*1000+time
                                elif lrc_word[j][k]==".":
                                    time=int(lrc_word[j][3:k])*1000+time
                                    time=int(lrc_word[j][k+1:])+time
                                    break
                            except:
                                print(lrc_word[j])
                        lrc_dict[time] = lrc_word[-1]        
            lrc_dict["time"]=list(lrc_dict.keys())
            print("get_lrc")
            file.close()
        except:
            lrc_dict = {}
now_word=0
def get_word():    #Get the lyrics of the current time
    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 ["No lyrics"]
    else:
        return []

def get_real_time():        #Get the real time when the song is played
    return music.get_play_time()
def my_mainloop():        #Main cycle
    global list_music,flag_list_music
    global event1,now_word
    word=get_word()        #Get current time lyrics
    if word:
        show1.get_word(lrc_word=word)
    event1=music.pop_event()
    if event1:          #event1 event is triggered only when the song ends normally
        print("over")
        flag_list_music=1       #Load new song lyrics
        if len(list_music):     #If there's a song
            show1.set_time=0
            way=show1.play_way.get()#Get the set playback mode
            if way==2:      #List play
                list_music.pop(0)
            elif way==1:    #Single tune circulation
                print("Single cycle")
            elif way==3:    #List play
                list_music.append(list_music.pop(0))
            elif way==4:    #Random play
                random.shuffle(list_music)
            else:
                assert False,"Error in playback mode"
            print("pop")
            if len(list_music):
                music.unload()
                music.load(list_music[0])
                music.play()
            else:
                print("The song list is empty")
    if flag_list_music:         #If you need to read in the song list
        now_word=0
        get_lrc_geci()          #Get lyrics
        list_music_change=copy.deepcopy(list_music)#Deep copy
        path=""
        for j in range(len(list_music_change)): #Get the song name
            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_click:
            #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()    #Create all_music class
    music.set_event(event=1)    #Set event
    show1=show2.show()        #Create GUI window
    show1.get_music(music=music,\
                    openfile=openfile,openpath=openpath,\
                    next_music=next_music,stop=stop)#Pass some functions to the show class
    event1=False
    show1.win.after(100,my_mainloop)    #Lead in the main loop
    show2.mainloop()    
    music.stop()        #Stop playing before closing GUI
if __name__ == '__main__':
    main()

  5, all_music.py

from pydub import AudioSegment
from pydub.playback import play
import multiprocessing
import time
import psutil
def terminate(process_pid):        #Terminating a process and its children
	process=psutil.Process(process_pid)
	p_child=process.children() # Child process list
	for p_c in p_child:
		p_c.kill()
	process.kill()
def suspend(process):            #Dormant process and its child processes
	p_child=process.children() # Child process list
	for p_c in p_child:
		p_c.suspend()
	process.suspend()
def resume(process):            #Let the process and its children recover
	p_child=process.children() # Child process list
	for p_c in p_child:
		p_c.resume()
	process.resume()
class all_music():        #all_music class
    def __init__(self):
        self.song_path=[]    #Song path
        self.song=[]        #Imported songs
        self.process1=[]    #Playback process
        self.suffix=[]        #Song type
        self.now_time=-1        #The length of time the song is currently playing
        self.start_time=-1      #The time when the timer starts counting
        self.excursion_time=0    #Offset time, which is used to obtain the real playback time during offset playback and pause
        self.length=-1        #Song length
        self.load_flag=0        #Loading status
        self.busy=0         #0: idle; 1: Playing; 2: Suspended; 3: Pause to resume playback
        self.event=0        #event
        self.speed=1        #speed
    def set_event(self,event):      #Set the event return value, return event when triggered, and return 0 when not triggered
        self.event=event
    def pop_event(self):            #View the current event status. After playing, return to the set event, otherwise return to 0
        try:
            result=self.q.get(block=False)
            self.busy=0
            return result
        except:
            return 0
    def pydub_play(self):           #Play music and trigger an event at the end
        play(self.song)
        self.q.put(self.event,block=True)
    def get_busy(self):             #Check to see if you are busy     
        return self.busy
    def get_length(self):           #Get song length
        return self.length
    def pos_set(self,time):         #Set song playback position
        if self.load_flag:
            self.stop()
            self.play(start=time)
        else:
            assert False,"No songs loaded"
    def get_play_time(self):        #Get the location where the current song is played
        if self.start_time!=-1:
            if self.busy==1:    #Judge whether it is in pause state
                #How many milliseconds did the current song play
                self.now_time=self.excursion_time+int((time.time()-self.start_time)*1000)
                #print("playing, time=%d"%self.now_time)
                return self.now_time
            else:
                #print("pause, time=%d"%self.now_time)
                return self.now_time
        else:
            #print("song not started")
            return -1
    def load(self,file_path):       #Get path
        if not self.load_flag:   #Determine whether a song has been loaded
            if file_path:   #Determine whether the path is empty
                self.song_path=file_path    #Give the song path to self
                for i in range(len(self.song_path)-1,-1,-1):    #Find file suffix
                    if self.song_path[i]==".":
                        break
                if self.song_path[i]==".":                      #Suffix songs to self
                    self.suffix=self.song_path[i+1:]
                    self.load_flag=1
                else:
                    assert False,"File suffix not found"
            else:
                assert False,"load(file_path)A song path is required"
        else:
            assert False,"A song has been loaded"
    def unload(self):           #Unload status
        if self.load_flag:   #Determine whether a song has been loaded
            self.load_flag=0
            self.song_path=[]
            self.suffix=[]
        else:
            assert False,"No songs loaded"
    def set_speed(self,speed):
        self.speed=speed
    def play(self,start=0):                 #Play songs
        #Judge whether the song is playing or paused
        if (self.busy==0 or self.busy==3)and self.load_flag: 
            if self.suffix:#Is there a subscript
                if self.suffix=="mp3":      #Import mp3 songs
                    self.song = AudioSegment.from_mp3(self.song_path) 
                elif self.suffix=="ogg":    #Import ogg songs
                    self.song = AudioSegment.from_ogg(self.song_path) 
                elif self.suffix=="flv":    #Import flv songs
                    self.song = AudioSegment.from_flv(self.song_path) 
                else:#Import songs in other supported formats
                    try:
                        self.song = AudioSegment.from_file(self.song_path,self.suffix)
                    except:
                        assert False,"Unsupported file or does not exist"
                if self.speed!=1:
                    self.song = self.song._spawn(self.song.raw_data, \
                                       overrides={"frame_rate": int(self.song.frame_rate * self.speed)})\
                                       .set_frame_rate(self.song.frame_rate)
                if start>len(self.song):
                    assert False,"The set time exceeds the duration of the song"
                self.excursion_time=start         #Set offset time to zero
                self.now_time=self.excursion_time#Set playback time to zero
                self.busy=1
                self.length=len(self.song)   #Set song duration
                if self.now_time:
                    self.song=self.song[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,"No songs loaded"
        else:
            assert False,"The song is not loaded or occupied, please first load or stop"
    def stop(self):     #End playback without unload
        if self.busy:   #Judge whether the song is playing or paused
            try:
                terminate(self.process1.pid)    #End song process
            except:
                pass
            #self.process1.join()
            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,"The song is not playing or paused"
    def pause(self):    #Pause playback
        if self.busy==1:   #Judge whether the song is playing
            self.get_play_time()        #Get current time
            p=psutil.Process(self.process1.pid)
            suspend(p)
            #self.process1.terminate()    #End song process
            self.busy=2
        else:
            assert False,"No songs are playing"
    def unpause(self):  #Resume paused playback
        if self.busy==2:   #Judge whether the song is playing
            self.busy=3
            p=psutil.Process(self.process1.pid)
            resume(p)
            self.excursion_time=self.now_time   #Set offset time to zero
            self.start_time=time.time()
            self.busy=1
            #self.play(start=self.now_time)
        else:
            assert False,"The song is not paused"
'''
if __name__ == '__main__':
    music=all_music()
    music.load("Days after the next stop - Twins.mp3")
'''

6, show2.py

from tkinter import *
from PIL import Image, ImageTk
import tkinter.font as tkFont
from tkinter import ttk
def color(color_255):            #Convert RGB to hexadecimal and output in string format
    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=[]
class show():        #show class
    def __init__(self): 
        #main window
        self.mouse_left_click=0#Left click status
        self.set_time=0
        self.flag_replay=0
        self.win = Tk()
        self.win.title(u"My music")
        self.win.iconphoto(True, PhotoImage(file='/home/xiaobai/Desktop/my_music/My_Music_tk.png'))
        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)
        #Music list 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)
        #Button 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)
        
        #Lyrics 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)
        #Button
        ft = tkFont.Font(family=u"Song typeface", size=15, weight=tkFont.BOLD)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"suspend",command =self.pause)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"play",command =self.play)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"Replay",command =self.replay)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([135,206,250])\
                ,activebackground="white",\
                text=u"Next song",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"clear list ",command =self.stop)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([242,203,46])\
                ,activebackground="white",\
                text=u"Open path",command =self.openpath)\
                .pack (side=LEFT, padx=13, pady=13)
        Button (self.frame1,font=ft,bg=color([242,169,0])\
                ,activebackground="white",\
                text=u"Open file",command =self.openfile)\
                .pack (side=LEFT, padx=13, pady=13)
        
        #Some text display
        #Show playlist text
        ft = tkFont.Font(family=u"Song 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"Broadcast",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"discharge",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"column",bg=color([135,206,250])).pack(anchor='w')
        Label(self.frame221,font=ft,\
              text=u"surface",bg=color([135,206,250])).pack(anchor='w')
        #Display "double speed" text
        ft = tkFont.Font(family=u"Song 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"   Double speed",bg=color([135,206,250]))
        Label_b.pack(side=LEFT)
        #Multiple speed setting
        self.set_comvalue=StringVar()#Form's own text, create a new value
        self.set_templist=ttk.Combobox(self.frame222,font=ft,\
                                       textvariable=self.set_comvalue,\
                                       state='readonly',\
                                       width=3) #initialization    
        self.set_templist["values"]=("0.8","0.9","1","1.2","1.4")#Playback speed can be set by yourself
        self.set_templist.current(2) #Select first
        self.set_templist['state'] = 'readonly'#read-only
        self.set_templist.bind("<<ComboboxSelected>>",self.music_speed) #Bind event, (when the drop-down list box is selected, bind go() function)
        self.set_templist.pack(side=LEFT)
        #list
        #Music List
        ft = tkFont.Font(family=u"Song typeface", size=15, weight=tkFont.BOLD)
        self.list_music1=Listbox(self.frame22,bg=color([255,255,255]),\
                            cursor='plus',font=ft,\
                            fg=color([0,0,0]),height=5,width=40)
        self.list_music1.pack(side=LEFT, padx=13, pady=13)
        WAY_SET = [("Single tune circulation", 1),("List play", 2),("List loop", 3),("Random play", 4)]
        self.play_way = IntVar()
        self.play_way.set(2)
        for way, num in WAY_SET:
            Radiobutton(self.frame22, 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")
        #current time 
        self.now_time_text = StringVar()
        self.now_time_text.set("0"+":"+"00")
        ft = tkFont.Font(family=u"Microsoft YaHei ", 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)
        #Song progress
        self.music_time_scale_length=600
        ft = tkFont.Font(family=u"Song 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)
        #Total time
        self.length_text = StringVar()
        self.length_text.set("0"+":"+"00")
        ft = tkFont.Font(family=u"Microsoft YaHei ", 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)
        #lyric
        self.lrc_word_length=40
        ft = tkFont.Font(family=u"Song typeface", 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)
        
    def music_speed(self,*args):        #Set playback speed
        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.play(start=self.set_time)
        self.music_time_scale.pack_forget()     #Time progress bar redrawing
        ft = tkFont.Font(family=u"Song 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()       #force refresh 
    def set_length_and_now_time(self,now_time,music_length=None):#Get song length
        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):#Get the left mouse button click event on the progress bar
        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()       #force refresh 
            self.music.stop()
            self.music.play(start=self.set_time)
            self.mouse_left_click=2
            print("mouse_set_time")
        else:
            self.mouse_left_click=1
            print("slide_scale")
        #print(f "click once with the left mouse button, and the coordinates are: x={event.x},y={event.y}")
    def mouse_left_release_fun(self,event):#Gets the left mouse button release event on the progress bar
        if self.mouse_left_click==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()       #force refresh 
            self.music.stop()
            self.music.play(start=self.set_time)
            print("slide_scale_set_time")
        self.mouse_left_click=0
        #print(f "the left mouse button release coordinates are: x={event.x},y={event.y}")
    def get_music(self,music,openfile,openpath,next_music,stop):#Get various functions
        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):#Get music list
        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=u"Song 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):#Get lyrics
        self.lrc_word.delete(0,"end")
        length=0
        if len(lrc_word)==1:
            for ch in lrc_word[0]:
                if u'\u4e00'<=ch<=u'\u9fff':
                    length=length+2
                else:
                    length=length+1
        else:
            for i in range(len(lrc_word)):
                if i:
                    for ch in lrc_word[i]:
                        if u'\u4e00'<=ch<=u'\u9fff':
                            length=length+2
                        else:
                            length=length+1
                else:
                    length=len(lrc_word[i])+length
        if length>60:
            length=60
        if self.lrc_word_length>length*1.1 or self.lrc_word_length<length:
            self.lrc_word.pack_forget()
            self.lrc_word_length=int(length)
            ft = tkFont.Font(family=u"Song typeface", 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) 
        for i in range(len(lrc_word)):
            if i:
                self.lrc_word.insert("end", " "*len(lrc_word[0])+lrc_word[i])
            else:
                self.lrc_word.insert("end", lrc_word[i])
    def pause(self):        #suspend
        self.music.pause()
        print("pause")
    def stop(self):        #Stop and empty the list
        self.set_time=0
        stop1()
        print("stop")
    def play(self):        #play
        self.music.unpause()
        print("play")
    def replay(self):        #Replay
        self.set_time=0
        self.music_time_scale.set(0)
        self.music.stop()
        self.music.play()
        print("replay")
    def openfile(self):        #Open file
        self.set_time=0
        openfiles()
        print("openfile")
    def set_times(self):    #Set the playback time, which is now deprecated and integrated into the mouse event function
        time=self.music_time_scale.get()
        print(time)
        self.set_time=time
        self.music.stop()
        self.music.play(start=time)
        print("set_time")
    def openpath(self):    #Open path
        self.set_time=0
        openpaths()
        print("openpath")
    def next_music(self):    #Next song
        self.set_time=0
        next_musics()
        print("next_music")
#show1=show()
#mainloop()

Let's go here first. Write what you think. If you have any questions, please leave a message.

Tags: Python Linux Ubuntu

Posted on Sat, 23 Oct 2021 01:43:56 -0400 by Atari