diff options
author | Christian Hesse <mail@eworm.de> | 2015-04-21 11:21:55 +0200 |
---|---|---|
committer | Christian Hesse <mail@eworm.de> | 2015-04-21 11:21:55 +0200 |
commit | 53787fc71e98f49cdae4fa8ceddc7b2182649abc (patch) | |
tree | a149c25cc8887cd13c0d7f0e7388b01ef0a05578 | |
parent | 5d06cc4834d3bf7b1431973617aaea5cc0c9498a (diff) | |
download | mpd-notification-53787fc71e98f49cdae4fa8ceddc7b2182649abc.tar.gz mpd-notification-53787fc71e98f49cdae4fa8ceddc7b2182649abc.tar.zst |
use libav/ffmpeg to get artwork from mp3 files
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | mpd-notification.c | 69 | ||||
-rw-r--r-- | mpd-notification.h | 6 |
3 files changed, 74 insertions, 2 deletions
@@ -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(®ex); 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); |