aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--mpd-notification.c69
-rw-r--r--mpd-notification.h6
3 files changed, 74 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 3ac2764..9bb5297 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ RM := rm
CFLAGS += -std=c11 -O2 -Wall -Werror
CFLAGS += $(shell pkg-config --cflags --libs libmpdclient)
CFLAGS += $(shell pkg-config --cflags --libs libnotify)
+CFLAGS += $(shell pkg-config --cflags --libs libavcodec libavformat)
# this is just a fallback in case you do not use git but downloaded
# a release tarball...
VERSION := 0.5.2
diff --git a/mpd-notification.c b/mpd-notification.c
index 1a7dec2..856f8b0 100644
--- a/mpd-notification.c
+++ b/mpd-notification.c
@@ -54,13 +54,71 @@ void received_signal(int signal) {
}
}
+/*** retrieve_album_art ***/
+char * retrieve_album_art(const char *path) {
+ int i, ret = 0;
+ FILE * album_art;
+ char * album_art_file = NULL;
+ AVPacket pkt;
+ AVFormatContext * pFormatCtx = NULL;
+
+ album_art_file = malloc(strlen(PROGNAME) + 15);
+ sprintf(album_art_file, "/tmp/.%s-%d", PROGNAME, getpid());
+
+ pFormatCtx = avformat_alloc_context();
+
+ if (avformat_open_input(&pFormatCtx, path, NULL, NULL) != 0) {
+ printf("avformat_open_input() failed");
+ goto fail;
+ }
+
+ /* only mp3 file contain artwork, so ignore others */
+ if (strcmp(pFormatCtx->iformat->name, "mp3") != 0)
+ goto fail;
+
+ if (pFormatCtx->iformat->read_header(pFormatCtx) < 0) {
+ printf("could not read the format header\n");
+ goto fail;
+ }
+
+ /* find the first attached picture, if available */
+ for (i = 0; i < pFormatCtx->nb_streams; i++) {
+ if (pFormatCtx->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
+ pkt = pFormatCtx->streams[i]->attached_pic;
+ album_art = fopen(album_art_file, "wb");
+ ret = fwrite(pkt.data, pkt.size, 1, album_art);
+ fclose(album_art);
+ break;
+ }
+ }
+
+fail:
+ if (pFormatCtx)
+ avformat_free_context(pFormatCtx);
+
+ if (ret) {
+ return album_art_file;
+ } else {
+ free(album_art_file);
+ return NULL;
+ }
+}
+
/*** get_icon ***/
char * get_icon(const char * music_dir, const char * uri) {
- char * icon = NULL, * uri_dirname;
+ char * icon = NULL, * uri_path = NULL, * uri_dirname = NULL;
DIR * dir;
struct dirent * entry;
regex_t regex;
+ /* try album artwork first */
+ uri_path = malloc(strlen(music_dir) + strlen(uri) + 2);
+ sprintf(uri_path, "%s/%s", music_dir, uri);
+ icon = retrieve_album_art(uri_path);
+
+ if (icon != NULL)
+ goto found;
+
uri_dirname = strdup(uri);
/* cut the dirname or just use "." (string, not char!) for current directory */
@@ -93,7 +151,11 @@ char * get_icon(const char * music_dir, const char * uri) {
regfree(&regex);
closedir(dir);
- free(uri_dirname);
+found:
+ if (uri_path)
+ free(uri_path);
+ if (uri_dirname)
+ free(uri_dirname);
return icon;
}
@@ -164,6 +226,9 @@ int main(int argc, char ** argv) {
}
}
+ /* libav */
+ av_register_all();
+
conn = mpd_connection_new(mpd_host, mpd_port, mpd_timeout);
if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
diff --git a/mpd-notification.h b/mpd-notification.h
index 29cf0f2..c991fd1 100644
--- a/mpd-notification.h
+++ b/mpd-notification.h
@@ -14,6 +14,9 @@
#include <libnotify/notify.h>
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@@ -30,6 +33,9 @@
/*** received_signal ***/
void received_signal(int signal);
+/*** retrieve_album_art ***/
+char * retrieve_album_art(const char *path);
+
/*** get_icon ***/
char * get_icon(const char * music_dir, const char * uri);