]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Hook up mpris artwork
authorMike Brady <mikebrady@eircom.net>
Sat, 20 Jan 2018 16:53:31 +0000 (16:53 +0000)
committerMike Brady <mikebrady@eircom.net>
Sat, 20 Jan 2018 16:53:31 +0000 (16:53 +0000)
metadata_hub.c
metadata_hub.h
mpris-service.c

index 7a03888b2fe61632952ab50cc7a9d99b0be2bf87..48db3cd2ba5c6e72d9e3273236a7670706e636ce 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <dirent.h>
 
 #include "config.h"
 
@@ -83,9 +83,13 @@ void run_metadata_watchers(void) {
   }
 }
 
-void metadata_write_image_file(const char *buf, int len) {
+char *metadata_write_image_file(const char *buf, int len) {
+
+  // warning -- this removes all files from the directory apart from this one, if it exists
+  // it will return a path to the image file allocated with malloc.
+  // free it if you don't need it.
 
-// warning -- this removes all files from the directory apart from this one, if it exists
+  char *path = NULL; // this will be what is returned
 
   uint8_t img_md5[16];
 // uint8_t ap_md5[16];
@@ -131,7 +135,6 @@ void metadata_write_image_file(const char *buf, int len) {
 
   int result = mkpath(config.cover_art_cache_dir, 0700);
   if ((result == 0) || (result == -EEXIST)) {
-    debug(1, "Cover art cache directory okay");
     // see if the file exists by opening it.
     // if it exists, we're done
     char *prefix = "cover-";
@@ -139,60 +142,63 @@ void metadata_write_image_file(const char *buf, int len) {
     size_t pl = strlen(config.cover_art_cache_dir) + 1 + strlen(prefix) + strlen(img_md5_str) + 1 +
                 strlen(ext);
 
-  
-    char *path = malloc(pl + 1);
+    path = malloc(pl + 1);
     snprintf(path, pl + 1, "%s/%s%s.%s", config.cover_art_cache_dir, prefix, img_md5_str, ext);
+
     int cover_fd = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
     if (cover_fd > 0) {
       // write the contents
       if (write(cover_fd, buf, len) < len) {
         warn("Writing cover art file \"%s\" failed!", path);
+        free(path);
+        path = NULL;
       }
       close(cover_fd);
-      free(path);
 
       // now delete all other files, if there are any
       DIR *d;
       struct dirent *dir;
       d = opendir(config.cover_art_cache_dir);
       if (d) {
-        int fnl = strlen(prefix)+strlen(img_md5_str)+1+strlen(ext)+1;
-        
+        int fnl = strlen(prefix) + strlen(img_md5_str) + 1 + strlen(ext) + 1;
+
         char *full_filename = malloc(fnl);
-        if (full_filename==NULL)
+        if (full_filename == NULL)
           die("Can't allocate memory at metadata_write_image_file.");
-        memset(full_filename,0,fnl);
+        memset(full_filename, 0, fnl);
         snprintf(full_filename, fnl, "%s%s.%s", prefix, img_md5_str, ext);
-        debug(1,"Full filename is \"%s\".",full_filename);
         int dir_fd = open(config.cover_art_cache_dir, O_DIRECTORY);
-        if (dir_fd>0) {
+        if (dir_fd > 0) {
           while ((dir = readdir(d)) != NULL) {
             if (dir->d_type == DT_REG) {
-              if(strcmp(full_filename,dir->d_name)!=0) {
-                debug(1,"Deleting file \"%s\".",dir->d_name);
-                if (unlinkat(dir_fd, dir->d_name, 0)!=0) {
-                  debug(1,"Error %d deleting cover art file \"%s\".",errno,dir->d_name);
+              if (strcmp(full_filename, dir->d_name) != 0) {
+                if (unlinkat(dir_fd, dir->d_name, 0) != 0) {
+                  debug(1, "Error %d deleting cover art file \"%s\".", errno, dir->d_name);
                 }
-              }           
+              }
             }
           }
         } else {
-          debug(1,"Can't open the directory for deletion.");
+          debug(1, "Can't open the directory for deletion.");
         }
         free(full_filename);
         closedir(d);
-      }      
+      }
     } else {
-      if (errno == EEXIST)
-        debug(1, "Cover art file \"%s\" already exists!", path);
-      else
+      //      if (errno == EEXIST)
+      //        debug(1, "Cover art file \"%s\" already exists!", path);
+      //      else {
+      if (errno != EEXIST) {
         warn("Could not open file \"%s\" for writing cover art", path);
-      free(path);
+        free(path);
+        path = NULL;
+      }
     }
   } else {
     debug(1, "Couldn't access or create the cover art cache directory \"%s\".",
           config.cover_art_cache_dir);
   }
+  return path;
 }
 
 void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uint32_t length) {
@@ -298,8 +304,11 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
     break;
   case 'PICT':
     debug(1, "MH Picture received, length %u bytes.", length);
-    if (length > 16)
-      metadata_write_image_file(data, length);
+    if (length > 16) {
+      if (metadata_store.cover_art_pathname)
+        free(metadata_store.cover_art_pathname);
+      metadata_store.cover_art_pathname = metadata_write_image_file(data, length);
+    }
     break;
   case 'clip':
     if ((metadata_store.client_ip == NULL) ||
index 0c5ae0248c467d9311543d78fd3f5882542f4f3e..29d8541c06c83a9adf612b0e11e6a11af3165d5f 100644 (file)
@@ -74,6 +74,8 @@ typedef struct metadata_bundle {
   unsigned char
       item_composite_id[16]; // seems to be nowplaying 4 ids: dbid, plid, playlistItem, itemid
 
+  char *cover_art_pathname; // if non-zero, it will have been assigned with malloc.
+
   //
 
   enum play_status_type
index 218c2e32aa755d294cdaade0324cf81babebaa93..abb5e70dd448df20e8f1ad6b9d62ad4ba9061195 100644 (file)
@@ -33,7 +33,7 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, void *userdata) {
   media_player2_player_set_loop_status(mprisPlayerPlayerSkeleton, response);
 
   GVariantBuilder *dict_builder, *aa;
-  GVariant *trackname, *albumname, *trackid, *tracklength;
+  GVariant *trackname, *albumname, *trackid, *tracklength, *artUrl;
 
   // Build the Track ID from the 16-byte item_composite_id in hex prefixed by
   // /org/gnome/ShairportSync
@@ -48,6 +48,7 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, void *userdata) {
   *pt = 0;
   // debug(1, "Item composite ID set to 0x%s.", st);
 
+  char artURIstring[1024];
   char trackidstring[1024];
   sprintf(trackidstring, "/org/gnome/ShairportSync/%s", st);
 
@@ -61,7 +62,7 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, void *userdata) {
 
   uint64_t track_length_in_microseconds = argc->songtime_in_milliseconds;
 
-  track_length_in_microseconds *= 1000; // to micorseconds in 64-bit precision
+  track_length_in_microseconds *= 1000; // to microseconds in 64-bit precision
 
   // Make up the track name and album name
   tracklength = g_variant_new("x", track_length_in_microseconds);
@@ -83,12 +84,21 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, void *userdata) {
   /* Build the metadata array */
   // debug(1,"Build metadata");
   dict_builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+  // Make up the artwork URI if we have one
+  if (argc->cover_art_pathname)
+    sprintf(artURIstring, "file://%s", argc->cover_art_pathname);
+  else
+    artURIstring[0] = 0;
+  // sprintf(artURIstring,"");
+  artUrl = g_variant_new("s", artURIstring);
+  g_variant_builder_add(dict_builder, "{sv}", "mpris:artUrl", artUrl);
+  g_variant_builder_add(dict_builder, "{sv}", "mpris:trackid", trackid);
+  g_variant_builder_add(dict_builder, "{sv}", "mpris:length", tracklength);
+
   g_variant_builder_add(dict_builder, "{sv}", "xesam:title", trackname);
   g_variant_builder_add(dict_builder, "{sv}", "xesam:album", albumname);
   g_variant_builder_add(dict_builder, "{sv}", "xesam:artist", artists);
   g_variant_builder_add(dict_builder, "{sv}", "xesam:genre", genres);
-  g_variant_builder_add(dict_builder, "{sv}", "xesam:trackid", trackid);
-  g_variant_builder_add(dict_builder, "{sv}", "xesam:length", tracklength);
   GVariant *dict = g_variant_builder_end(dict_builder);
   g_variant_builder_unref(dict_builder);