Skip to content

Repository files navigation

MAGNET 磁格音乐

CI Release

基于 Avalonia 12 与 SukiUI 7 的 Windows / Android 磁格风格音乐播放器。

功能

  • Windows Media Foundation + WASAPI 原生播放
  • Android Media3 原生播放、后台服务与媒体通知
  • MP3、FLAC、AAC、M4A、WAV、WMA;OGG/Opus 暂不支持
  • 本地曲库、最近播放、队列、收藏及导入歌单
  • 网易云音乐与 QQ 音乐搜索、二维码登录和歌单同步
  • 歌词页、底部对齐频谱与页面过渡动画
  • 播放模式、每日歌单和用户状态本地持久化

开发

需要 .NET 10 SDK。Android 构建还需要 Android SDK 与 JDK 17 或更高版本。

dotnet restore
dotnet run -f net10.0
dotnet test tests\MagnetTileMusicPlayer.Tests\MagnetTileMusicPlayer.Tests.csproj -c Release

Windows 使用系统原生媒体能力,不依赖 VLC。在线账号密码不会写入本地;扫码产生的会话 Cookie 通过应用凭据存储持久化,退出账号时清理。

在线音源网关

应用不保存平台密码。扫码授权产生的网易云音乐与 QQ 音乐会话 Cookie 通过系统凭据保护后保存在本机,只用于请求当前账号有权访问的内容。

所有接口使用相同的客户端身份令牌:

Authorization: Bearer <token>

二维码登录

网易云音乐与 QQ 音乐都由客户端创建短时二维码挑战并轮询平台授权状态,不需要嵌入 WebView。QQ 音乐二维码使用腾讯 QQ 授权页的当前参数,需使用手机 QQ 扫码并确认。

创建登录挑战:

POST /v1/auth/qr?provider=netease

响应必须包含 sessionId,并通过 qrCodeTextqrCodeUrlqrCodeData 提供一种二维码来源:

{
  "sessionId": "login-session-id",
  "qrCodeText": "provider-login-payload",
  "expiresInSeconds": 180,
  "pollIntervalMs": 1500
}

轮询授权状态:

GET /v1/auth/status?provider=netease&sessionId=login-session-id

status 可取 pendingscannedauthorizedexpireddenied

{
  "status": "authorized",
  "account": {
    "id": "provider-user-id",
    "displayName": "用户昵称",
    "avatarUrl": "https://example.com/avatar.jpg"
  }
}

查询当前账号与退出登录:

GET    /v1/me?provider=netease
DELETE /v1/auth/session?provider=netease

登录挑战使用随机会话 ID、三分钟有效期,并只在应用内存中保存轮询上下文。授权成功后仅持久化平台返回的会话 Cookie;退出账号会同时清理内存会话和本地凭据。

个人歌单

GET /v1/me/playlists?provider=netease

响应:

{
  "items": [
    {
      "id": "playlist-id",
      "name": "我喜欢的音乐",
      "description": "收藏的歌曲",
      "trackCount": 128,
      "coverUrl": "https://example.com/playlist.jpg"
    }
  ]
}

导入歌单曲目:

GET /v1/playlists/playlist-id/tracks?provider=netease&limit=1000

响应使用与搜索相同的歌曲结构。播放器只持久化平台歌曲 ID 和元数据,不保存可能过期的 streamUrl

搜索

GET /v1/search?provider=netease&q=关键词&limit=30

provider 可取 neteaseqq。响应:

{
  "items": [
    {
      "id": "platform-track-id",
      "title": "歌曲名",
      "artist": "艺术家",
      "album": "专辑名",
      "durationMs": 245000,
      "coverUrl": "https://example.com/cover.jpg",
      "streamUrl": null
    }
  ]
}

获取播放地址

当搜索或导入结果没有直接返回 streamUrl 时,播放器按需请求:

GET /v1/stream?provider=netease&id=platform-track-id

响应:

{
  "url": "https://authorized-cdn.example.com/audio.mp3"
}

网关应只返回当前用户有权播放的地址,并自行处理短期 URL 刷新。播放器不会绕过 DRM、付费权限或地区限制。

发布

正式版本从 0.1.0 开始。推送 vMAJOR.MINOR.PATCH 标签后,GitHub Actions 自动完成:

  1. 校验标签与项目版本。
  2. 构建自包含 Windows x64 ZIP。
  3. 使用仓库 Secrets 签名 Android Release APK。
  4. 生成 SHA-256 校验文件并创建 GitHub Release。
  5. 下载站自动读取并提供最新 Release 包。

完整配置和密钥要求见 .github/RELEASING.md。准备版本:

.\scripts\release.ps1 -Version 0.1.0 -Push

项目结构

Models/             音乐、账号、状态与页面模型
Services/           本地、在线音源、缓存与播放协调
Platforms/Android/  Media3 播放器、后台服务与通知资源
ViewModels/         导航、播放、登录与持久化状态
Views/              Avalonia 页面、布局与动画
site/               GitHub Pages 下载站
.github/workflows/  CI、Pages 与 Release 自动化
tests/              单元与行为测试

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages