diff --git a/README.md b/README.md index c142fbb..0c7cef3 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,10 @@ Guides for other distibutions will appear in future. If you know one, feel free ## TODO -- [ ] Add pause command +- [x] Add pause command +- [ ] Add clear playlist command - [ ] Add navigation inside song +- [ ] Add notification support ## Bugs diff --git a/commands.h b/commands.h index 76f5246..7866832 100644 --- a/commands.h +++ b/commands.h @@ -5,6 +5,7 @@ #define LOAD 'l' #define FORWARD 'f' #define BACKWARD 'b' +#define PAUSE 'p' #define NEWLINE '\n' #endif /* __COMMANDS_H__ */ diff --git a/pipeplayer.c b/pipeplayer.c index 9feb6cd..0060be7 100644 --- a/pipeplayer.c +++ b/pipeplayer.c @@ -55,6 +55,7 @@ main(int argc, char *argv[]) // mpg player struct mpg_player player, *player_ptr = &player; player.ao.need_close_device = false; + player.playing = false; // playlist struct playlist playlist = { diff --git a/player.c b/player.c index c319f27..84936f4 100644 --- a/player.c +++ b/player.c @@ -40,10 +40,9 @@ free_player(struct mpg_player *player) } void -play(struct mpg_player *player, const char *path) +prepare_to_play(struct mpg_player *player, const char *path) { - /* Open the file and get the decoding format */ - LOG_INFO("Playing %s", path); + LOG_DEBUG("Preparing to play %s", path); struct audio_output *ao = &player->ao; ao_sample_format *format = &ao->format; @@ -64,6 +63,15 @@ play(struct mpg_player *player, const char *path) format->matrix = 0; ao->device = ao_open_live(ao->driver, format, NULL); ao->need_close_device = true; +} + +void +play(struct mpg_player *player) +{ + /* Open the file and get the decoding format */ + struct audio_output *ao = &player->ao; + + player->playing = true; /* Decode and play */ while (mpg123_read( @@ -71,6 +79,6 @@ play(struct mpg_player *player, const char *path) player->buffer, player->buffer_size, &player->done - ) == MPG123_OK) + ) == MPG123_OK && player->playing) ao_play(ao->device, player->buffer, player->done); } diff --git a/player.h b/player.h index 999c0cd..e4d7e06 100644 --- a/player.h +++ b/player.h @@ -20,11 +20,13 @@ struct mpg_player { char *buffer; size_t buffer_size, done; int error; + bool playing; struct audio_output ao; }; void init_player(struct mpg_player *); void free_player(struct mpg_player *); -void play(struct mpg_player *, const char *path); +void prepare_to_play(struct mpg_player *, const char *path); +void play(struct mpg_player *); #endif /* __PLAYER_H__ */ diff --git a/threads.c b/threads.c index ddf1092..8b00ccf 100644 --- a/threads.c +++ b/threads.c @@ -35,16 +35,35 @@ play_thread(void *vargp) struct mpg_player *player = arg->player; LOG_DEBUG("Starting player thread"); - LOG_DEBUG("playlist->path = %s", playlist->path); + LOG_DEBUG("playlist->path = %s", playlist->path); LOG_DEBUG("playlist->index = %lu", playlist->index); LOG_DEBUG("playlist->length = %lu", playlist->length); + // Play after pause + if (playlist->need_cancel && !player->playing) { + LOG_DEBUG("Continue"); + play(player); + + // If paused again + if (!player->playing) + return 0; + + playlist->index++; + } + playlist->need_cancel = true; - for (; playlist->index < playlist->length; playlist->index++) - play(player, playlist->array[playlist->index]); + for (; playlist->index < playlist->length; playlist->index++) { + prepare_to_play(player, playlist->array[playlist->index]); + play(player); + + // If paused + if (!player->playing) + return 0; + } playlist->need_cancel = false; + player->playing = false; return 0; } @@ -57,8 +76,10 @@ _restart_playlist_thread(struct playlist *playlist, void *vargp) LOG_DEBUG("Killing player thread"); - if (playlist->need_cancel) + if (playlist->need_cancel) { pthread_cancel(*thread_player); + playlist->need_cancel = false; + } pthread_create(thread_player, NULL, play_thread, vargp); } @@ -70,6 +91,8 @@ input_thread(void *vargp) bool run = true; struct thread_arg *arg = (struct thread_arg *)vargp; + struct mpg_player *player = arg->player; + pthread_t *thread_player = arg->thread_player; struct playlist *playlist = arg->playlist; char *pipe_path = arg->pipe_path; @@ -107,6 +130,20 @@ input_thread(void *vargp) _restart_playlist_thread(playlist, vargp); break; + case PAUSE: + LOG_DEBUG("Case: PAUSE"); + // Pause only if playlist need cancel (play something) + if (!playlist->need_cancel) { + LOG_DEBUG("Skip pause"); + break; + } + + if (player->playing) + player->playing = false; + else + pthread_create(thread_player, NULL, play_thread, vargp); + break; + default: fprintf(stderr, "Unknown command: %s\n", command); }