当前位置: 首页 > news >正文

音乐播放器

目录

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

一、设计目标

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

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

二、实现流程

1. 数据库操作

  1. 创建数据库
# 创建音乐盒数据库
CREATE DATABASE music_dbDEFAULT 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 = Nonedef login(self,uname,pwd) -> bool:'''用户登录功能:param uname: 用户名:param pwd: 密码'''# 编写sqlsql = "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 Trueelse:print("登录失败")return False

2.导入音乐

    def insert_music(self,files:tuple[str]) -> None:'''将导入的音乐添加到数据库'''# 编写sqlinsert_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()# 执行sqlmid = db.execute_dml_back_id(insert_sql,name,file)# 维护用户和音乐的对应关系# 创建工具类对象db = DBUtil()# 编写sqlinsert_play_list_sql = "insert into t_play_list(u_id,m_id) values(%s,%s)"# 执行sqldb.execute_dml(insert_play_list_sql,self.user[0],mid)

3.查询用户音乐列表

    def find_user_music(self) -> list[str]:'''查询用户音乐列表:return: 音乐列表'''# 编写sqlsql = "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()# 执行sqlm_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:根据传入的音乐名查找要删除的音乐idget_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:获取音乐idmusic_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. 对软件设计的认知:设计和编写前端页面、根据前端页面实现功能;其中有一个重点:后端服务层的功能重点是与数据库的交互,根据数据库返回的数据进行条件判断,提取数据库的数据进行信息呈现和功能实现。

相关文章:

音乐播放器

目录 一、设计目标二、实现流程1. 数据库操作2. 后端功能实现3. 前端UI界面实现4. 程序入口 三、项目收获 一、设计目标 1. 模拟网易云音乐&#xff0c;实现本地音乐盒。 2. 功能分析&#xff1a; 登录功能窗口显示加载本地音乐建立播放列表播放音乐删除播放列表音乐 3.设计思…...

三星组件新的HBM开发团队加速HBM研发

为应对人工智能(AI)市场扩张带来的对高性能存储解决方案需求的增长&#xff0c;三星电子在其设备解决方案(DS)部门内部成立了全新的“HBM开发团队”&#xff0c;旨在提升其在高带宽存储器(HBM)领域的竞争力。根据Business Korea的最新报告&#xff0c;该团队将专注于推进HBM3、…...

图书馆数据仓库

目录 1.数据仓库的数据来源为业务数据库&#xff08;mysql&#xff09; 初始化脚本 init_book_result.sql 2.通过sqoop将mysql中的业务数据导入到大数据平台&#xff08;hive&#xff09; 导入mysql数据到hive中 3.通过hive进行数据计算和数据分析 形成数据报表 4.再通过sq…...

基于uniapp(vue3)H5附件上传组件,可限制文件大小

代码&#xff1a; <template><view class"upload-file"><text>最多上传5份附件&#xff0c;需小于50M</text><view class"" click"selectFile">上传</view></view><view class"list" v…...

Phoenix Omid Timestamp Oracle 组件实现原理

Omid Timestamp Oracle 组件实现原理 作用 生成全局单调递增的时间戳&#xff0c;支持获取操作和崩溃恢复。 功能 1.生成全局单调递增的时间戳(支持崩溃恢复)apinext返回下一个时间戳getLast返回最后一个分配的时间戳(当前时间戳)实现方式TimestampOracleImpl单调递增的时间…...

Lex Fridman Podcast with Andrej Karpathy

我不太喜欢Lex Fridman的声音&#xff0c;总觉得那让人昏昏欲睡&#xff0c; 但无奈他采访的人都太大牌了&#xff0c;只能去听。但是听着听着&#xff0c;就会觉得有深度的采访这些人&#xff0c;似乎也只有他这种由研究员背景的人能干&#xff0c; 另&#xff0c;他提的问题确…...

力扣1895.最大的幻方

