音乐播放器

目录

  • 一、设计目标
  • 二、实现流程
    • 1. 数据库操作
    • 2. 后端功能实现
    • 3. 前端UI界面实现
    • 4. 程序入口
  • 三、项目收获

一、设计目标

1. 模拟网易云音乐,实现本地音乐盒
2. 功能分析

  • 登录功能
  • 窗口显示
  • 加载本地音乐
  • 建立播放列表
  • 播放音乐
  • 删除播放列表音乐
    3.设计思路
  • 前端UI页面:播放按钮、导入音乐按钮、删除按钮、音乐播放列表
  • 后端服务端:登录功能、导入音乐的功能、播放音乐的功能、删除音乐的功能
  • 为了将前端页面和后端服务更好的结合,在实际实现中,根据设计程序的目标加入一些属性或方法,来帮助程序功能更好的实现。
    例如:前端音乐列表的加载,需要在后端服务程序中添加一个从数据库中查找当前用户音乐列表的方法,然后由前端UI界面调用把查找到的音乐加入音乐列表中。
    4.数据库组件
  • 为了实现功能,需要在数据库中设计的三张表
  • 用户表:存储用户信息,用来实现登录功能
  • 音乐表:存储音乐信息(名称、歌手、资源路径),存储所有导入的音乐,用来实现寻找音乐资源进行加载、播放和删除的功能。
  • 用户播放列表:存储用户id及其对应的音乐id,且这两个值分别有另外两张表的外键约束,用来正确的显示用户对应的歌曲。

二、实现流程

1. 数据库操作

  1. 创建数据库
# 创建音乐盒数据库
CREATE DATABASE music_db
    DEFAULT CHARACTER SET = 'utf8mb4';
  1. 使用数据库
USE music_db;
  1. 创建用户表
CREATE TABLE t_user(
    id int(11) PRIMARY KEY AUTO_INCREMENT, 
    username VARCHAR(32),
    password VARCHAR(32)
);
  1. 创建音乐表
CREATE TABLE t_music(
    id int(11) PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(32),
    singer VARCHAR(32),
    path VARCHAR(256)
);
  1. 创建用户播放列表
CREATE Table t_play_list(
    id int(11) PRIMARY KEY AUTO_INCREMENT,
    u_id int(11),
    m_id int(11),
    FOREIGN KEY(u_id) REFERENCES t_user(id),
    FOREIGN KEY(m_id) REFERENCES t_music(id)
);
  1. 插入用户数据
insert into t_user(username, password) values('张三','123456');

2. 后端功能实现

1.登录功能

# 导包
from tools import DBUtil # 导入工具类:进行数据库上的操作
import pygame # 用来播放音乐

class MusicService:
    def __init__(self) -> None:
        self.user = None
    def login(self,uname,pwd) -> bool:
        '''
        用户登录功能
        :param uname: 用户名
        :param pwd: 密码
        '''
        # 编写sql
        sql = "select id,username from t_user where username=%s and password=%s"
        # 创建工具类对象
        db = DBUtil()
        # 执行查询操作
        res = db.query_one(sql,uname,pwd)
        # 判断是否登录成功
        if res:
            # print("赋值 self.user", self.user)  # 这里应该看到 self.user 被正确赋值
            self.user = res 
            print("登录成功,欢迎使用")
            # print(self.user[0])
            return True
        else:
            print("登录失败")
            return False

2.导入音乐

    def insert_music(self,files:tuple[str]) -> None:
        '''
        将导入的音乐添加到数据库
        '''
        # 编写sql
        insert_sql = "insert into t_music(title,path) values(%s,%s)"
        # 遍历音乐文件
        for file in files:
            # print(file)
            name = file[file.rfind(" ")+1:file.rfind(".")]
            # 创建工具类对象
            db = DBUtil()
            # 执行sql
            mid = db.execute_dml_back_id(insert_sql,name,file)
            # 维护用户和音乐的对应关系
            # 创建工具类对象
            db = DBUtil()
            # 编写sql
            insert_play_list_sql = "insert into t_play_list(u_id,m_id) values(%s,%s)"
            # 执行sql
            db.execute_dml(insert_play_list_sql,self.user[0],mid)

3.查询用户音乐列表

    def find_user_music(self) -> list[str]:
        '''
        查询用户音乐列表
        :return: 音乐列表
        '''
        # 编写sql
        sql = "SELECT m.title from t_play_list p left join t_music m on p.m_id = m.id WHERE u_id = %s;"
        # 创建工具类对象
        db = DBUtil()
        # 执行sql
        m_list = db.query_all(sql,self.user[0])
        return m_list

