当前位置: 首页 > 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高,具有圆角边…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG

TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码&#xff1a;HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

如何把工业通信协议转换成http websocket

1.现状 工业通信协议多数工作在边缘设备上&#xff0c;比如&#xff1a;PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发&#xff0c;当设备上用的是modbus从站时&#xff0c;采集设备数据需要开发modbus主站&#xff1b;当设备上用的是西门子PN协议时&#xf…...

【工具教程】多个条形码识别用条码内容对图片重命名,批量PDF条形码识别后用条码内容批量改名,使用教程及注意事项

一、条形码识别改名使用教程 打开软件并选择处理模式&#xff1a;打开软件后&#xff0c;根据要处理的文件类型&#xff0c;选择 “图片识别模式” 或 “PDF 识别模式”。如果是处理包含条形码的 PDF 文件&#xff0c;就选择 “PDF 识别模式”&#xff1b;若是处理图片文件&…...