ShikenMatrix 是一个基于 原生 Rust 构建的跨平台桌面应用程序,旨在提供优雅的窗口管理和媒体信息展示体验。它采用现代化的原生 UI 框架(macOS 使用 SwiftUI,Windows 使用 WinUI 3),能够实时显示当前前台窗口的详细信息以及正在播放的媒体内容。
本项目是 Kizuna 项目的继任者,在原有功能基础上进行了全面的重构和功能增强,提供更加现代化、高性能和跨平台的用户体验。
本项目采用 GNU Affero General Public License v3.0 开源协议。
- 实时监控:自动获取并显示当前活动窗口的标题、图标和进程信息
- 应用图标展示:动态加载并显示前台应用的图标(支持原生缓存)
- 窗口标题跟踪:实时更新窗口标题变化
- 智能缓存:LRU 缓存机制,最多缓存 20 个应用图标(~7 MB)
- 媒体元数据:支持显示当前播放的音乐/视频标题、艺术家、专辑信息
- 专辑封面展示:自动获取并显示高质量专辑封面
- 播放状态同步:实时同步播放/暂停状态,仅在播放时显示媒体信息
- 跨应用支持:支持系统级媒体控制
- macOS: 使用 MediaRemote 框架(基于 MediaRemote-rs)
- Windows: 使用 System Media Transport Controls (SMTC)
- 原生框架:macOS 使用 SwiftUI,Windows 使用 WinUI 3,提供原生体验
- 玻璃拟态风格:采用精美的 Acrylic/Glassmorphism 视觉效果,完美融入系统环境
- 自适应主题:自动适配系统亮色/暗色模式,提供一致的视觉体验
- 自适应窗口:窗口大小根据内容自动调整,确保最佳显示效果
- 流畅动画:所有交互都配备精心设计的过渡动画
- 拖拽移动:按住顶部拖拽区域即可移动窗口
- 胶囊菜单:双击或长按顶部区域打开交互式胶囊菜单
- 窗口操作:支持关闭、最小化、置顶等常用窗口操作
- 视觉反馈:所有交互都有清晰的视觉和动画反馈
- macOS:✅ 完整支持(SwiftUI + Metal)
- Windows:✅ 完整支持(WinUI 3 + DirectX)
- 架构设计:采用平台抽象层(
platform模块),便于扩展到其他操作系统
┌─────────────────────────────────────────┐
│ 原生 UI 层 │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ SwiftUI │ │ WinUI 3 │ │
│ │ (macOS) │ │ (Windows) │ │
│ └──────────────┘ └──────────────┘ │
└──────────────┬──────────────────────────┘
│ FFI Bridge (C ABI)
┌──────────────┴──────────────────────────┐
│ Rust Backend │
│ ┌────────────────────────────────┐ │
│ │ Reporter (tokio async) │ │
│ │ - WebSocket 上报 │ │
│ │ - 数据去重与缓存 │ │
│ └────────────────────────────────┘ │
│ ┌────────────────────────────────┐ │
│ │ Platform Layer │ │
│ │ - Window Info │ │
│ │ - Media Info │ │
│ └────────────────────────────────┘ │
└─────────────────────────────────────────┘
- macOS: 11.0 Big Sur 或更高版本
- Xcode: 14.0 或更高版本
- Rust: 1.70 或更高版本(通过 rustup 安装)
- cbindgen: 用于生成 C 头文件
- Windows 10: 版本 1809 或更高版本
- Visual Studio: 2019 或更高版本(含 C++ 工作负载)
- Rust: 1.70 或更高版本
- Windows SDK: 最新版本
# 克隆项目
git clone https://github.com/AlienFamilyHub/ShikenMatrix.git
cd ShikenMatrix
# 1. 构建 Rust 库
cd macos-ui
./build-rust.sh
# 2. 使用 Xcode 打开项目
open ShikenMatrix/ShikenMatrix.xcodeproj
# 3. 在 Xcode 中运行 (Cmd+R)# 克隆项目
git clone https://github.com/AlienFamilyHub/ShikenMatrix.git
cd ShikenMatrix/win-ui
# 1. 使用 Visual Studio 打开解决方案
# 双击 ShikenMatrix.slnx 或 ShikenMatrix.csproj
# 2. 在 Visual Studio 中还原 NuGet 包
# Visual Studio 会自动提示还原包
# 3. 构建并运行 (F5)
# 首次构建时会自动执行 pre-build.ps1 编译 Rust 库首次运行时,应用会请求辅助功能权限,这是获取前台窗口信息所必需的:
- 打开 系统设置 > 隐私与安全性 > 辅助功能
- 找到
ShikenMatrix并勾选启用 - 重启应用
如遇"无法打开,因为它来自身份不明的开发者",可在"系统设置 → 隐私与安全性"中允许该程序运行,或在终端执行:
xattr -d com.apple.quarantine /Applications/ShikenMatrix.app
Windows 系统对窗口信息访问的权限管理相对宽松,通常无需额外配置即可正常使用。
ShikenMatrix/
├── src/ # Rust 后端代码
│ ├── ffi/ # FFI 接口(C ABI)
│ │ ├── mod.rs # FFI 模块
│ │ ├── reporter.rs # 上报服务 FFI
│ │ └── types.rs # FFI 类型定义
│ ├── platform/ # 平台抽象层
│ │ ├── mod.rs # 平台接口定义
│ │ ├── macos/ # macOS 平台实现
│ │ │ ├── window.rs # 窗口监控 (Accessibility API)
│ │ │ └── media.rs # 媒体监控 (MediaRemote)
│ │ └── windows/ # Windows 平台实现
│ │ ├── window.rs # 窗口监控 (Win32 API)
│ │ └── media.rs # 媒体监控 (SMTC)
│ ├── services/ # 核心服务
│ │ ├── mod.rs # 服务模块
│ │ ├── reporter.rs # 上报服务(WebSocket)
│ │ └── config.rs # 配置管理
│ ├── lib.rs # 库入口
│ └── main.rs # 可执行文件入口
│
├── macos-ui/ # macOS UI 项目
│ ├── ShikenMatrix/ # Xcode 项目
│ │ ├── ShikenMatrix/ # SwiftUI 源码
│ │ │ ├── ShikenMatrixApp.swift # 应用入口
│ │ │ ├── ContentView.swift # 主窗口
│ │ │ ├── StatusBarManager.swift # 状态栏管理
│ │ │ └── Assets.xcassets/ # 资源文件
│ │ └── ShikenMatrix.xcodeproj # Xcode 项目文件
│ ├── build-rust.sh # Rust 构建脚本
│ └── rust-lib/ # 编译后的 Rust 库
│
├── win-ui/ # Windows UI 项目
│ └── ShikenMatrix/ # WinUI 3 项目
│ ├── App.xaml.cs # 应用入口
│ ├── MainWindow.xaml # 主窗口 XAML
│ ├── MainWindow.xaml.cs # 主窗口逻辑
│ ├── ViewModels/ # MVVM 视图模型
│ │ └── MainViewModel.cs # 主视图模型
│ ├── Models/ # 数据模型
│ │ ├── LogEntry.cs # 日志条目
│ │ ├── MediaData.cs # 媒体数据
│ │ ├── WindowData.cs # 窗口数据
│ │ └── ...
│ ├── Services/ # 服务层
│ │ ├── RustBridge.cs # Rust FFI 调用
│ │ └── TrayIconManager.cs # 系统托盘
│ ├── Native/ # 原生方法声明
│ │ └── NativeMethods.cs # P/Invoke 声明
│ ├── Converters/ # 值转换器
│ ├── Assets/ # 应用资源
│ ├── pre-build.ps1 # Rust 预构建脚本
│ └── ShikenMatrix.csproj # 项目文件
│
├── Cargo.toml # Rust 依赖配置
├── cbindgen.toml # cbindgen 配置
├── build.rs # Rust 构建脚本
├── .gitattributes # Git 属性配置(换行符)
└── README.md # 项目说明文档
后端(Rust)
- 平台抽象层设计,统一的接口定义
- 使用 FFI (C ABI) 暴露系统级功能
- 异步任务处理(基于 tokio)
- 平台特定实现:
- macOS: 使用 objc2 绑定调用 Core Foundation / AppKit / MediaRemote
- Windows: 使用 windows-rs 调用 Win32 API / Windows Media Control
前端
- macOS: SwiftUI + AppKit
- 使用
@main和App协议 - 原生窗口控制和系统集成
- 使用
- Windows: WinUI 3 + Windows App SDK (.NET 8.0)
- 使用 WinUI 3 的现代控件
- Fluent Design 设计语言
- 系统托盘集成
- 后端功能:在
src/platform/中添加平台接口和实现 - 前端组件:在对应平台的 UI 项目中创建新的组件
- FFI 桥接:在
src/ffi/中添加 C 接口,前端通过RustBridge调用
后端技术
- Rust - 系统级编程语言
- tokio - 异步运行时
- serde - 序列化/反序列化
- tokio-tungstenite - WebSocket 客户端
平台集成
- macOS:
- objc2 - Objective-C 运行时绑定
- core-foundation - Core Foundation 框架绑定
- MediaRemote-rs - MediaRemote 框架绑定(自有库)
- Windows:
- windows-rs (0.62) - 现代 Windows API 绑定
- Win32_Foundation
- Win32_UI_WindowsAndMessaging
- Win32_System_Threading
- Media_Control
- Storage_Streams
- windows-rs (0.62) - 现代 Windows API 绑定
前端技术
- macOS: SwiftUI, AppKit
- Windows: WinUI 3, Windows App SDK, .NET 8.0
A: 请确保已授予应用辅助功能权限。前往 系统设置 > 隐私与安全性 > 辅助功能,勾选 ShikenMatrix。
A: 网易云音乐(等国内音乐播放器)不按照微软官方的媒体渠道上报媒体信息(即 Windows System Media Control 集成)。从 Windows 10 版本 1607 开始,默认情况下,使用 MediaPlayer 类或 AudioGraph 类播放媒体的 UWP 应用会自动与 SMTC 集成。只需实例化 MediaPlayer 的新实例,并将 MediaSource、MediaPlaybackItem 或 MediaPlaybackList 分配给播放器的 Source 属性,然后用户将在 SMTC 中看到你的应用名称,并且可以使用 SMTC 控件播放、暂停和在播放列表中移动。 —— Windows 文档
这时需要其他方法来使本程序的媒体上报结构生效,可以通过插件使其通过 SMTC 上报信息。对于网易云音乐,可以尝试使用 MicroCBer/BetterNCM 和 BetterNCM/InfinityLink 搭配使用。
TL;DR:
国内音乐播放器(如网易云音乐)未采用 Windows 标准媒体控制接口 (SMTC),导致无法显示媒体信息。可通过安装特定插件(如网易云音乐的
BetterNCM+InfinityLink)来解决。
A: 媒体信息仅在有音乐/视频正在播放时显示。请确保:
- 系统中有媒体正在播放
- 播放器支持系统级媒体控制(如 Apple Music、Spotify、Chrome 等)
A: 窗口大小会根据内容自动调整,以确保最佳显示效果。当前版本不支持手动调整大小。
A: 目前完整支持 macOS,Windows 支持正在开发中。
A: 欢迎提交 Pull Request!请确保:
- 遵循项目的代码风格
- 为新功能添加适当的注释
- 测试在不同平台上的兼容性
本项目基于 GNU Affero General Public License v3.0 开源。
Developed by TNXG
- GitHub: TNXG
本项目使用的 MediaRemote-rs 参考了 mediaremote-adapter 的设计思路,通过巧妙的三层架构绕过了 macOS 15.4+ 引入的 MediaRemote entitlement 验证。
为什么能工作?
根据 @My-Iris 的发现,bundle identifier 以 com.apple. 开头的进程被授予访问 MediaRemote 框架的权限。系统 Perl 二进制文件 /usr/bin/perl 的 bundle identifier 为 com.apple.perl,因此被系统信任。
┌─────────────────────────────────────┐
│ Rust 应用 (ShikenMatrix) │
│ (调用 mediaremote-rs crate) │
└──────────────┬──────────────────────┘
│ FFI / dylib 嵌入
┌──────────────┴──────────────────────┐
│ libmediaremote_rs.dylib (预编译) │
│ (包含 MediaRemote 绑定代码) │
└──────────────┬──────────────────────┘
│ Perl 脚本调用
┌──────────────┴──────────────────────┐
│ Perl Loader (沙盒层) │
│ (绕过权限验证) │
└──────────────┬──────────────────────┘
│ MediaRemote Framework
┌──────────────┴──────────────────────┐
│ macOS MediaRemote.framework │
│ (Apple 私有框架) │
└─────────────────────────────────────┘
-
嵌入预编译 dylib
- 将预编译的 dylib 嵌入到 Rust 二进制中
- 运行时提取到临时目录,避免签名依赖
-
Perl 沙盒层
- 使用 Perl 的
DynaLoader动态加载 dylib - 绕过 macOS 15.4+ 的 entitlement 验证(Perl 进程不受限制)
- 使用 Perl 的
-
objc2 直接绑定
- 通过
objc2直接调用 MediaRemote Framework - 使用
MRMediaRemoteGetNowPlayingInfo获取播放信息 - 解析 NSDictionary 获取元数据和封面
- 通过
-
智能 Artwork 处理
- 从 MediaRemote 获取二进制封面数据
- Base64 编码传输
- 自动检测 MIME 类型(JPEG/PNG/GIF/WebP)
| 方案 | macOS 15.4+ 支持 | 需要 Entitlement | 维护成本 |
|---|---|---|---|
| MediaRemote-rs | ✅ 完美支持 | ❌ 不需要 | 中等(自有库) |
| mediaremote-adapter | ✅ 完美支持 | ❌ 不需要 | 中等(脚本) |
| 直接 MediaRemote | ❌ 受限制 | ✅ 需要 | 高 |
| 系统 MP* 框架 | ❌ 不需要 | 低(官方) |
这种架构使得 ShikenMatrix 能够在最新的 macOS 系统上无障碍地获取媒体信息,无需申请特殊权限或进行复杂的代码签名配置。
- objc2 - Objective-C 绑定
- tokio - 异步运行时
- SwiftUI - 原生 UI 框架
- mediaremote-adapter - Perl 沙盒层设计思路参考
- MediaRemote-rs - macOS MediaRemote 框架绑定(自有库)
- WinUI 3 - Windows 原生 UI 框架