2 releases
new 0.1.1 | Mar 7, 2025 |
---|---|
0.1.0 | Mar 4, 2025 |
#267 in Images
104 downloads per month
51KB
655 lines
MediaRemote in Rust
This library provides bindings for Apple's private framework, MediaRemote. It is primarily designed to access information about media that is currently playing. Therefore, not all methods from the MediaRemote framework are included in these bindings.
This library should be safe to use. However, it is the first attempt at building these bindings, so there is a high chance of unexpected errors. If you encounter any issues, please report them in the issue tracker or submit a pull request to help improve the library.
Warning: Since MediaRemote is a private Apple framework, using it may introduce compatibility or stability issues, and your app may not be approved for distribution on the App Store. Use this library at your own risk.
Quick Start
To get started, first ensure that the library is installed.
use media_remote::NowPlaying;
fn main() {
// Create an instance of NowPlaying to interact with the media.
let now_playing = NowPlaying::new();
// Use a guard lock to safely access media information within this block.
// The guard should be released as soon as possible to avoid blocking.
{
let guard = now_playing.get_info();
let info = guard.as_ref();
// If information is available, print the title of the currently playing media.
if let Some(info) = info {
println!("Currently playing: {:?}", info.title);
}
}
// Toggle the play/pause state of the media.
now_playing.toggle();
}
API Documentation
This is a brief documentation. More detailed documentation, including examples, is written inside the code documentation. Hover over the function to check the documentation.
High Level API
NowPlaying::new() -> NowPlaying
Creates a new instance of NowPlaying
and registers for playback notifications.
-
Returns:
NowPlaying
: A new instance of theNowPlaying
struct.
NowPlaying::get_info(&self) -> RwLockReadGuard<'_, Option<NowPlayingInfo>>
Retrieves the latest now playing information.
-
Returns:
RwLockReadGuard<'_, Option<NowPlayingInfo>>
: A guard to the now playing metadata.
-
Note:
- The lock should be released as soon as possible to minimize blocking time.
NowPlaying::subscribe<F: Fn(RwLockReadGuard<'_, Option<NowPlayingInfo>>) + Send + Sync + 'static>(&self, listener: F) -> ListenerToken
Subscribes a listener to receive updates when the "Now Playing" information changes.
-
Arguments:
listener
: A function or closure that accepts aRwLockReadGuard<'_, Option<NowPlayingInfo>>
.
-
Returns:
ListenerToken
: A token representing the listener, which can later be used to unsubscribe.
NowPlaying::unsubscribe(&self, token: ListenerToken)
Unsubscribes a previously registered listener using the provided ListenerToken
.
-
Arguments:
token
: TheListenerToken
returned when the listener was subscribed.
NowPlayingInfo
pub struct NowPlayingInfo {
pub is_playing: Option<bool>,
pub title: Option<String>,
pub artist: Option<String>,
pub album: Option<String>,
pub album_cover: Option<DynamicImage>,
pub elapsed_time: Option<f64>,
pub duration: Option<f64>,
pub bundle_id: Option<String>,
pub bundle_name: Option<String>,
pub bundle_icon: Option<DynamicImage>,
}
Media Control Functions
These functions allow you to control the currently playing media.
-
NowPlaying::toggle(&self) -> bool
Toggles between play and pause states.
-
NowPlaying::play(&self) -> bool
Starts playing the media.
-
NowPlaying::pause(&self) -> bool
Pauses the media.
-
NowPlaying::next(&self) -> bool
Skips to the next track.
-
NowPlaying::previous(&self) -> bool
Goes back to the previous track.
Low Level API
get_now_playing_application_is_playing() -> Option<bool>
Checks whether the currently playing media application is actively playing.
-
Returns:
Some(true)
: If a media application is playing.Some(false)
: If no media is currently playing.None
: If the function times out (e.g., due to an API failure or missing response).
get_now_playing_client() -> Option<Id>
Retrieves the current "now playing" client ID (which is a reference).
-
Returns:
Some(Id)
: If a valid client ID is found.None
: If no client ID is found or the request times out.
-
Note:
- This function should not be used as the returned ID is short-lived and may cause undefined behavior when used outside of the block.
get_now_playing_application_pid() -> Option<i32>
Retrieves the current "now playing" application PID.
-
Returns:
Some(PID)
: If a valid application PID is found.None
: If no application PID is found or the request times out.
get_now_playing_info() -> Option<HashMap<String, InfoTypes>>
Retrieves the currently playing media information as a HashMap<String, InfoTypes>
. The function interacts with Apple's CoreFoundation API to extract metadata related to the currently playing media.
-
Returns:
Some(HashMap<String, InfoTypes>)
: If metadata is successfully retrieved.None
: If no metadata is available or retrieval fails.
get_now_playing_client_parent_app_bundle_identifier() -> Option<String>
Retrieves the bundle identifier of the parent app for the current "now playing" client.
-
Returns:
Some(String)
: The bundle identifier of the parent app if successfully retrieved.None
: If the client ID is invalid, the bundle identifier is null, or retrieval fails.
get_now_playing_client_bundle_identifier() -> Option<String>
Retrieves the bundle identifier of the current "now playing" client.
-
Returns:
Some(String)
: The bundle identifier of the client app if successfully retrieved.None
: If the client ID is invalid, the bundle identifier is null, or retrieval fails.
send_command(command: Command) -> bool
Sends a media command to the currently active media client.
-
Arguments:
command
: The Command to be sent, representing an action like play, pause, skip, etc.
-
Returns:
true
: If the command was successfully sent and processed.false
: If the operation failed or the command was not recognized.
-
Notes:
- The
useInfo
argument is not supported by this function and is not used in the current implementation. - If no media is currently playing, this function may open iTunes (or the default media player) to handle the command.
- The
set_playback_speed(speed: i32)
Sets the playback speed of the currently active media client.
-
Arguments:
speed
: The playback speed multiplier.
-
Note:
- Playback speed changes typically do not work most of the time. Depending on the media client or content, setting the playback speed may not have the desired effect.
set_elapsed_time(elapsed_time: f64)
Sets the elapsed time of the currently playing media.
-
Arguments:
elapsed_time
: The elapsed time in seconds to set the current position of the media.
-
Note:
- Setting the elapsed time can often cause the media to pause. Be cautious when using this function, as the playback might be interrupted and require manual resumption.
register_for_now_playing_notifications()
Registers the caller for "Now Playing" notifications.
- Note:
- Must be called before adding observers to ensure notifications are received.
unregister_for_now_playing_notifications()
Unregisters the caller for "Now Playing" notifications.
-
Note:
- Should be called when notifications are no longer needed to free resources.
Helper Functions
add_observer(notification: Notification, closure: F) -> Observer
Adds an observer for a specific media notification.
-
Arguments:
notification
: The Notification type representing the event to observe.closure
: A closure to execute when the notification is received.
-
Returns:
- An Observer handle that can be used to remove the observer later.
-
Note:
register_for_now_playing_notifications()
must be called before using this function, or notifications may not be received.
remove_observer(observer: Observer)
Removes a previously added observer.
-
Arguments:
observer
: The Observer handle returned from add_observer().
get_bundle_info(id: &str) -> Option<BundleInfo>
Retrieves information about an application based on its bundle identifier, including the application's name and icon.
-
Arguments:
id
: A string slice representing the bundle identifier of the application.
-
Returns:
Some(BundleInfo)
: If the application is found, containing the application's name and icon.None
: If the application cannot be found, or if there is an error retrieving the information.
Dependencies
~12MB
~229K SLoC