4.播放音乐

    def play_music(self,music_name:str) -> None:
        '''
        播放音乐
        :param m_name: 音乐名
        '''
        # 编写sql:根据传入的音乐名查找对应的音乐路径
        sql = "SELECT m.path FROM t_play_list p left join t_music m on p.m_id = m.id WHERE u_id = %s and m.title = %s;"
        # 执行sql:获取音乐路径
        path = DBUtil().query_one(sql,self.user[0],music_name)[0]
        # 初始化混合器
        pygame.mixer.init()
        # 加载音乐
        pygame.mixer.music.load(path)
        # 播放音乐
        pygame.mixer.music.play()

5.删除音乐

    def delete_music(self,music_name:str) -> None:
        '''
        删除音乐
        :param: music_name: 音乐名
        '''
        # 编写sql:根据传入的音乐名查找要删除的音乐id
        get_id_sql = "SELECT m.id from t_music m LEFT JOIN t_play_list p on m.id = p.m_id WHERE m.title = %s and p.u_id = %s;"
        # 执行sql:获取音乐id
        music_id = DBUtil().query_one(get_id_sql,music_name,self.user[0])[0]
        # 编写sql,并删除播放列表中对应的音乐
        delete_play_list_sql = "DELETE FROM t_play_list WHERE u_id = %s and m_id = %s;"
        DBUtil().execute_dml(delete_play_list_sql,self.user[0],music_id)
        # 编写sql,并删除音乐表中对应的音乐
        delete_music_sql = "DELETE FROM t_music WHERE id = %s;"
        DBUtil().execute_dml(delete_music_sql,music_id)

3. 前端UI界面实现

1.初始化软件窗口

# 导包
import tkinter # 引入tkinter,绘画界面
from service import MusicService # 引入服务层
from tkinter.filedialog import askopenfilenames # 引入文件选择框

class PlayWindow:
    '''
    软件窗口
    '''
    def __init__(self) -> None:
        top = tkinter.Tk()
        # 创建按钮
        btn1 = tkinter.Button(top,text='播放')
        btn2 = tkinter.Button(top,text='导入音乐')
        btn3 = tkinter.Button(top,text='删除')
        # 创建播放列表
        self.listbox = tkinter.Listbox(top)
        # 设置按钮的位置
        btn1.grid(row=0,column=0,padx=5,pady=5)
        btn2.grid(row=0,column=2,padx=5,pady=5)
        btn3.grid(row=0,column=4,padx=5,pady=5)
        # 设置播放列表的位置
        self.listbox.grid(row=1,column=0,columnspan=5,padx=5,pady=5)
        # 获取用户音乐播放列表
        self.load_music()
        # 绑定按钮事件
        btn2.bind('<ButtonRelease-1>',self.import_music)
        btn1.bind('<ButtonRelease-1>',self.play_music)
        btn3.bind('<ButtonRelease-1>',self.delete_music)
        # 进入消息循环
        top.mainloop()

2.导入音乐按钮事件绑定的方法

    def import_music(self,event):
        '''
        导入音乐
        '''
        print('导入音乐')
        # 弹出文件选择框
        filenames = askopenfilenames(filetypes=[('mp3','*.mp3'),('flac','*.flac')])
        print(filenames)
        # 调用服务层
        # ms = MusicService()
        # 把导入的音乐插入到数据库中
        ms.insert_music(filenames)
        # 导入新音乐后刷新播放列表
        self.load_music()

3.加载用户音乐播放列表的方法

    def load_music(self):
        '''
        加载用户音乐列表
        '''
        # 查询当前用户播放列表
        music_list = ms.find_user_music()
        # 清空播放列表
        self.listbox.delete(0,tkinter.END)
        # 遍历列表,把音乐名添加到播放列表中
        for music in music_list:
            self.listbox.insert(0,music[0])

4.播放音乐按钮绑定的方法

    def play_music(self,event):
        '''
        播放音乐
        '''
        # 获取当前选中的音乐索引
        index = self.listbox.curselection()
        # 获取当前选中的音乐名
        music_name = self.listbox.get(index)
        # print(music_name)
        # 播放音乐
        ms.play_music(music_name)

5.删除音乐按钮绑定的方法

    def delete_music(self,event):
        '''
        删除音乐
        '''
        # 获取当前选中的音乐索引
        index = self.listbox.curselection()
        # 根据音乐索引获取音乐名
        music_name = self.listbox.get(index)
        # 调用后台服务的删除功能
        ms.delete_music(music_name)
        # 刷新播放列表
        self.load_music()

