Python3——MP3播放器

Posted 嘆世殘者——華帥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3——MP3播放器相关的知识,希望对你有一定的参考价值。

sql

# 创建数据库
CREATE DATABASE `music_player` CHARACTER SET utf8;
# 创建MP3音乐文件的表
CREATE TABLE  mp3_file_list(
  id int PRIMARY KEY ,
  mp3_name VARCHAR(200) NOT NULL UNIQUE,
  mp3_file VARCHAR(200) NOT NULL
);
# 用户信息表
CREATE TABLE mp3_user(
  id INT PRIMARY KEY ,
  username VARCHAR(200) NOT NULL ,
  password VARCHAR(200) NOT NULL
);
# 用户的播放列表
CREATE TABLE mp3_player_list(
  id INT PRIMARY KEY ,
  uid INT,
  mid INT,
  CONSTRAINT f_mp3_user_id FOREIGN KEY (uid) REFERENCES mp3_user (id),
  CONSTRAINT f_mp3_file_list_id FOREIGN KEY (mid) REFERENCES mp3_file_list(id)
);

 

mysql_util.py

# coding=utf-8
# Version:python3.6.1
__date__ = 2019/1/9 14:38
__author__ = Lgsp_Harold

import pymysql

class MysqlHelper(object):
    config = {
        "host":"192.168.234.44", "user": "root",
        "password": "admin",
        "db": "music_player",
        "charset": "utf8"
    }

    def __init__(self):
        self.connection = None
        self.cursor = None

    # 从数据库表中查询一行数据
    def getOne(self, sql, *args):
        try:
            self.connection = pymysql.connect(**MysqlHelper.config)
            self.cursor = self.connection.cursor()
            self.cursor.execute(sql, args)
            return self.cursor.fetchone()
        except Exception as ex:
            print(ex, ex)
        finally:
            self.close()

    # 从数据库表中查询多行数据
    def getList(self, sql, *args):
        try:
            self.connection = pymysql.connect(**MysqlHelper.config)
            self.cursor = self.connection.cursor()
            self.cursor.execute(sql, args)
            return self.cursor.fetchall()
        except Exception as ex:
            print(ex, ex)
        finally:
            self.close()

    # 对数据库进行增,删,改
    def executeDML(self, sql, *args):
        try:
            self.connection = pymysql.connect(**MysqlHelper.config)
            self.cursor = self.connection.cursor()
            num = self.cursor.execute(sql, args)  # sql语句执行之后影响的行数
            new_id = self.connection.insert_id() # 返回系统刚刚自动生成的id
            self.connection.commit()
            return new_id
        except Exception as ex:
            self.connection.rollback()
            print(ex, ex)
        finally:
            self.close()

    def close(self):
        if (self.cursor):
            self.cursor.close()
        if (self.connection):
            self.connection.close()

 

playservice.py

# coding=utf-8
# Version:python3.6.1
__date__ = 2019/1/9 14:31
__author__ = Lgsp_Harold

import pygame
from mysql_util import MysqlHelper

