MusicApp 是一款基于 WPF 框架开发的网易云音乐桌面客户端,由开发者 liuguofeng独立开发,项目托管在 Gitee(https://gitee.com/liu_guo_feng/music-app),采用 Apache License 2.0 开源协议。
项目使用开源的 NeteaseCloudMusicApi 作为后端数据源,构建了一个功能完整的 Windows 桌面音乐播放器。
技术栈
| UI 框架 | |
| .NET 版本 | |
| 架构模式 | |
| JSON 处理 | |
| 系统托盘 | |
| 后端 API | |
| 开发工具 |
核心功能
音乐发现与播放
首页展示轮播图、推荐歌单、新歌推荐等内容。调用网易云 /personalized/newsong 接口获取个性化每日推荐,支持"播放全部"一键播放推荐歌曲。
浏览歌单详情时,展示歌单内完整歌曲列表,支持右键菜单对单曲进行操作。
歌词同步滚动
歌词解析采用正则表达式 (^\[\d+:\d+\.\d+\]) 提取时间戳,通过 DispatcherTimer 以 50ms 频率刷新,实现歌词随播放进度自动滚动高亮,当前歌词自动居中显示(ScrollToCenterOfView)。
多种播放模式
支持列表循环、单曲循环、随机播放、顺序播放四种模式,可在播放控制栏自由切换。
播放列表管理
播放列表可切换显示/隐藏,支持右键菜单操作:添加到下一首播放、移除歌曲、清空列表等。
搜索功能
支持搜索单曲、歌手、专辑、歌单,同时展示热搜排行榜。搜索结果以列表形式展示,支持直接播放和加入播放列表。
主题切换
MusicApp 内置 6 种主题色,通过动态切换 ResourceDictionary 实现热换肤,无需重启应用。同时支持亮色/暗色(DefaultColor / BlackColor)模式切换。
主题资源文件位于 Themes/Color/ 目录下:
Themes/Color/
├── DefaultColor.xaml # 默认亮色主题
└── BlackColor.xaml # 暗色主题
Windows 任务栏集成
应用在 Windows 任务栏缩略图上显示当前播放歌曲名和播放/暂停状态图标,支持直接在任务栏预览中点击"上一首/下一首/播放/暂停"按钮,无需打开主窗口即可控制播放。
任务栏控制图标位于 Assets/Images/TaskbarItemInfo/ 目录。
系统托盘
支持最小化到系统托盘,托盘图标可进行基本操作。系统托盘组件使用 Hardcodet.NotifyIcon.Wpf 库实现,自定义控件位于 Control/NotifyIcon.xaml。
游客模式
应用启动时自动调用网易云 /register/anonimous 接口注册游客账号,无需登录即可使用核心音乐播放功能。
歌曲缓存与状态持久化
歌曲本地缓存:播放过的 MP3 歌曲自动保存到本地 cache/songs 目录,下次播放同一首歌时直接从本地读取,避免重复下载,节省网络流量。
播放状态持久化:当前播放歌曲、播放模式、主题偏好等通过 JSON 文件本地缓存,应用关闭时保存,下次启动自动恢复。本地数据模型定义在 Models/JsonDataModel.cs。
全局异常处理
应用通过 App.xaml.cs 注册全局异常处理器,UI 线程未捕获的异常自动记录到 ./error/ 目录的日志文件,方便排查问题。
项目架构
项目严格遵循 MVVM 模式,Model、View、ViewModel 三层分离:
MusicApp/
├── App.xaml / App.xaml.cs # 应用入口,全局异常处理
├── MusicApp.csproj # .NET 6 WPF 项目配置
│
├── Common/ # 公共工具类
│ ├── CommandBase.cs # 自定义命令基类 (ICommand)
│ ├── HttpUtil.cs # HTTP 请求工具
│ ├── JsonFileUtil.cs # JSON 文件读写
│ └── NotifyBase.cs # INotifyPropertyChanged 基类
│
├── Component/ # 自定义组件样式
│ ├── AppCsStyle/ # C# 代码定义样式
│ └── AppStyle/ # XAML 样式资源
│
├── Control/ # 自定义用户控件
│ ├── PlayerControl.xaml # 播放器控件
│ ├── SearchListControl.xaml # 搜索结果列表
│ ├── SongDetailControl.xaml # 歌曲详情(歌词页)
│ ├── SongPlayListControl.xaml # 播放列表
│ ├── ThemeColorControl.xaml # 主题切换
│ └── Widget/
│ ├── CarouselControl.xaml # 轮播图
│ ├── LoadingControl.xaml # 加载指示器
│ └── SongsControl.xaml # 歌曲列表
│
├── Models/ # 数据模型
│ ├── Vo/ # API 响应对象
│ └── PageView/ChildPage/ # 子页面模型
│
├── ViewModels/ # 视图模型
│ ├── MainWindowViewModel.cs # 主窗口 VM
│ ├── PlayerViewModel.cs # 播放器 VM(核心)
│ ├── SongDetailViewModel.cs # 歌词滚动 VM
│ └── ...
│
├── Views/ # 视图层
│ └── MainWindow.xaml # 主窗口
│
├── Themes/ # 主题资源
│ └── Color/
│ ├── DefaultColor.xaml # 亮色主题
│ └── BlackColor.xaml # 暗色主题
│
└── server/ # Docker API 容器
└── music_api.tar # 预打包的网易云 API 镜像
跨 ViewModel 通信通过 Action 委托实现,命令绑定通过自定义 CommandBase 类(实现 ICommand 接口)完成。
后端部署
项目内置了打包好的 music_api.tar Docker 镜像,两条命令即可启动本地网易云 API 服务:
docker load -i music_api.tar
docker run -d -p 3000:3000 music_api:1.0
后端 API 启动后,客户端通过 HttpUtil 连接到本地 http://localhost:3000 获取音乐数据。
项目数据
项目从基础架构起步,后期完成了从 code-behind 到 MVVM 的架构重构(mvvm 分支),体现了作者对 WPF 最佳实践的追求。
运行方式
# Clone 项目
git clone https://gitee.com/liu_guo_feng/music-app.git
# 启动后端 API(可选,需安装 Docker)
cd server
docker load -i music_api.tar
docker run -d -p 3000:3000 music_api:1.0
# 使用 Visual Studio 2022 打开 MusicApp.csproj 运行
注意:项目仅供学习使用,不作商业用途。
项目地址:
https://gitee.com/liu_guo_feng/music-app
如果你觉得这个项目有用,欢迎 Star 支持,也欢迎在评论区交流使用心得。