From: Mike Brady Date: Sat, 20 Jan 2018 16:53:31 +0000 (+0000) Subject: Hook up mpris artwork X-Git-Tag: 3.2d29~104 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6b5a1b39c5a5afd7e6830b01ba0fa56b70927d81;p=thirdparty%2Fshairport-sync.git Hook up mpris artwork --- diff --git a/metadata_hub.c b/metadata_hub.c index 7a03888b..48db3cd2 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -32,12 +32,12 @@ #include #include +#include #include #include #include #include #include -#include #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) || diff --git a/metadata_hub.h b/metadata_hub.h index 0c5ae024..29d8541c 100644 --- a/metadata_hub.h +++ b/metadata_hub.h @@ -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 diff --git a/mpris-service.c b/mpris-service.c index 218c2e32..abb5e70d 100644 --- a/mpris-service.c +++ b/mpris-service.c @@ -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);