力扣1895.最大的幻方 求前缀和暴力枚举幻方边长 求行列前缀和 class Solution {public:int largestMagicSquare(vector<vector<int>>& grid) {int n grid.size() , m grid[0].size();vector<vector<int>> rowsum(n,vector<int>(m));for…...

【C++】 解决 C++ 语言报错:Segmentation Fault

文章目录 引言 段错误&#xff08;Segmentation Fault&#xff09;是 C 编程中常见且令人头疼的错误之一。段错误通常发生在程序试图访问未被允许的内存区域时&#xff0c;导致程序崩溃。本文将深入探讨段错误的产生原因、检测方法及其预防和解决方案&#xff0c;帮助开发者在…...

【linuxC语言】手撕Http协议之程序框架

文章目录 前言提示基本框架主函数一个小问题代码概况多线程版本单线程版本总结前言 在现代网络编程中,HTTP协议无疑是最常用的协议之一。它是互联网上应用最为广泛的一种网络协议。理解HTTP协议并能够手动实现它,对于深入理解网络编程和提高编程技能都有着重要的意义。本文将…...

溶解氧(DO)理论指南(1)

转载自梅特勒官网资料&#xff0c;仅用于学习交流&#xff0c;侵权则删&#xff01; 溶解氧理论指南 1 溶解氧(DO)原理1.1 溶解氧和分压1.2 氧气在水中的溶解度1.3 溶解氧对生物的重要性1.4 溶解氧对工业的重要性 1 溶解氧(DO)原理 氧是宇宙中第三大常见元素&#xff0c;也是…...

Mysql中常用函数的使用示例

场景 基础知识回顾&#xff1a;mysql中常用函数的使用示例。 注&#xff1a; 博客&#xff1a;霸道流氓气质-CSDN博客 实现 数学函数 -- ABS(x)返回x的绝对值 SELECT ABS(-1),ABS(2); -- PI()返回圆周率 SELECT PI(); -- SQRT(x)返回非负数x的二次方根 SELECT SQRT(4); -…...

开源205W桌面充电器,140W+65W升降压PD3.1快充模块(2C+1A口),IP6557+IP6538

开源一个基于IP6557和IP6538芯片的205W升降压快充模块&#xff08;140W65W&#xff09;&#xff0c;其中一路C口支持PD3.1协议&#xff0c;最高输出28V5A&#xff0c;另一路是A口C口&#xff0c;最高输出65W&#xff08;20V3.25A&#xff09;&#xff0c;可搭配一个24V10A的开关…...

Java中的内存数据库与缓存技术

Java中的内存数据库与缓存技术 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 内存数据库的概念与优势 1.1 什么是内存数据库&#xff1f; 内存数据库是…...

GUKE万能工具箱(附带源码)

GUKE万能工具箱&#xff08;附带源码&#xff09; 效果图部分源码领取完整源码下期更新 效果图 部分源码 <!DOCTYPE html> <html><head><meta charset"utf-8" name"viewport" content"widthdevice-width, initial-scale1"…...

FFmpeg开发笔记(四十二)使用ZLMediaKit开启SRT视频直播服务

《FFmpeg开发实战&#xff1a;从零基础到短视频上线》一书在第10章介绍了轻量级流媒体服务器MediaMTX&#xff0c;通过该工具可以测试RTSP/RTMP等流媒体协议的推拉流。不过MediaMTX的功能实在是太简单了&#xff0c;无法应用于真实直播的生产环境&#xff0c;真正能用于生产环境…...

spring-boot-starter-data-redis是否支持reactive响应式编程

开源项目SDK&#xff1a;https://github.com/mingyang66/spring-parent 个人文档&#xff1a;https://mingyang66.github.io/raccoon-docs/#/ spring-boot-starter-data-redis&#xff1a; 使用传统的基于阻塞的I/O编程模型&#xff0c;这意味着当你调用Redis操作时&#xff0…...

Java后端每日面试题(day3)

目录 Spring中Bean的作用域有哪些&#xff1f;Spring中Bean的生命周期Bean 是线程安全的吗&#xff1f;了解Spring Boot中的日志组件吗&#xff1f; Spring中Bean的作用域有哪些&#xff1f; Bean的作用域&#xff1a; singleton&#xff1a;单例&#xff0c;Spring中的bean默…...

[单master节点k8s部署]18.监控系统构建(三)Grafana安装

Grafana是一个跨平台的开源的度量分析和可视化工具。支持多种数据源&#xff0c;比如OpenTSDB&#xff0c;Prometheus&#xff0c;ElasticResearch&#xff0c;Cloudwatch等。 Grafana安装 通过yaml配置grafana的pod和service&#xff0c;grafana工作在kube-system的命名空间…...

【JavaScript脚本宇宙】优化你的Web色彩:精选JavaScript颜色工具对比

万能色彩助手&#xff1a;详解最受欢迎的JavaScript颜色库 前言 在现代Web开发中&#xff0c;颜色处理和转换是一个不可忽视的环节。无论是网站设计、数据可视化还是用户界面开发&#xff0c;都离不开对颜色的精确控制和转换。为了满足这一需求&#xff0c;众多JavaScript库应…...

用html+css设计一个列表清单小卡片

目录 简介: 效果图: 源代码: 可能的问题: 简介: 这个HTML代码片段是一个简单的列表清单设计。它包含一个卡片元素(class为"card"),内部包含一个无序列表(ul),列表项(li)前面有一个特殊的符号(△)。整个卡片元素设计成300px宽,150px高,具有圆角边…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...

Selenium 查找页面元素的方式

Selenium 查找页面元素的方式 Selenium 提供了多种方法来查找网页中的元素&#xff0c;以下是主要的定位方式&#xff1a; 基本定位方式 通过ID定位 driver.find_element(By.ID, "element_id")通过Name定位 driver.find_element(By.NAME, "element_name"…...

更新 Docker 容器中的某一个文件

&#x1f504; 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法&#xff0c;适用于不同场景。 ✅ 方法一&#xff1a;使用 docker cp 拷贝文件到容器中&#xff08;最简单&#xff09; &#x1f9f0; 命令格式&#xff1a; docker cp <…...

安宝特案例丨寻医不再长途跋涉?Vuzix再次以AR技术智能驱动远程医疗

加拿大领先科技公司TeleVU基于Vuzix智能眼镜打造远程医疗生态系统&#xff0c;彻底革新患者护理模式。 安宝特合作伙伴TeleVU成立30余年&#xff0c;沉淀医疗技术、计算机科学与人工智能经验&#xff0c;聚焦医疗保健领域&#xff0c;提供AR、AI、IoT解决方案。 该方案使医疗…...

链结构与工作量证明7️⃣:用 Go 实现比特币的核心机制

链结构与工作量证明:用 Go 实现比特币的核心机制 如果你用 Go 写过区块、算过哈希,也大致理解了非对称加密、数据序列化这些“硬核知识”,那么恭喜你,现在我们终于可以把这些拼成一条完整的“区块链”。 不过别急,这一节我们重点搞懂两件事: 区块之间是怎么连接成“链”…...

CSP信奥赛C++常用系统函数汇总

# CSP信奥赛C常用系统函数汇总## 一、输入输出函数### 1. cin / cout&#xff08;<iostream>&#xff09; cpp int x; cin >> x; // 输入 cout << x << endl;// 输出 优化&#xff1a;ios::sync_with_stdio(false); 可提升速度 2. scanf() /…...