音樂播放器

目錄

  • 一、設計目標
  • 二、實現流程
    • 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. 對軟件設計的認知:設計和編寫前端頁面、根據前端頁面實現功能;其中有一個重點:后端服務層的功能重點是與數據庫的交互,根據數據庫返回的數據進行條件判斷,提取數據庫的數據進行信息呈現和功能實現。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41447.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41447.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41447.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

通過Java調用OceanBase云平臺API

最近由于工作原因又開始搗鼓OceanBase&#xff0c;OceanBase云平臺(OCP)提供了強大的管理和監控功能&#xff0c;而且對外開放API接口&#xff0c;可以將部分監控整合到自己的平臺&#xff0c;所以寫了個Java調用OCP API的demo做為自己的技術儲備&#xff0c;也想分享給大家。也…

linux下mysql的定時備份

備份是容災的基礎&#xff0c;是指為了防止系統出現操作或系統故障導致數據丟失&#xff0c;而將全部或部分數據集合從應用主機的硬盤或陣列復制到其他的存儲介質的過程為什么備份 硬件故障軟件故障誤操作病毒入侵保留歷史記錄災難性事件 存儲介質 光盤磁帶硬盤磁盤陣列DAS:直接…

[leetcode]文件組合

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<vector<int>> fileCombination(int target) {vector<vector<int>> vec;vector<int> res;int sum 0, limit (target - 1) / 2; // (target - 1) / 2 等效于 target /…

一些你可能不知道的前端小優化- ??(?????)

前言 以前寫css和html和一些原生DOM操作&#xff0c;感覺寫完就完事了。從來沒有考慮過一些性能優化的問題&#xff0c;剛好最近學完了瀏覽器的事件循環和瀏覽器的工作流程。今天大家分享一些我剛學習到的前端小優化。 瀏覽器的工作流程 瀏覽器的渲染過程大致分為以下幾個階…

Windows 11內置一鍵系統備份與還原 輕松替代Ghost

面對系統崩潰、惡意軟件侵襲或其他不可預見因素導致的啟動失敗&#xff0c;Windows 7~Windows 11內置的系統映像功能能夠迅速將您的系統恢復至健康狀態&#xff0c;確保工作的連續性和數據的完整性。 Windows內置3種備份策略 U盤備份&#xff1a;便攜且安全 打開“創建一個恢…

Ubuntu20.04突然沒網的一種解決辦法

本來要學一下點云地圖處理&#xff0c;用octomap庫&#xff0c;但是提示少了octomap-server庫&#xff0c;然后通過下面命令安裝的時候&#xff1a; sudo apt install ros-noetic-octomap-server 提示&#xff1a;錯誤:7 https://mirrors.ustc.edu.cn/ubuntu focal-security …

MWC上海展 | 創新微MinewSemi攜ME54系列新品亮相Nordic展臺

6月28日&#xff0c; 2024MWC上海圓滿落幕&#xff0c;此次盛會吸引了來自全球124個國家及地區的近40,000名與會者。本屆大會以“未來先行&#xff08;Future First&#xff09;”為主題&#xff0c;聚焦“超越5G”“人工智能經濟”“數智制造”三大子主題&#xff0c;探索討論…

leetcode熱題HOT42. 接雨水

一、問題描述&#xff1a; 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖&#xff0c;計算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 二、解題思路&#xff1a; 思路1&#xff1a;通過動態規劃的預處理方式&#xff0c;分別計算每個柱子左右兩側的最大高度&…

js數據庫多級分類按樹形結構打印

可以使用 JavaScript 來按層級打印 categories 數組。首先&#xff0c;需要將這個數組轉換成一個樹形結構&#xff0c;然后再進行遞歸或者迭代來打印每個層級的內容。 以下是一個示例代碼&#xff0c;用來實現這個功能&#xff1a; const categories [{ id: 2, name: "…

java如何刪除字符串內部分字符

java中&#xff0c;如果要刪除字符串內部分字符&#xff0c;需要用delete方法&#xff0c;前提字符串是可變字符串StringBuffer類型的。 delete方法的語法格式是sbf.delete(start,end) 其中&#xff0c;sbf是任意StringBuffer對象&#xff0c;start是起始索引&#xff0c;end…

AQ mode

算法原理概述 AQ即adaptive quantization(自適應量化),屬于宏塊級別碼流分配的范疇,在一幀的宏塊之間調整碼率分配,x264中AQ算法的核心內容是:復雜宏塊使用大的QP,簡單宏塊使用小的QP。x264如何定義復雜?x264是根據宏塊內像素值的方差來評價宏塊復雜性,方差越大,宏塊…

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

轉載自梅特勒官網資料&#xff0c;僅用于學習交流&#xff0c;侵權則刪&#xff01; 溶解氧理論指南 1 溶解氧(DO)原理1.1 溶解氧和分壓1.2 氧氣在水中的溶解度1.3 溶解氧對生物的重要性1.4 溶解氧對工業的重要性 1 溶解氧(DO)原理 氧是宇宙中第三大常見元素&#xff0c;也是…

JavaScript(6)——數據類型轉換

為什么需要類型轉換&#xff1f; JavaScript是弱數據類型&#xff1a;JavaScript不知道變量到底屬于哪種數據類型&#xff0c;只有賦值了才清除 使用表單&#xff0c;prompt獲取的數據默認為字符串類型&#xff0c;此時不能直接進行算數運算 隱式轉換 某些運算符被執行時&am…

力扣hot100-鏈表

文章目錄 概要鏈表的類型 題目&#xff1a;相交鏈表題解 概要 鏈表&#xff08;Linked List&#xff09;是數據結構中的一種&#xff0c;用于存儲具有線性關系的數據。在鏈表中&#xff0c;每個元素稱為一個節點&#xff08;Node&#xff09;&#xff0c;每個節點包含兩個部分…

”極大似然估計“和”貝葉斯估計“思想對比

極大似然估計&#xff08;Maximum Likelihood Estimation, MLE&#xff09;和貝葉斯估計&#xff08;Bayesian Estimation&#xff09;是統計學中兩種重要的參數估計方法&#xff0c;它們在思想和應用上有著顯著的差異。下面我將詳細對比這兩種方法的思想&#xff0c;并分別舉出…

兩次叛國投敵,沒有禍及子孫反而家族長盛不衰的傳奇

這個人就是韓國國王韓王信&#xff0c;漢朝八大異姓王之一。 第一次叛國投敵&#xff0c;發生在楚漢爭霸時期。有一次他的軍隊被項羽包圍&#xff0c;于是選擇了投降。不過&#xff0c;這是權宜之計&#xff0c;不久就借機回到劉邦陣營。 第二次叛國投敵&#xff0c;發生在西…

【Linux開發】基于ALSA庫實現音量調節

基于ALSA庫實現音量調節 ALSA庫實現音量調節1、使用alsamixer工具查看音頻接口2、完整代碼2.1、snd_mixer_open2.2、snd_mixer_attach、2.3、snd_mixer_selem_register2.4、snd_mixer_load2.5、snd_mixer_first_elem/snd_mixer_elem_next2.6、snd_mixer_selem_get_playback_vol…

linux下php的psr.so擴展源碼安裝

cd /usr/local/src git clone https://github.com/jbboehr/php-psr.git cd php-psr /usr/local/php/bin/phpize ./configure --with-php-config/usr/local/php/bin/php-config make make install在php.ini中添加extensionpsr.so 重啟php-fpm /etc/init.d/php-fpm relo…

打卡第3天---鏈表相關

除了每天自己寫博客總結我個人的學習收獲情況之外,我也會看其他錄友寫的博客文章,對于其他錄友的博客內容在代碼隨想錄的訓練營都是開誠布公的,都能互相看到。彼此學習,彼此參照,有一位錄友思路很清晰呀,用畫圖軟件把自己對題的思路畫的特別清晰,我 應該向他們學習;除此…

從零開始使用 Docsify 搭建文檔站點

引言 在當今的技術環境中&#xff0c;擁有一份易于訪問和美觀的文檔是至關重要的。Docsify 是一個非常適合快速搭建文檔站點的工具&#xff0c;它簡單易用&#xff0c;且不需要生成靜態文件。本文將帶你一步步從零開始使用 Docsify 搭建一個文檔站點。 1. 安裝 Node.js 和 np…