mpdcontrol.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <regex.h>
  5. #include <mpd/client.h>
  6. #define MPDHOST "localhost"
  7. #define MPDPORT 6600
  8. struct mpd_connection *get_conn(){
  9. struct mpd_connection *conn;
  10. conn = mpd_connection_new(MPDHOST, MPDPORT, 1000);
  11. if(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS){
  12. fprintf(stderr, "Could not connect to mpd: %s\n", mpd_connection_get_error_message(conn));
  13. mpd_connection_free(conn);
  14. return NULL;
  15. }
  16. return conn;
  17. }
  18. void mpdchange(const Arg *direction){
  19. struct mpd_connection *conn;
  20. conn = get_conn();
  21. if(conn == NULL){
  22. return;
  23. }
  24. if(direction->i > 0){
  25. mpd_run_next(conn);
  26. }
  27. else{
  28. mpd_run_previous(conn);
  29. }
  30. mpd_connection_free(conn);
  31. }
  32. char *get_regerror(int errcode, regex_t *compiled){
  33. size_t length = regerror(errcode, compiled, NULL, 0);
  34. char *buffer = malloc(length);
  35. (void) regerror(errcode, compiled, buffer, length);
  36. return buffer;
  37. }
  38. void mpdcontrol(){
  39. struct mpd_connection *conn;
  40. struct mpd_status *status;
  41. struct mpd_song *song;
  42. enum mpd_state state;
  43. const char *filename;
  44. regex_t expr;
  45. conn = get_conn();
  46. if(conn == NULL){
  47. return;
  48. }
  49. status = mpd_run_status(conn);
  50. if(status == NULL){
  51. fprintf(stderr, "Could not get mpd status: %s\n", mpd_status_get_error(status));
  52. mpd_status_free(status);
  53. mpd_connection_free(conn);
  54. return;
  55. }
  56. state = mpd_status_get_state(status);
  57. if(state == MPD_STATE_STOP || state == MPD_STATE_PAUSE){
  58. mpd_run_play(conn);
  59. mpd_status_free(status);
  60. mpd_connection_free(conn);
  61. }
  62. else if(state != MPD_STATE_UNKNOWN){ //playing some music
  63. song = mpd_run_current_song(conn);
  64. if(song == NULL){
  65. fprintf(stderr, "Error fetching current song!\n");
  66. mpd_song_free(song);
  67. mpd_status_free(status);
  68. mpd_connection_free(conn);
  69. return;
  70. }
  71. filename = mpd_song_get_uri(song);
  72. int errcode = regcomp(&expr, "^[[:alnum:]]+://", REG_EXTENDED|REG_NOSUB);
  73. if(errcode != 0){
  74. char *err = get_regerror(errcode, &expr);
  75. fprintf(stderr, "Could not compile regexp: %s\n", err);
  76. mpd_song_free(song);
  77. mpd_status_free(status);
  78. mpd_connection_free(conn);
  79. free(err);
  80. regfree(&expr);
  81. return;
  82. }
  83. int matchcode = regexec(&expr, filename, 0, NULL, 0);
  84. if(matchcode == 0){
  85. if(strstr(filename, "file://") == filename){ //match just at the start of the filename
  86. //this means that mpd is playing a file outside the music_dir,
  87. //but on disk, so we can safely pause
  88. mpd_run_toggle_pause(conn);
  89. }
  90. else{
  91. mpd_run_stop(conn);
  92. }
  93. }
  94. else if(matchcode == REG_NOMATCH){
  95. mpd_run_toggle_pause(conn);
  96. }
  97. else{
  98. char *err = get_regerror(matchcode, &expr);
  99. fprintf(stderr, "Error while matching regexp: %s\n", err);
  100. free(err);
  101. }
  102. regfree(&expr);
  103. mpd_song_free(song);
  104. mpd_status_free(status);
  105. mpd_connection_free(conn);
  106. }
  107. }