]> git.r.bdr.sh - rbdr/lyricli/blobdiff - src/sources/apple_music.rs
Add macos sources
[rbdr/lyricli] / src / sources / apple_music.rs
diff --git a/src/sources/apple_music.rs b/src/sources/apple_music.rs
new file mode 100644 (file)
index 0000000..cb36f5c
--- /dev/null
@@ -0,0 +1,71 @@
+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(())
+    }
+}
+
+