Initial commit
This commit is contained in:
commit
5ec151409e
11
Makefile
Normal file
11
Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
CC = gcc
|
||||
CFLAGS = -g -Wall
|
||||
LDLIBS=-lpthread -lmpdclient
|
||||
|
||||
OBJECTS = mpd_control.o
|
||||
mpd_control: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
clean:
|
||||
rm $(OBJECTS)
|
||||
rm mpd_control
|
19
PKGBUILD
Normal file
19
PKGBUILD
Normal file
@ -0,0 +1,19 @@
|
||||
pkgname=mpd_control
|
||||
pkgver=0.0.1
|
||||
pkgrel=1
|
||||
pkgdesc="An i3blocks blocklet for MPD"
|
||||
arch=('i686' 'x86_64')
|
||||
license=('MIT')
|
||||
depends=('libmpdclient')
|
||||
source=("Makefile" "mpd_control.c")
|
||||
sha256sums=('d75fcdd75f83daec43912d6ef243974b181ea9fe98ba2c43160b9e1541abb283'
|
||||
'fd0383ecc78b393bcb09f6666c3dff20846bf7be047ae7a20f612a84bb9e57fd')
|
||||
provides=('mpd_control')
|
||||
|
||||
build() {
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
install -Dm755 mpd_control ${pkgdir}/usr/bin/mpd_control
|
||||
}
|
180
mpd_control.c
Normal file
180
mpd_control.c
Normal file
@ -0,0 +1,180 @@
|
||||
#include <mpd/client.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct worker_meta {
|
||||
long long update_interval;
|
||||
bool stop;
|
||||
};
|
||||
|
||||
static long long
|
||||
current_timestamp() {
|
||||
struct timeval te;
|
||||
gettimeofday(&te, NULL);
|
||||
return te.tv_sec*1000LL + te.tv_usec/1000;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_error(struct mpd_connection *c)
|
||||
{
|
||||
assert(mpd_connection_get_error(c) != MPD_ERROR_SUCCESS);
|
||||
|
||||
fprintf(stderr, "%s\n", mpd_connection_get_error_message(c));
|
||||
mpd_connection_free(c);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_tag(struct mpd_song *song, char *tag, enum mpd_tag_type type)
|
||||
{
|
||||
const char *value;
|
||||
unsigned i = 0;
|
||||
while ((value = mpd_song_get_tag(song, type, i++)) != NULL) {
|
||||
strcpy(tag, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
print_status(struct mpd_connection *conn)
|
||||
{
|
||||
struct mpd_status *status;
|
||||
struct mpd_song *song;
|
||||
|
||||
mpd_command_list_begin(conn, true);
|
||||
mpd_send_status(conn);
|
||||
mpd_send_current_song(conn);
|
||||
mpd_command_list_end(conn);
|
||||
|
||||
status = mpd_recv_status(conn);
|
||||
if (status == NULL)
|
||||
return handle_error(conn);
|
||||
|
||||
const enum mpd_state state = mpd_status_get_state(status);
|
||||
|
||||
const bool repeat = mpd_status_get_repeat(status);
|
||||
const bool random = mpd_status_get_random(status);
|
||||
|
||||
const unsigned queue_pos = mpd_status_get_song_pos(status);
|
||||
const unsigned queue_length = mpd_status_get_queue_length(status);
|
||||
const unsigned elapsed = mpd_status_get_elapsed_time(status);
|
||||
const unsigned remaining = mpd_status_get_total_time(status) - elapsed;
|
||||
const unsigned remaining_mins = remaining / 60;
|
||||
const unsigned remaining_secs = remaining % 60;
|
||||
|
||||
mpd_status_free(status);
|
||||
if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS)
|
||||
return handle_error(conn);
|
||||
|
||||
mpd_response_next(conn);
|
||||
|
||||
char artist[256];
|
||||
char album[256];
|
||||
char title[256];
|
||||
|
||||
while ((song = mpd_recv_song(conn)) != NULL) {
|
||||
get_tag(song, artist, MPD_TAG_ARTIST);
|
||||
get_tag(song, album, MPD_TAG_ALBUM);
|
||||
get_tag(song, title, MPD_TAG_TITLE);
|
||||
mpd_song_free(song);
|
||||
}
|
||||
|
||||
if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS ||
|
||||
!mpd_response_finish(conn))
|
||||
return handle_error(conn);
|
||||
|
||||
char *play_icon;
|
||||
if (state == MPD_STATE_PLAY) {
|
||||
play_icon = "";
|
||||
} else if (state == MPD_STATE_PAUSE) {
|
||||
play_icon = "";
|
||||
} else {
|
||||
play_icon = "";
|
||||
}
|
||||
|
||||
char state_icon[16];
|
||||
strcpy(state_icon, "");
|
||||
if (repeat)
|
||||
strcat(state_icon, " ");
|
||||
if (random)
|
||||
strcat(state_icon, " ");
|
||||
|
||||
if (state == MPD_STATE_PLAY || state == MPD_STATE_PAUSE)
|
||||
printf("%s%s %s - %s (-%u:%02u) [%u/%u]\n",
|
||||
play_icon, state_icon, artist, title,
|
||||
remaining_mins, remaining_secs,
|
||||
queue_pos+1, queue_length);
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
status_loop(void* worker_meta)
|
||||
{
|
||||
struct worker_meta *meta = (struct worker_meta*)worker_meta;
|
||||
struct mpd_connection *conn = mpd_connection_new(NULL, 0, 0);
|
||||
|
||||
for (;;) {
|
||||
if (meta->stop) {
|
||||
break;
|
||||
}
|
||||
|
||||
long long start = current_timestamp();
|
||||
print_status(conn);
|
||||
usleep((meta->update_interval - (current_timestamp() - start)) * 1000);
|
||||
}
|
||||
|
||||
mpd_connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct worker_meta meta = {950, false};
|
||||
|
||||
pthread_t update_thread;
|
||||
if(pthread_create(&update_thread, NULL, status_loop, &meta)) {
|
||||
fprintf(stderr, "Error creating thread\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
char *line;
|
||||
size_t size;
|
||||
|
||||
if (getline(&line, &size, stdin) != -1) {
|
||||
struct mpd_connection *conn = mpd_connection_new(NULL, 0, 0);
|
||||
if (strcmp(line, "1\n") == 0) {
|
||||
mpd_run_previous(conn);
|
||||
} else if (strcmp(line, "2\n") == 0) {
|
||||
mpd_run_toggle_pause(conn);
|
||||
} else if (strcmp(line, "3\n") == 0) {
|
||||
mpd_run_next(conn);
|
||||
} else if (strcmp(line, "4\n") == 0) {
|
||||
mpd_run_seek_current(conn, 3, true);
|
||||
} else if (strcmp(line, "5\n") == 0) {
|
||||
mpd_run_seek_current(conn, -3, true);
|
||||
} else {
|
||||
// ignore unrecognized input
|
||||
continue;
|
||||
}
|
||||
print_status(conn);
|
||||
mpd_connection_free(conn);
|
||||
}
|
||||
}
|
||||
|
||||
if(pthread_join(update_thread, NULL)) {
|
||||
fprintf(stderr, "Error joining thread\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user