forked from paulbarbu/mpdcontrol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmpdcontrol.c
executable file
·147 lines (118 loc) · 3.64 KB
/
mpdcontrol.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <regex.h>
#include <mpd/client.h>
#define MPDHOST "127.0.0.1"
#define MPDPORT 0
/**
* Aquire a connection to the MPD daemon
*
* @return a pointer to struct mpd_connection if successfully connected, or NULL
* otherwise
*/
struct mpd_connection *get_conn(){
struct mpd_connection *conn;
conn = mpd_connection_new(MPDHOST, MPDPORT, 1000);
if(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS){
fprintf(stderr, "Could not connect to mpd: %s\n", mpd_connection_get_error_message(conn));
mpd_connection_free(conn);
return NULL;
}
return conn;
}
/**
* Get the error string from the regex library
*
* @param errcode the error code (as returned by regexec or regcomp)
* for which to fetch the error string
* @param compiled the compiled regex
*
* @return a pointer to char representing the error string
*/
char *get_regerror(int errcode, regex_t *compiled){
size_t length = regerror(errcode, compiled, NULL, 0);
char *buffer = malloc(length);
(void) regerror(errcode, compiled, buffer, length);
return buffer;
}
/**
* Control the MPD daemon
*
* If no music is playing (stopped or paused), play some
* If the music is playing, either pause it (if the file played is on disk) or
* stop it (if it's a stream, since it makes no sense to pause a stream)
*/
void mpdcontrol(){
struct mpd_connection *conn;
struct mpd_status *status;
struct mpd_song *song;
enum mpd_state state;
const char *filename;
regex_t expr;
conn = get_conn();
if(conn == NULL){
return;
}
status = mpd_run_status(conn);
if(status == NULL){
fprintf(stderr, "Could not get mpd status: %s\n", mpd_status_get_error(status));
mpd_status_free(status);
mpd_connection_free(conn);
return;
}
state = mpd_status_get_state(status);
if(state == MPD_STATE_STOP || state == MPD_STATE_PAUSE){
mpd_run_play(conn);
mpd_status_free(status);
mpd_connection_free(conn);
}
else if(state != MPD_STATE_UNKNOWN){ //playing some music
song = mpd_run_current_song(conn);
if(song == NULL){
fprintf(stderr, "Error fetching current song!\n");
mpd_song_free(song);
mpd_status_free(status);
mpd_connection_free(conn);
return;
}
filename = mpd_song_get_uri(song);
int errcode = regcomp(&expr, "^[[:alnum:]]+://", REG_EXTENDED|REG_NOSUB);
if(errcode != 0){
char *err = get_regerror(errcode, &expr);
fprintf(stderr, "Could not compile regexp: %s\n", err);
mpd_song_free(song);
mpd_status_free(status);
mpd_connection_free(conn);
free(err);
regfree(&expr);
return;
}
int matchcode = regexec(&expr, filename, 0, NULL, 0);
if(matchcode == 0){
if(strstr(filename, "mp3")){ //mp3 at the end of the filename
//means that mpd is playing a file that we can safely pause
mpd_run_toggle_pause(conn);
}
else{
mpd_run_stop(conn);
}
}
else if(matchcode == REG_NOMATCH){
mpd_run_toggle_pause(conn);
}
else{
char *err = get_regerror(matchcode, &expr);
fprintf(stderr, "Error while matching regexp: %s\n", err);
free(err);
}
regfree(&expr);
mpd_song_free(song);
mpd_status_free(status);
mpd_connection_free(conn);
}
}
int main(){
mpdcontrol();
return 0;
}