Created
September 26, 2013 18:05
-
-
Save sahib/6718139 to your computer and use it in GitHub Desktop.
Compile: gcc mpdsonglisten.c -o mpdsonglisten -lmpdclient -std=c99 Run: ./mpdsonglisten localhost 6600 <on_play_script> <on_stop_script>
Example: ./mpdsong localhost 6600 'echo plays!' 'echo stopped!' It will call on_play_script once mpd starts playing,
and on_stop_script once it pauses, stops or does something unknown. Error handling is done by…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Compile: gcc mpdsonglisten.c -o mpdsonglisten -lmpdclient -std=c99 | |
* Run: ./mpdsonglisten localhost 6600 <on_play_script> <on_stop_script> | |
* Example: ./mpdsong localhost 6600 'echo plays!' 'echo stopped!' | |
* | |
* It will call on_play_script once mpd starts playing, | |
* and on_stop_script once it pauses, stops or does something unknown. | |
* | |
* Error handling is done by ignoring none-fatal erros and trying to reconnect if | |
* fatal errors happen. | |
* */ | |
#include <mpd/client.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <signal.h> | |
#include <stdio.h> | |
static volatile bool not_ctrlc_pressed = true; | |
static bool check_error(struct mpd_connection * client) | |
{ | |
if(mpd_connection_get_error(client) != MPD_ERROR_SUCCESS) { | |
printf("Error: %s (Retry in 1 second...)\n", mpd_connection_get_error_message(client)); | |
if(!mpd_connection_clear_error(client)) { | |
mpd_connection_free(client); | |
sleep(1); | |
return true; | |
} | |
} | |
return (client == NULL); | |
} | |
static struct mpd_connection * connect(const char * host, unsigned port) | |
{ | |
struct mpd_connection * client = NULL; | |
for(;;) { | |
client = mpd_connection_new(host, port, 2000); | |
if(check_error(client)) { | |
continue; | |
} | |
break; | |
} | |
return client; | |
} | |
void cancel_signal(int signal) | |
{ | |
if(signal == SIGINT) { | |
not_ctrlc_pressed = false; | |
} | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
if (argc < 3) { | |
printf("Usage: prog <hostname> <port>"); | |
return EXIT_FAILURE; | |
} | |
int previous_sond_id = -1; | |
enum mpd_state prev_state = MPD_STATE_UNKNOWN; | |
struct mpd_connection * client = connect(argv[1], strtol(argv[2], NULL, 10)); | |
signal(SIGINT, cancel_signal); | |
while(not_ctrlc_pressed) { | |
enum mpd_idle events = mpd_run_idle (client); | |
if(check_error(client)) { | |
client = connect(argv[1], strtol(argv[2], NULL, 10)); | |
continue; | |
} | |
if (events & MPD_IDLE_PLAYER) { | |
struct mpd_status * status = mpd_run_status(client); | |
if (status != NULL) { | |
enum mpd_state play_state = mpd_status_get_state(status); | |
int current_song_id = mpd_status_get_song_id(status); | |
switch(play_state) { | |
case MPD_STATE_PLAY: | |
if (current_song_id != previous_sond_id && prev_state != play_state) { | |
previous_sond_id = current_song_id; | |
if (argc > 3) | |
system(argv[3]); | |
} | |
break; | |
case MPD_STATE_UNKNOWN: | |
case MPD_STATE_PAUSE: | |
case MPD_STATE_STOP: | |
previous_sond_id = -1; | |
if (argc > 4) | |
system(argv[4]); | |
break; | |
} | |
prev_state = play_state; | |
} | |
} | |
} | |
if(client != NULL) { | |
mpd_connection_free(client); | |
} | |
return EXIT_SUCCESS; | |
} |
Debian users will have to install libmpdclient-dev
in order to be able to build :
sudo apt-get install libmpdclient-dev
Also, you can use a systemd user unit to start this on boot :
systemctl --user --force --full edit mpdlisten.service
[Unit]
Description=Run a script when mpd playback toggles
[Service]
Environment=MPD_HOST=localhost
Environment=MPD_PORT=6600
ExecStart=/home/%u/.local/bin/mpdlisten $MPD_HOST $MPD_PORT 'echo plays!' 'echo stopped!'
Type=simple
[Install]
WantedBy=default.target
Edit the Environment and Exec path according to your setup.
Then
systemctl --user daemon-reload
systemctl --user enable mpdlisten.service
systemctl --user start mpdlisten.service
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, I'm using your MPD client in a set up. As a practice of documentation, I'm documenting the process here:
https://hedenberg.org/carsetup/
Is it OK that I keep a copy of your source code on my server, and have it publicly available? I don't expect huge, or any traffic. I have an attribution linking to this page at the end of the document. It's not clear to me under which license the above is published.
It does what It's supposed to. Thank you for writing it!