4. 程序入口

if __name__ == "__main__":
    # 输入登录信息
    uname = input('请输入用户名:')
    pwd = input('请输入密码:')
    # 创建服务对象
    ms = MusicService()
    if ms.login(uname,pwd):
        # 创建播放窗口
        pw = PlayWindow()

三、项目收获

  1. 一种软件设计思维:先明确要设计的软件——>分析软件各个功能并分成模块——>前端页面绘画——>根据前端页面设计与其页面相绑定的后端方法——>后端方法要与数据库交互
  2. 一个技巧:在编写不确定的代码的时候,可以使用调试模式,使用调试控制台输入代码快速获得相应的变量输出,从而快速确定要编写的代码。这样可以有效的避免多次运行才能获得正确代码的情况,这在大型软件的设计中很有用!!!
  3. 对软件设计的认知:设计和编写前端页面、根据前端页面实现功能;其中有一个重点:后端服务层的功能重点是与数据库的交互,根据数据库返回的数据进行条件判断,提取数据库的数据进行信息呈现和功能实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/775815.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

桌面保存的Word文件删除怎么找回?超实用的三个方法?

在日常工作和学习中&#xff0c;我们经常会使用Word文档进行文字编辑和文件保存。但是&#xff0c;有时由于操作失误或系统故障&#xff0c;我们会不小心将存放在电脑桌面重要的Word文件删除了。导致无法挽回的损失&#xff0c;但幸运的是&#xff0c;有一些方法可以帮助我们找…

基于SpringBoot的乐校园二手书交易管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言 Java 数据库 MySQL 技术 SpringBoot框架 工具 Visual Studio、MySQL数据库开发工具 系统展示 首页 用户注册界面 二手图书界面 个人中心界面 摘要 乐校园…

新港海岸NCS8822 低功耗DP转VGA 分辨率支持1920*1200*60HZ

NCS8822描述&#xff1a; NCS8822是一个低功耗显示端口到vga转换器。NCS8822集成了一个与DP1.2兼容的接收器和一个高速三通道视频DAC。对于DP1.2输入&#xff0c;NCS8822支持1车道/2车道&#xff0c;也支持车道交换功能。对于VGA输出NCS8822&#xff0c;在60Hz帧率下对WUXGA&a…

【HICE】搭建不同的主机名访问web服务

1.首先进入1.conf.d编辑内容&#xff0c;再重启服务&#xff0c;关闭防火墙 2.部署网页haha.html和xixi.html 3.在vim /etc/hosts增加域名 3.在window中进行本地解析的编辑 4.浏览器的验证

自闭症孩子的语言之旅:最晚几岁会说话的探索与思考

作为在自闭症学校工作的教育者&#xff0c;我深知自闭症这一神经发展性障碍给孩子们带来的挑战&#xff0c;尤其是他们在语言发展方面的困难。自闭症孩子的语言发展轨迹各不相同&#xff0c;有的孩子可能早早地展现出语言天赋&#xff0c;而有的孩子则可能迟迟不开口。那么&…

AI文字图片人脸生成原创视频文生图生肖生小程序开发

AI文字图片人脸生成原创视频文生图生肖生小程序开发 无限开 0.12生成 图生视频 AI技术在生成文字、图片、人脸以及视频方面已经取得了显著的进步。以下是一些可能包含在AI文字图片人脸生成原创视频小程序中的功能列表&#xff1a; 文字转视频&#xff1a; 输入文字或文章&…

如何选择TikTok菲律宾直播网络?

为了满足用户对于实时互动的需求&#xff0c;TikTok推出了直播功能&#xff0c;让用户能够与粉丝即时交流。本文将探讨如何选择适合的TikTok菲律宾直播网络&#xff0c;并分析OgLive是否是值得信赖的选择。 TikTok菲律宾直播网络面临的挑战 作为全球领先的短视频平台&#xff…

数据分析和人工智能平台帮助企业创造更好、更安全、更可持续的产品

——Sam Mahalingam | Altair 首席技术官 | 2024.6.24 Altair的数据分析和人工智能&#xff08;AI&#xff09;平台AltairRapidMiner最近被Gartner 魔力象限™评为数据科学和机器学习平台领导者。有些人可能不太熟悉&#xff0c;实际上Gartner 魔力象限™ 报告是严格的、基于事…

【扩散模型(三)】IP-Adapter 源码详解1-输入篇

