--- /dev/null
+use std::ffi::CStr;
+use std::io::Result;
+
+use cocoa::{base::nil, foundation::NSString};
+use objc::{class, msg_send, sel, sel_impl, runtime::Object};
+use objc_id::Id;
+
+use crate::Track;
+
+use super::LyricsSource;
+
+pub struct AppleMusic;
+
+impl AppleMusic {
+ pub fn new() -> Self {
+ AppleMusic
+ }
+}
+
+impl LyricsSource for AppleMusic {
+
+ fn name(&self) -> String {
+ "apple_music".to_string()
+ }
+
+ fn current_track(&self) -> Option<Track> {
+ unsafe {
+ let app: Id<Object> = {
+ let cls = class!(SBApplication);
+ let bundle_identifier = NSString::alloc(nil).init_str("com.apple.Music");
+ let app: *mut Object = msg_send![cls, applicationWithBundleIdentifier:bundle_identifier];
+ Id::from_ptr(app)
+ };
+
+ if msg_send![app, isRunning] {
+ let current_track: *mut Object = msg_send![app, currentTrack];
+ if !current_track.is_null() {
+ let name_raw: *mut Object = msg_send![current_track, name];
+ let artist_raw: *mut Object = msg_send![current_track, artist];
+
+ let name_ptr: *const i8 = msg_send![name_raw, UTF8String];
+ let artist_ptr: *const i8 = msg_send![artist_raw, UTF8String];
+
+ let name = CStr::from_ptr(name_ptr).to_string_lossy().into_owned();
+ let artist = CStr::from_ptr(artist_ptr).to_string_lossy().into_owned();
+
+
+ return Some(Track {
+ name,
+ artist
+ })
+ }
+ }
+ }
+ None
+ }
+
+ fn disable(&self) -> Result<()> {
+ Ok(())
+ }
+
+ fn enable(&self) -> Result<()> {
+ Ok(())
+ }
+
+ fn reset(&self) -> Result<()> {
+ Ok(())
+ }
+}
+
+