Hook up mpris artwork

This commit is contained in:
Mike Brady
2018-01-20 16:53:31 +00:00
parent c371aa59fd
commit 6b5a1b39c5
3 changed files with 51 additions and 30 deletions
+35 -26
View File
@@ -32,12 +32,12 @@
#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
// 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.
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) ||
+2
View 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
+14 -4
View 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);