通过模仿网易云音乐的UI进行界面的创建,使用SQLite实现本地数据库的存储功能,使用QT自带的QMediaPlayer进行音频解码的播放。通过爬虫接口获得煎饼搜网站的音乐接口,获得音乐内容,再通过网易云接口获得歌词文件。
- 实现了自定义窗口移动,通过拖动顶层栏来进行移动,以及对应的缩小到任务栏,最大化,退出等功能,用户还可以双击顶层栏进行放大和恢复原先的尺寸。
- 实现了托盘功能,用户可以通过托盘中的应用图标右击来进行退出和显示功能。
- 用户可以通过点击右侧的列表项切换到对应的音乐界面。
- 支持由用户导入本地歌曲文件夹,可以自动检索文件夹下的歌曲。如果想要导入歌词以及对应的信息,需要导入固定格式的内容,可以导入附件songs,其中包含了一些格式化的歌曲。
- 支持播放多种类型的音乐,包括mp3,flac,wav等等格式,加载多种格式的封面图片,如jpg,png等等。
- 支持歌单播放,目前支持的歌单有本地音乐,来源于Gitee的在线音乐,我喜欢的音乐,以及通过搜索得到的音乐。
- 用户可以通过双击四个界面中的任何一个列表项来进行播放对应的音乐,每一个界面都有播放全部的按钮,点击此按钮会清除当前播放列表中其他的列表内容,去播放当前界面中的所有音乐。
- 四个界面中以及底栏的最右侧按钮,都可以通过右击列表项来进行菜单操作,进行加入播放列表操作。在本地音乐,在线音乐,搜索音乐中和播放列表中,不同的是添加了加入喜欢的功能,在我喜欢的界面中,对应的添加了移除的功能菜单。
- 支持用户搜索网络歌曲,功能由爬虫实现,可以搜索网易云音乐中的免费歌曲并且在线进行播放。(注意,需要提前将网络代理关闭)。
- 支持三种播放模式:循环播放(默认),单曲循环,随机播放。歌曲的暂停和继续,切换上一首音乐和下一首音乐等功能。
- 在用户点击了底栏最左侧的头像后,会向上出现一个歌词与封面界面,通过左上角的向下按钮或者再次点击头像可以回到原先的界面。
- 用户可以通过拖动进度条来改变歌曲的播放进度。
- 用户可以通过鼠标悬浮到音量按钮上,通过拖动改变音量,或者通过点击音量按钮实现静音功能。
- 用户可以通过点击底栏最右侧的列表按钮看到当前的播放列表,当双击列表项的时候,会改变播放顺序,首先播放当前的歌曲。
整体使用MVC架构进行界面和模型的分离,使用控制层来完成二者之间的交互工作。
- MainWindow: 主界面,分为上边栏,侧边栏,中心,和底部栏四个部分。(单例模式)
- Lyric: 歌词界面,主要进行歌词的展示工作。
- Loading: 加载界面,主要是为了实现搜索音乐的加载过程。
- Volume: 音量界面,实现与音量滑块的交互。
- PlayListView: 播放列表界面,实现当前播放列表的展示。
- Cache: 实现歌曲在播放过程中的缓存。
- DataBase: 实现本地数据库的创建,相关数据的增删查改。(单例模式)
- ImportLocalMusic: 导入本地音乐,实现音乐的匹配,返回结构化信息。
- DownloadFile: 与Cache进行搭配实现歌曲的缓存,同时为以后添加下载功能留下接口。
- SearchMusic: 通过爬虫接口,实现搜索歌曲的功能,返回对应的歌曲信息。
- PlayList: 实现歌曲播放列表,根据不同的播放模式获得不同的下一首播放歌曲信息,同时完成了喜欢音乐的插入和移除功能。(单例模式)
- AllControl: 包含了所有的其他控制类,方便在main文件包含。
- CustomItemDeleGate: 自定义委托,提高表格显示的灵活性。
- DisPlay: 控制在各个界面的播放列表中应该显示出来的内容。
- ControlPlayList: 控制播放列表,实现界面中按键与播放列表的交互。
- StartPlayMusic: 开始播放音乐,通过ControlPlayList获得具体该播放的歌曲,以及打断时候播放的内容,进行歌词的解析展示等。
- MessageStruct.h: 存储了传递信息的格式结构体,以及一些样式表,方便切换。
- 首先是我想要实现表格之间的交替颜色,在最开始我使用的是QTableWidget,很久都没有解决这个问题,因此后面尝试使用QTableView + 自定义委托的方式进行实现。同时认识到了后者的好处,更加的自由和可以自定义展示。
- 在设计数据库的时候,本来想要根据歌曲的本地路径作为主键,但是考虑到了后面的网络接口以及后续的扩展,设计了一个allPath和songID作为次主键,解决了网络在线音乐表格背后的数据隐藏,还解决了以后尝试下载缓存的时候,如果一首歌曲的部分文件出现缺失,可以通过此项进行填充显示,还可以通过songID解决添加喜欢音乐时本地和网络中歌曲相同,但是路径不同的情况。
- 很多是因为初始化或者内存泄漏(继续delete一个已经delete的指针,或者使用没有new的对象),通过Qt中的对象树很有利于解决内存泄漏的问题。
- 在使用爬虫得到的接口的时候,会有一部分音乐是无法播放的,网站更改了规则,因此需要在播放的时候进行判断,使用了QMediaPlayer的errorOccured和stateChanged等都没有解决问题,在输出中,发现只是一个警告,因此不会触发上面所说的信号。目前我选择对文件的大小判断来确定下载到的文件是否是有效的音频文件,后期我会通过改进爬虫来解决无法播放的问题(只用于学习)。
- 进度条拖动造成了音乐卡顿,且拖动卡顿。原因在于,拖动的时候进度条向前跨度较大,但是音乐播放的时候,同样触发了进度条的位置,会造成反复横条,通过添加一个是否正在拖动的标志变量可以完成解决,当拖动的时候,不会触发音乐播放改变,造成进度条改变的问题,在释放的时候,再改变到对应的位置即可。
- 在线的音乐无法移出我喜欢的音乐,原因在于我移除的时候,传给的是allPath,而不是songPath,修改即可。
- mainwindow很大,快接近1000行代码,看起来较为臃肿。
- 使用信号槽lambda,使得结构看起来较为混乱。
- 一些隐藏的问题,如果快速切换在线音乐和本地音乐,因为加载动画的进行,会出现进度条的异常显示。
- 可以通过类似于android中的toggle对用户进行消息提示,如无法播放,加入列表等等提示信息,而不是大量的QMessageBox。
- 窗口的放大和缩小动画,以及边缘阴影效果。
- 主题颜色的更换。
- 用户可以自定义歌单。
- 灵动岛类似的桌面歌词效果。