系列文章目录 【扩散模型&#xff08;一&#xff09;】中介绍了 Stable Diffusion 可以被理解为重建分支&#xff08;reconstruction branch&#xff09;和条件分支&#xff08;condition branch&#xff09;【扩散模型&#xff08;二&#xff09;】IP-Adapter 从条件分支的视…

生产力工具|viso常用常见科学素材包

一、科学插图素材网站 一图胜千言&#xff0c;想要使自己的论文或重要汇报更加引人入胜&#xff1f;不妨考虑利用各类示意图和科学插图来辅助研究工作。特别是对于新手或者繁忙的科研人员而言&#xff0c;利用免费的在线科学插图素材库&#xff0c;能够极大地节省时间和精力。 …

20.5.【C语言】求长度的两种方式

1.sizeof 用于测数据类型的长度的函数&#xff08;详细见第3篇&#xff09; 2.strlen 其计算长度时只有遇到\0才会停止&#xff0c;并且\0不会计算在内 如char arr[]{a,1,b}; printf("%d\n",strlen(arr)); 结果是个随机数&#xff01;strlen读内存中的数据&…

3D生成模型TripoSR完美搭建流程,包含所有问题解决方案!

最近需要使用3D生成模型,无意中看到了TripoSR,觉得效果还行,于是打算在Linux系统上部署一下,结果遇到很多坑,在这里写一下详细的部署流程和部署过程中遇到的问题。 下面是TripoSR的源码地址。 GitHub - VAST-AI-Research/TripoSRContribute to VAST-AI-Research/TripoSR…

已经安装deveco-studio-4.1.3.500的基础上安装deveco-studio-3.1.0.501

目录标题 1、执行exe文件后安装即可2、双击devecostudio64_3.1.0.501.exe2.1、安装Note (注意和4.1的Note放不同目录)2.2、安装ohpm (注意和4.1版本的ohpm放不同目录)2.3、安装SDK (注意和4.1版本的SDK放不同目录) 1、执行exe文件后安装即可 2、双击devecostudio64_3.1.0.501.e…

linux主机(A)通过私钥登录linux主机(B)

1.登录B主机&#xff0c;先在B主机执行 ssh-keygen 2.设置id_rsa的权限 chmod 600 id_rsa 3.将生成的id_rsa.pub导入到authorized_keys ssh-copy-id -i ./id_rsa.pub root127.0.0.1 4.将id_rsa复制到A主机 scp id_rsa_123 root1.1.1.A:/home/ 5.登录到A主机使用私钥登录 因…

C++左值/右值/左值引用/右值引用

1&#xff09;C入门级小知识&#xff0c;分享给将要学习或者正在学习C开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 左值和右值的概念&#xff1a; 早期的c语言中关于左值和右值的定义&a…

使用中国大陆镜像源安装最新版的 docker Deamon

在一个智算项目交付过程中&#xff0c;出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷&#xff0c;需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…

强化学习后的数学原理:随机近似与梯度下降

概述 这节课的作用&#xff1a; 本节课大纲如下&#xff1a; Motivating examples 先回顾一下 mean estimation &#xff1a; 为什么总数反复提到这个 mean estimation&#xff0c;就是因为 RL 当中有非常多的 expectation&#xff0c;后面就会知道除了 state value 这些定义…

传统视觉Transformer的替代者:交叉注意力Transformer(CAT)

传统视觉Transformer的替代者&#xff1a;交叉注意力Transformer&#xff08;CAT&#xff09; 在深度学习的世界里&#xff0c;Transformer架构以其在自然语言处理&#xff08;NLP&#xff09;领域的卓越表现而闻名。然而&#xff0c;当它进入计算机视觉&#xff08;CV&#x…

Hilbert编码 思路和scala 代码

需求&#xff1a; 使用Hilbert 曲线对遥感影像瓦片数据进行编码&#xff0c;获取某个区域的编码值即可 Hilbert 曲线编码方式 思路 大致可以对四个方向的数据进行归类 左下左上右上右下 这个也对应着编码的顺序 思考在不同Hilbert深度&#xff08;阶&#xff09;情况下的…

AutoX.js某音自动评论(一个函数,5秒完成)

背景 某音自动化评论&#xff0c;步骤简单&#xff0c;对版本兼容性要高&#xff08;不用节点id定位&#xff09; 思路 通过Intent直接跳转到视频*利用文字&#xff0c;描述&#xff08;正则&#xff09;等匹配输入框&#xff0c;发表评论 效果 某音自动化评论 已经封装成一…