Skip to content

Instantly share code, notes, and snippets.

@sahib
Created September 26, 2013 18:05
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sahib/6718139 to your computer and use it in GitHub Desktop.
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…
/*
* 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;
}
@FnasBas
Copy link

FnasBas commented Aug 2, 2018

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!

@ABelliqueux
Copy link

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