class Service(object):
    def __init__(self):
        self.helper = MysqlHelper()
        pygame.mixer.init()

    #登陆的业务 username 由用户输入。如果数据库表中存在一条用户数据,那么登陆成功。并且用户数据保存到属性中去。
    def login(self,username,password):
        user = self.helper.getOne("select id,username,password from mp3_user WHERE username=%s and password=%s",username,password)
        if user:
            print("%s登陆成功"%user[1])
            self.username = user[1]
            self.uid = user[0]
            return True
        else:
            print("你输入的用户名和密码有误")
            return False

    # 把mp3文件插入到表mp3中。注意:为了保证mp3的唯一性。需要在插入新mp3之前先查询一下,是否已经存在。如果存在就不用插入
    def load_mp3(self, files):  # files 是用户选中的音乐文件列表
        if files:
            for f in files:
                end = f.find(".mp3")
                start = f.rfind("/")
                mp3_name = f[start+1:end]   # 通过字符串截取获得歌曲的名字
                # print(mp3_name)
                # print(f)

                #为了保证mp3的唯一性。首先根据歌曲的名字去表中查询。
                mp3_id = self.helper.getOne("select id from mp3_file_list WHERE mp3_name=%s",mp3_name)
                if mp3_id and mp3_id[0] != 0:   # 如果数据库表中已经存在了,则不要插入;否则插入数据
                    print("%s已经在数据库中存在",mp3_name)
                    mp3_id = mp3_id[0]
                else:
                    # 如果不存在,需要插入。并且返回插入之后,数据库系统自动生成的ID
                    mp3_id = self.helper.executeDML("insert into mp3_file_list (mp3_name,mp3_file) VALUE (%s,%s)", mp3_name, f)
                # 最后一步往用户的播放列表中插入对应的指。
                self.helper.executeDML("insert into mp3_player_list (mid,uid) VALUE (%s,%s)",mp3_id,self.uid)
        else:
            print("用户没有选择文件")

    # 根据用户登陆之后的ID,从数据库中查到该用户播放列表
    def find_play_list_by_user(self):
        sql = "select t_m2.mp3_name from mp3_player_list as t_m1 join mp3_file_list as t_m2 on t_m1.mid = t_m2.id where t_m1.uid = %s"
        return self.helper.getList(sql,self.uid)

    # 播放MP3
    def play_mp3(self,mp3_name):
        file_path = self.helper.getOne("select mp3_file from mp3_file_list WHERE mp3_name=%s",mp3_name)
        if file_path and file_path[0]: # 数据库中找到了该mp3的路径
            pygame.mixer.music.load(r%s%file_path[0])
            pygame.mixer.music.play()
            pygame.mixer.music.set_volume(0.1)
            # print(pygame.mixer.music.get_volume())

    # 删除MP3
    def delete_play_list(self,mp3_name):
        mp3_id = self.helper.getOne("select id from mp3_file_list WHERE mp3_name=%s",mp3_name)
        if mp3_id:
            # mid = mp3_id[0]
            self.helper.executeDML("delete from mp3_player_list WHERE mid=%s and uid=%s",mp3_id[0],self.uid)

    # 暂停
    def pause_mp3(self):
        pygame.mixer.music.pause()
    # 继续播放
    def unpause_mp3(self):
        pygame.mixer.music.unpause()

    # 停止
    def stop_mp3(self):
        pygame.mixer.music.stop()

    # 设置音量
    def setVolume(self):
        getVolume = pygame.mixer.music.get_volume()
        # print(getVolume)
        pygame.mixer.music.set_volume(getVolume + 0.01)
        # print(pygame.mixer.music.get_volume())

 

music.py

#coding:utf-8
from tkinter import *
import tkinter.messagebox
from tkinter.filedialog import askopenfilenames
import pygame
from playservice import Service

#<Button-1>:鼠标左击事件
#<Button-2>:鼠标中击事件
#<Button-3>:鼠标右击事件
#<ButtonRelease-x>:鼠标释放事件,x=[1,2,3],分别表示鼠标的左中右键操作
#<Double-Button-1>:双击事件

