191 lines
4.3 KiB
C
191 lines
4.3 KiB
C
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
|
|
#include "commands.h"
|
|
#include "playlist.h"
|
|
#include "player.h"
|
|
#include "log.h"
|
|
#include "threads.h"
|
|
#include "pipe.h"
|
|
#include "config.h"
|
|
|
|
#if NOTIFICATION == 1
|
|
#include "notify.h"
|
|
#endif
|
|
|
|
void
|
|
run_threads(struct mpg_player *player, struct playlist *playlist, char *pipe_path)
|
|
{
|
|
pthread_t thread_player = {0}, thread_handler = {0};
|
|
|
|
struct thread_arg arg = {
|
|
.player = player,
|
|
.playlist = playlist,
|
|
.pipe_path = pipe_path,
|
|
.thread_player = &thread_player
|
|
};
|
|
|
|
pthread_create(&thread_handler, NULL, input_thread, (void *)&arg);
|
|
pthread_join(thread_handler, NULL);
|
|
}
|
|
|
|
void *
|
|
play_thread(void *vargp)
|
|
{
|
|
struct thread_arg *arg = (struct thread_arg *)vargp;
|
|
struct playlist *playlist = arg->playlist;
|
|
struct mpg_player *player = arg->player;
|
|
char *current;
|
|
|
|
LOG_DEBUG("Starting player thread");
|
|
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++) {
|
|
current = playlist->array[playlist->index];
|
|
prepare_to_play(player, current);
|
|
LOG_INFO("Playing %s", current);
|
|
#if NOTIFICATION == 1
|
|
notify(playlist->names_array[playlist->index]);
|
|
#endif
|
|
play(player);
|
|
|
|
// If paused
|
|
if (!player->playing)
|
|
return 0;
|
|
}
|
|
|
|
free_playlist(playlist);
|
|
playlist->need_cancel = false;
|
|
player->playing = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
_restart_playlist_thread(struct playlist *playlist, void *vargp)
|
|
{
|
|
struct thread_arg *arg = (struct thread_arg *)vargp;
|
|
pthread_t *thread_player = arg->thread_player;
|
|
|
|
LOG_DEBUG("Killing player thread");
|
|
|
|
if (playlist->need_cancel) {
|
|
pthread_cancel(*thread_player);
|
|
playlist->need_cancel = false;
|
|
}
|
|
pthread_create(thread_player, NULL, play_thread, vargp);
|
|
}
|
|
|
|
void *
|
|
input_thread(void *vargp)
|
|
{
|
|
size_t length;
|
|
char *command, **command_ptr = (char **) malloc(sizeof(char *));
|
|
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;
|
|
|
|
while (run) {
|
|
length = pipe_readline(command_ptr, pipe_path);
|
|
command = *command_ptr;
|
|
LOG_DEBUG("Command: %s", command);
|
|
|
|
switch (*command) {
|
|
case EXIT:
|
|
case EOF:
|
|
LOG_DEBUG("Case: EXIT | EOF");
|
|
if (playlist->need_cancel)
|
|
pthread_cancel(*arg->thread_player);
|
|
run = false;
|
|
break;
|
|
|
|
case LOAD:
|
|
LOG_DEBUG("Case: LOAD");
|
|
playlist->path = malloc(length);
|
|
strcpy(playlist->path, command + 1);
|
|
load_playlist(playlist);
|
|
_restart_playlist_thread(playlist, vargp);
|
|
break;
|
|
|
|
|
|
// Only when playlist is loaded
|
|
case CLEAR:
|
|
LOG_DEBUG("Case: CLEAR");
|
|
|
|
if (!playlist->need_cancel)
|
|
break;
|
|
free_playlist(playlist);
|
|
pthread_cancel(*thread_player);
|
|
playlist->need_cancel = false;
|
|
break;
|
|
|
|
case FORWARD:
|
|
LOG_DEBUG("Case: FORWARD");
|
|
|
|
if (!playlist->need_cancel)
|
|
break;
|
|
|
|
playlist->index = (playlist->index + 1) % playlist->length;
|
|
_restart_playlist_thread(playlist, vargp);
|
|
break;
|
|
|
|
case BACKWARD:
|
|
LOG_DEBUG("Case: BACKWARD");
|
|
|
|
if (!playlist->need_cancel)
|
|
break;
|
|
|
|
playlist->index = (playlist->index + playlist->length - 1) % playlist->length;
|
|
_restart_playlist_thread(playlist, vargp);
|
|
break;
|
|
|
|
case PAUSE:
|
|
LOG_DEBUG("Case: PAUSE");
|
|
|
|
if (!playlist->need_cancel)
|
|
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);
|
|
}
|
|
|
|
// Clear command
|
|
if (command != NULL)
|
|
free(command);
|
|
}
|
|
|
|
// Clear command pointer
|
|
free(command_ptr);
|
|
|
|
return 0;
|
|
}
|