diff options
| -rw-r--r-- | Makefile | 17 | ||||
| -rw-r--r-- | README.md | 73 | ||||
| -rw-r--r-- | config.def.h | 4 | ||||
| -rw-r--r-- | mpd-notification.c | 94 | ||||
| -rw-r--r-- | mpd-notification.h | 8 | ||||
| -rw-r--r-- | systemd/Upholds-mpd-notification.conf | 9 | ||||
| -rw-r--r-- | systemd/mpd-notification.service | 2 |
7 files changed, 149 insertions, 58 deletions
@@ -19,13 +19,17 @@ CFLAGS_EXTRA += $(shell pkg-config --cflags --libs libnotify) CFLAGS_LIBAV := $(shell pkg-config --cflags --libs libavformat libavutil 2>/dev/null) ifneq ($(CFLAGS_LIBAV),) CFLAGS_EXTRA += -DHAVE_LIBAV $(CFLAGS_LIBAV) -CFLAGS_EXTRA += -lmagic +CFLAGS_MAGIC := $(shell pkg-config --cflags --libs libmagic 2>/dev/null) +ifneq ($(CFLAGS_MAGIC),) +CFLAGS_EXTRA += -DHAVE_MAGIC $(CFLAGS_MAGIC) +endif endif LDFLAGS += -Wl,-z,now -Wl,-z,relro -pie # this is just a fallback in case you do not use git but downloaded # a release tarball... -VERSION := 0.9.0 +DISTVER := 0.9.3 +VERSION ?= $(shell git describe --long 2>/dev/null || echo $(DISTVER)) all: mpd-notification README.html @@ -36,7 +40,7 @@ config.h: $(CP) config.def.h config.h version.h: $(wildcard .git/HEAD .git/index .git/refs/tags/*) Makefile - printf "#ifndef VERSION\n#define VERSION \"%s\"\n#endif\n" $(shell git describe --long 2>/dev/null || echo ${VERSION}) > $@ + printf "#ifndef VERSION\n#define VERSION \"%s\"\n#endif\n" "$(VERSION)" > $@ README.html: README.md $(MD) README.md > README.html @@ -47,6 +51,7 @@ install-bin: mpd-notification $(INSTALL) -D -m0755 mpd-notification $(DESTDIR)/usr/bin/mpd-notification ifneq ($(CFLAGS_SYSTEMD),) $(INSTALL) -D -m0644 systemd/mpd-notification.service $(DESTDIR)/usr/lib/systemd/user/mpd-notification.service + $(INSTALL) -D -m0644 systemd/Upholds-mpd-notification.conf $(DESTDIR)/usr/lib/systemd/user/mpd.service.d/Upholds-mpd-notification.conf endif install-doc: README.html @@ -62,6 +67,6 @@ distclean: $(RM) -f *.o *~ README.html mpd-notification version.h config.h release: - git archive --format=tar.xz --prefix=mpd-notification-$(VERSION)/ $(VERSION) > mpd-notification-$(VERSION).tar.xz - gpg --armor --detach-sign --comment mpd-notification-$(VERSION).tar.xz mpd-notification-$(VERSION).tar.xz - git notes --ref=refs/notes/signatures/tar add -C $$(git archive --format=tar --prefix=mpd-notification-$(VERSION)/ $(VERSION) | gpg --armor --detach-sign --comment mpd-notification-$(VERSION).tar | git hash-object -w --stdin) $(VERSION) + git archive --format=tar.xz --prefix=mpd-notification-$(DISTVER)/ $(DISTVER) > mpd-notification-$(DISTVER).tar.xz + gpg --armor --detach-sign --comment mpd-notification-$(DISTVER).tar.xz mpd-notification-$(DISTVER).tar.xz + git notes --ref=refs/notes/signatures/tar add -C $$(git archive --format=tar --prefix=mpd-notification-$(DISTVER)/ $(DISTVER) | gpg --armor --detach-sign --comment mpd-notification-$(DISTVER).tar | git hash-object -w --stdin) $(DISTVER) @@ -1,6 +1,10 @@ mpd-notification ================ +[](https://github.com/eworm-de/mpd-notification/stargazers) +[](https://github.com/eworm-de/mpd-notification/network) +[](https://github.com/eworm-de/mpd-notification/watchers) + **Notify about tracks played by mpd** This runs in background and produces notifications whenever mpd produces @@ -15,23 +19,27 @@ This now even supports album artwork: Read below for the details. +*Use at your own risk*, pay attention to +[license and warranty](#license-and-warranty), and +[disclaimer on external links](#disclaimer-on-external-links)! + Requirements ------------ To compile and run `mpd-notification` you need: -* [systemd](https://www.github.com/systemd/systemd) -* [file](https://www.darwinsys.com/file/) for `libmagic` -* [iniparser](https://github.com/ndevilla/iniparser) -* [libav](https://libav.org/) or [ffmpeg](https://www.ffmpeg.org/) -* [libnotify](https://developer.gnome.org/notification-spec/) -* [libmpdclient](https://www.musicpd.org/libs/libmpdclient/) -* [markdown](https://daringfireball.net/projects/markdown/) (HTML documentation) +* [systemd ↗️](https://www.github.com/systemd/systemd) +* [file ↗️](https://www.darwinsys.com/file/) for `libmagic` +* [iniparser ↗️](https://github.com/ndevilla/iniparser) +* [libav ↗️](https://libav.org/) or [ffmpeg ↗️](https://www.ffmpeg.org/) +* [libnotify ↗️](https://developer.gnome.org/notification-spec/) +* [libmpdclient ↗️](https://www.musicpd.org/libs/libmpdclient/) +* [markdown ↗️](https://daringfireball.net/projects/markdown/) (HTML documentation) * `gnome-icon-theme` or `adwaita-icon-theme` (or anything else that includes an icon named `audio-x-generic`) To use `mpd-notification` you probably want `mpd`, the -[music player daemon](http://www.musicpd.org/) itself. ;) +[music player daemon ↗️](https://www.musicpd.org/) itself. ;) Some systems may require additional development packages for the libraries. Look for `libnotify-devel`, `libmpdclient-devel` or similar. @@ -41,11 +49,11 @@ Build and install Building and installing is very easy. Just run: -> make + make followed by: -> make install + make install This will place an executable at `/usr/bin/mpd-notification`, documentation can be found in `/usr/share/doc/mpd-notification/`. @@ -54,11 +62,24 @@ Additionally a systemd unit file is installed to `/usr/lib/systemd/user/`. Usage ----- -Just run `mpd-notification` to run it once. A systemd user service can be -started and/or enabled with `systemctl --user start mpd-notification` -or `systemctl --user enable mpd-notification`. +Nothing special needs to be done when `mpd` is started (or enabled) as +user instance: + + systemctl --user start mpd.service + +It does uphold `mpd-notification.service`, so the service is started +automatically. + +If this does does not apply (for exameple because the system service +`mpd.service` is started) just start it specifically: + + systemctl --user start mpd-notification.service -`mpd-notification` accepts some arguments: +... and/or enable to make it start automatically after login: + + systemctl --user enable mpd-notification.service + +Just run `mpd-notification` to run it once. It accepts some arguments: * *-h*: show help * *-H HOST*: connect to *HOST* @@ -66,8 +87,8 @@ or `systemctl --user enable mpd-notification`. * *--notification-file-workaround*: write artwork to file for notification daemons that do required it * *-p PORT*: connect to *PORT* -* *-s PIXELS*: scale image to a maximum size *PIXELS* x *PIXELS* pixels, keeping - ratio +* *-s PIXELS*: scale image to a maximum size *PIXELS* x *PIXELS* pixels, + keeping ratio * *-t TIMEOUT*: notification timeout, *TIMEOUT* in seconds * *-v*: verbose output * *-V*: print version information @@ -107,7 +128,7 @@ Artwork `mpd-notification` display album artwork you need to tell it where to look for artwork. You can do that by exporting `XDG_MUSIC_DIR` to your environment, by specifying `-m` or `--music-dir` on the command line or by setting `music-dir` -in configuration file. `mpd-notification` reads album artwork from `mp3` +in configuration file. `mpd-notification` reads album artwork from supported files, otherwise an image file containing the artwork needs to be placed in the same directory as the media file and named `cover.jpg`, `cover.png`, `folder.jpg` or `folder.png`. @@ -125,6 +146,21 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [GNU General Public License](COPYING.md) for more details. +Disclaimer on external links +---------------------------- + +Our website contains links to the websites of third parties ("external +links"). As the content of these websites is not under our control, we +cannot assume any liability for such external content. In all cases, the +provider of information of the linked websites is liable for the content +and accuracy of the information provided. At the point in time when the +links were placed, no infringements of the law were recognisable to us. +As soon as an infringement of the law becomes known to us, we will +immediately remove the link in question. + +> 💡️ **Hint**: All external links are marked with an arrow pointing +> diagonally in an up-right (or north-east) direction (↗️). + ### Upstream URL: @@ -133,3 +169,6 @@ URL: Mirror: [eworm.de](https://git.eworm.de/cgit.cgi/mpd-notification/) [GitLab.com](https://gitlab.com/eworm-de/mpd-notification#mpd-notification) + +--- +[⬆️ Go back to top](#top) diff --git a/config.def.h b/config.def.h index b8ef018..e7a1264 100644 --- a/config.def.h +++ b/config.def.h @@ -1,5 +1,5 @@ /* - * (C) 2011-2024 by Christian Hesse <mail@eworm.de> + * (C) 2011-2025 by Christian Hesse <mail@eworm.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ /* this is a regular expression that has to match image filename used * for artwork */ -#define REGEX_ARTWORK "\\(folder\\|cover\\)\\.\\(jpg\\|png\\)" +#define REGEX_ARTWORK "\\(folder\\|cover\\)\\.\\(avif\\|jpg\\|png\\|webp\\)" /* how to connect to mpd host ? * MPD_HOST is the server's host name, IP address or Unix socket path. If the diff --git a/mpd-notification.c b/mpd-notification.c index af8985a..0d18fea 100644 --- a/mpd-notification.c +++ b/mpd-notification.c @@ -1,5 +1,5 @@ /* - * (C) 2011-2024 by Christian Hesse <mail@eworm.de> + * (C) 2011-2025 by Christian Hesse <mail@eworm.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,9 +40,35 @@ NotifyNotification * notification = NULL; struct mpd_connection * conn = NULL; uint8_t doexit = 0; uint8_t verbose = 0; -#ifdef HAVE_LIBAV +#ifdef HAVE_MAGIC magic_t magic = NULL; -#endif +#endif /* HAVE_MAGIC */ + +/* wrapper for sd_notify() to avoid #ifdef */ +static int mpdn_sd_notify(int unset_environment, const char *format, ...) { + int r = 0; + +#ifdef HAVE_SYSTEMD + va_list args; + char *string; + size_t str_len; + + va_start(args, format); + str_len = vsnprintf(NULL, 0, format, args) + 1; + va_end(args); + + string = malloc(str_len); + + va_start(args, format); + vsnprintf(string, str_len, format, args); + va_end(args); + + r = sd_notify(unset_environment, string); + free(string); +#endif /* HAVE_SYSTEMD */ + + return r; +} /*** received_signal ***/ void received_signal(int signal) { @@ -83,9 +109,8 @@ GdkPixbuf * retrieve_artwork(const char * music_dir, const char * uri) { #ifdef HAVE_LIBAV int i; - const char *magic_mime; AVFormatContext * pFormatCtx = NULL; - GdkPixbufLoader * loader; + GdkPixbufLoader * loader = NULL; /* try album artwork first */ if ((uri_path = malloc(strlen(music_dir) + strlen(uri) + 2)) == NULL) { @@ -95,6 +120,9 @@ GdkPixbuf * retrieve_artwork(const char * music_dir, const char * uri) { sprintf(uri_path, "%s/%s", music_dir, uri); +#ifdef HAVE_MAGIC + const char *magic_mime; + if ((magic_mime = magic_file(magic, uri_path)) == NULL) { fprintf(stderr, "%s: We did not get a MIME type...\n", program); goto image; @@ -104,10 +132,13 @@ GdkPixbuf * retrieve_artwork(const char * music_dir, const char * uri) { printf("%s: MIME type for %s is: %s\n", program, uri_path, magic_mime); /* Are there more mime-types supporting embedded artwork? Tell me! */ - if (strcmp(magic_mime, "audio/mp4") != 0 && + if (strcmp(magic_mime, "audio/flac") != 0 && + strcmp(magic_mime, "audio/mp4") != 0 && strcmp(magic_mime, "audio/mpeg") != 0 && + strcmp(magic_mime, "audio/ogg") != 0 && strcmp(magic_mime, "audio/x-m4a") != 0) goto image; +#endif /* HAVE_MAGIC */ if ((pFormatCtx = avformat_alloc_context()) == NULL) { fprintf(stderr, "%s: avformat_alloc_context() failed.\n", program); @@ -134,13 +165,21 @@ GdkPixbuf * retrieve_artwork(const char * music_dir, const char * uri) { fprintf(stderr, "%s: gdk_pixbuf_loader_write() failed parsing buffer.\n", program); goto image; } + + if (gdk_pixbuf_loader_close(loader, NULL) == FALSE) { + fprintf(stderr, "%s: gdk_pixbuf_loader_close() failed.\n", program); + goto image; + } if ((pixbuf = gdk_pixbuf_loader_get_pixbuf(loader)) == NULL) { fprintf(stderr, "%s: gdk_pixbuf_loader_get_pixbuf() failed creating pixbuf.\n", program); goto image; } - gdk_pixbuf_loader_close(loader, NULL); + g_object_ref(pixbuf); + g_object_unref(loader); + loader = NULL; + goto done; } } @@ -149,7 +188,9 @@ GdkPixbuf * retrieve_artwork(const char * music_dir, const char * uri) { printf("%s: No artwork in media file.\n", program); image: -#endif + if (loader) + g_object_unref(loader); +#endif /* HAVE_LIBAV */ /* cut the file name from path for current directory */ *strrchr(uri_path, '/') = 0; @@ -200,7 +241,7 @@ done: avformat_close_input(&pFormatCtx); avformat_free_context(pFormatCtx); } -#endif +#endif /* HAVE_LIBAV */ free(uri_path); @@ -345,10 +386,13 @@ int main(int argc, char ** argv) { printf("%s: %s v%s" #ifdef HAVE_SYSTEMD " +systemd" -#endif +#endif /* HAVE_SYSTEMD */ #ifdef HAVE_LIBAV " +libav" -#endif +#ifdef HAVE_MAGIC + " +libmagic" +#endif /* HAVE_MAGIC */ +#endif /* HAVE_LIBAV */ " (compiled: " __DATE__ ", " __TIME__ ")\n", program, PROGNAME, VERSION); if (help > 0) @@ -407,6 +451,7 @@ int main(int argc, char ** argv) { if (verbose == 0) av_log_set_level(AV_LOG_FATAL); +#ifdef HAVE_MAGIC if ((magic = magic_open(MAGIC_MIME_TYPE)) == NULL) { fprintf(stderr, "%s: Could not initialize magic library.\n", program); goto out40; @@ -417,7 +462,8 @@ int main(int argc, char ** argv) { magic_close(magic); goto out30; } -#endif +#endif /* HAVE_MAGIC */ +#endif /* HAVE_LIBAV */ conn = mpd_connection_new(mpd_host, mpd_port, mpd_timeout * 1000); @@ -450,9 +496,7 @@ int main(int argc, char ** argv) { sigaction(SIGUSR1, &act, NULL); /* report ready to systemd */ -#ifdef HAVE_SYSTEMD - sd_notify(0, "READY=1\nSTATUS=Waiting for mpd event..."); -#endif + mpdn_sd_notify(0, "READY=1\nSTATUS=Waiting for mpd event..."); while (doexit == 0 && mpd_run_idle_mask(conn, MPD_IDLE_PLAYER)) { mpd_command_list_begin(conn, true); @@ -483,9 +527,7 @@ int main(int argc, char ** argv) { if (title == NULL) goto nonotification; -#ifdef HAVE_SYSTEMD - sd_notifyf(0, "READY=1\nSTATUS=%s: %s", state == MPD_STATE_PLAY ? "Playing" : "Paused", title); -#endif + mpdn_sd_notify(0, "READY=1\nSTATUS=%s: %s", state == MPD_STATE_PLAY ? "Playing" : "Paused", title); /* get the formatted notification string */ notifystr = format_text(state == MPD_STATE_PLAY ? text_play : text_pause, @@ -519,9 +561,7 @@ int main(int argc, char ** argv) { mpd_song_free(song); } else if (state == MPD_STATE_STOP) { notifystr = strdup(text_stop); -#ifdef HAVE_SYSTEMD - sd_notifyf(0, "READY=1\nSTATUS=%s", text_stop); -#endif + mpdn_sd_notify(0, "READY=1\nSTATUS=%s", text_stop); } else notifystr = strdup(TEXT_UNKNOWN); @@ -565,9 +605,7 @@ nonotification: printf("%s: Exiting...\n", program); /* report stopping to systemd */ -#ifdef HAVE_SYSTEMD - sd_notify(0, "STOPPING=1\nSTATUS=Stopping..."); -#endif + mpdn_sd_notify(0, "STOPPING=1\nSTATUS=Stopping..."); rc = EXIT_SUCCESS; @@ -580,18 +618,16 @@ out20: mpd_connection_free(conn); out30: -#ifdef HAVE_LIBAV +#ifdef HAVE_MAGIC if (magic != NULL) magic_close(magic); out40: -#endif +#endif /* HAVE_MAGIC */ if (ini != NULL) iniparser_freedict(ini); -#ifdef HAVE_SYSTEMD - sd_notify(0, "STATUS=Stopped. Bye!"); -#endif + mpdn_sd_notify(0, "STATUS=Stopped. Bye!"); return rc; } diff --git a/mpd-notification.h b/mpd-notification.h index d11e822..4068144 100644 --- a/mpd-notification.h +++ b/mpd-notification.h @@ -1,5 +1,5 @@ /* - * (C) 2011-2024 by Christian Hesse <mail@eworm.de> + * (C) 2011-2025 by Christian Hesse <mail@eworm.de> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ /* systemd headers */ #ifdef HAVE_SYSTEMD #include <systemd/sd-daemon.h> -#endif +#endif /* HAVE_SYSTEMD */ #include <iniparser/iniparser.h> #include <libnotify/notify.h> @@ -40,8 +40,10 @@ #ifdef HAVE_LIBAV #include <libavformat/avformat.h> +#ifdef HAVE_MAGIC #include <magic.h> -#endif +#endif /* HAVE_MAGIC */ +#endif /* HAVE_LIBAV */ #include "config.h" #include "version.h" diff --git a/systemd/Upholds-mpd-notification.conf b/systemd/Upholds-mpd-notification.conf new file mode 100644 index 0000000..d84dbff --- /dev/null +++ b/systemd/Upholds-mpd-notification.conf @@ -0,0 +1,9 @@ +# (C) 2025 by Christian Hesse <mail@eworm.de> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +[Unit] +Upholds=mpd-notification.service diff --git a/systemd/mpd-notification.service b/systemd/mpd-notification.service index 61b8f66..6a75da1 100644 --- a/systemd/mpd-notification.service +++ b/systemd/mpd-notification.service @@ -1,4 +1,4 @@ -# (C) 2011-2024 by Christian Hesse <mail@eworm.de> +# (C) 2011-2025 by Christian Hesse <mail@eworm.de> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by |