class MainWindow:
    def play(self,event):
        # tkinter.messagebox.showinfo("messagebox","this is button 1 dialog")
        # filepath = askopenfilename(filetypes=(("MP3 file","*.mp3"),))
        # print(filepath)
        # track = pygame.mixer.music.load(r‘D:/ProgramFiles/Development/PycharmProjects/music_player/music.mp3‘)
        # print(track,type(track))
        # pygame.mixer.music.play()
        num = self.tl.curselection()  # 获取用户所选的MP3的下标
        mp3_name = self.tl.get(num)  # 根据下标返回mp3的名字
        self.service.play_mp3(mp3_name)



    def delete_mp3(self,event):
        num = self.tl.curselection()  # 获取用户所选的MP3的下标
        mp3_name = self.tl.get(num)  # 根据下标返回mp3的名字
        self.service.delete_play_list(mp3_name)
        list = self.service.find_play_list_by_user()
        # print(list)
        self.tl.delete(0, END)
        for i in list:
            self.tl.insert(END, i[0])

    def pause_mp3(self,event):
        self.service.pause_mp3()

    def unpause_mp3(self,event):
        self.service.unpause_mp3()

    def stop_mp3(self,event):
        self.service.stop_mp3()

    def setVolume(self,event):
        self.service.setVolume()

    # 当用户在导入歌曲的按钮上点击调用的函数
    def loadMp3(self,event):
        # tkinter.messagebox.showinfo("messagebox","this is button 4 dialog")
        files = askopenfilenames(filetypes=(("Mp3 file","*.mp3*"),))
        self.service.load_mp3(files)
        list = self.service.find_play_list_by_user()
        # print(list)
        self.tl.delete(0,END)
        for i in list:
            self.tl.insert(END,i[0])

    def select_text(self, event):
        # tkinter.messagebox.showinfo("messagebox", "this is")
        # item = self.tl.curselection()
        # print(self.tl.get(item))
        pass

    def __init__(self):
        self.service=service
        self.frame = Tk()
        self.frame.title("Leslie的播放器")
        self.button1 = Button(self.frame, text="播放")
        self.button2 = Button(self.frame, text="暂停")
        self.button7 = Button(self.frame, text="继续")
        self.button3 = Button(self.frame, text="停止")
        self.button4 = Button(self.frame, text="导入歌曲")
        self.button5 = Button(self.frame, text="删除歌曲")
        self.button6 = Button(self.frame, text="增加音量")

        self.tl = Listbox(self.frame,{"selectmode":SINGLE}) # 播放列表
        self.button1.grid(row=0, column=0, padx=5, pady=5)
        self.button2.grid(row=0, column=1, padx=5, pady=5)
        self.button3.grid(row=0, column=2, padx=5, pady=5)
        self.button7.grid(row=0, column=6, padx=5, pady=5)
        self.button4.grid(row=0, column=3, padx=5, pady=5)
        self.button5.grid(row=0, column=4, padx=5, pady=5)
        self.button6.grid(row=0, column=5, padx=5, pady=5)
        self.tl.grid(row=1, column=0, padx=5, pady=5, columnspan=6)

        # 返回该登陆用户的播放列表
        list = self.service.find_play_list_by_user()
        self.tl.delete(0, END)
        for i in list:
            self.tl.insert(END, i[0])

        # 给list_box绑定鼠标事件
        self.tl.bind("<ButtonRelease-1>",self.select_text)
        self.button1.bind("<ButtonRelease-1>", self.play)
        self.button5.bind("<ButtonRelease-1>", self.delete_mp3)
        self.button2.bind("<ButtonRelease-1>", self.pause_mp3)
        self.button7.bind("<ButtonRelease-1>", self.unpause_mp3)
        self.button4.bind("<ButtonRelease-1>", self.loadMp3)
        self.button3.bind("<ButtonRelease-1>", self.stop_mp3)
        self.button6.bind("<ButtonRelease-1>", self.setVolume)


        self.frame.mainloop()



if __name__=="__main__":
    username = input("请输入登陆的账号:")
    password = input("请输入登陆的密码:")
    service = Service()
    if service.login(username,password):
        pygame.mixer.init()
        window = MainWindow()

 

以上是关于Python3——MP3播放器的主要内容,如果未能解决你的问题,请参考以下文章

python3.x Mp3 播放器与 PyQt5

如果它尝试播放 mp3 文件,我的代码会崩溃,适用于 wav 文件

解决PyQt5 QMediaPlayer播放mp3后占用的问题

Python 用pygame模块播放MP3

当我点击播放按钮更多然后在我的MP3播放器中我的应用程序崩溃

获取 mp3 文件指定时间范围的字节范围位置