mediaremote-rs 是一个 Rust 库,用于访问 macOS 的私有 MediaRemote.framework。它允许开发者获取系统当前的媒体播放信息(如曲目、艺术家、进度等),并监听播放状态的实时变化。
由于 macOS 15.4+ 对 MediaRemote 框架实施了更严格的访问限制,本库通过独特的跨进程适配器技术,确保在最新版 macOS 上依然可用。
- 获取播放信息:读取当前曲目标题、艺术家、专辑、时长、播放进度等。
- 实时状态监听:订阅媒体状态变化,仅在发生变动时接收更新(基于 Rust Channel)。
- 专辑封面支持:获取 Base64 编码的封面图片及 MIME 类型。
- 权限检测:提供 API 检测当前环境是否支持 MediaRemote 访问。
- 强类型接口:提供完整的 Rust 类型定义和 JSON 序列化支持。
- 广泛兼容性:支持 Apple Music, Spotify, Chrome, IINA 等所有集成系统媒体控制的应用。
在 Cargo.toml 中添加依赖:
[dependencies]
mediaremote-rs = "0.1.1"获取当前的播放状态和详细信息。
use mediaremote_rs::{get_now_playing, is_playing, test_access};
fn main() {
// 可选:检查是否能够访问 MediaRemote 服务
if !test_access() {
eprintln!("无法访问 MediaRemote 服务,请检查权限或系统版本。");
return;
}
// 检查是否有媒体正在播放
if is_playing() {
println!("正在播放中...");
}
// 获取详细信息
if let Some(info) = get_now_playing() {
println!("标题: {}", info.title);
println!("艺术家: {}", info.artist.unwrap_or_default());
println!("专辑: {}", info.album.unwrap_or_default());
if let Some(duration) = info.duration {
println!("时长: {:.1} 秒", duration);
}
} else {
println!("当前没有媒体播放信息");
}
}使用 subscribe 函数创建一个监听器,它会在后台线程轮询并在状态变化时发送消息。
use mediaremote_rs::subscribe;
use std::time::Duration;
fn main() {
// 每 500ms 检查一次变化
let receiver = subscribe(Duration::from_millis(500));
println!("开始监听媒体状态变化 (按 Ctrl+C 停止)...");
for info in receiver {
if info.playing {
println!("▶️ {} - {}", info.title, info.artist.unwrap_or("未知艺术家".into()));
} else {
println!("⏸️ 已暂停: {}", info.title);
}
}
}核心结构体 NowPlayingInfo 包含了所有可用的媒体信息:
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NowPlayingInfo {
pub bundle_identifier: String, // 应用包 ID (如 "com.apple.Music")
pub playing: bool, // 播放状态
pub title: String, // 标题
pub artist: Option<String>, // 艺术家
pub album: Option<String>, // 专辑
pub duration: Option<f64>, // 总时长(秒)
pub elapsed_time: Option<f64>, // 当前进度(秒)
pub artwork_mime_type: Option<String>, // 封面格式 (如 "image/jpeg")
pub artwork_data: Option<String>, // 封面数据 (Base64 字符串)
pub playback_rate: Option<f64>, // 播放速率
}从 macOS 15.4 开始,苹果限制了普通应用直接加载 MediaRemote.framework。只有拥有特定 entitlement 或 com.apple. 前缀的系统应用才能正常使用。
本库采用了一种双进程架构来绕过此限制:
- Rust 主进程:你的应用程序。
- Perl 适配器:利用系统内置的
/usr/bin/perl(它拥有com.apple.perl5签名,因此有权访问 MediaRemote)。
- Rust 程序在运行时提取一个预编译的动态库 (
libmediaremote_rs.dylib) 到临时目录。 - 通过
Command调用系统 Perl,加载该动态库。 - 动态库通过 Objective-C 接口调用 MediaRemote API 获取数据。
- 数据序列化为 JSON 并通过标准输出返回给 Rust 主进程。
这种方法既保证了功能的可用性,又通过 Rust 封装提供了类型安全和易用性。
- 性能:虽然使用了子进程调用,但库经过优化,仅在必要时进行 IPC 通信。对于
subscribe模式,建议轮询间隔不低于 200ms 以平衡实时性和 CPU 占用。 - 环境要求:
- macOS 10.12+
- 系统必须安装有
/usr/bin/perl(macOS 默认自带)
欢迎提交 Issue 和 Pull Request!
MIT License