summaryrefslogtreecommitdiff
path: root/src/fruits
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2023-11-11 17:51:49 -0500
committerAndrew Opalach <andrew@akon.city> 2023-11-11 17:51:49 -0500
commit7e5043a2505efa383ae372662fa4849051cd9799 (patch)
treee7736218b7ab323579a440f24d899ed00beb9f73 /src/fruits
parent113eb3b481417364f84350e90be252355d807f06 (diff)
downloadcamu-7e5043a2505efa383ae372662fa4849051cd9799.tar.gz
camu-7e5043a2505efa383ae372662fa4849051cd9799.tar.bz2
camu-7e5043a2505efa383ae372662fa4849051cd9799.zip
Improve basic cmv usage
- Make cap more robust - Disable ECHO in the TUI - Improve youtube playback url selection - Some cleanup Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/fruits')
-rw-r--r--src/fruits/cap/cap.c87
-rw-r--r--src/fruits/cap/cap.h7
-rw-r--r--src/fruits/cmv/cmv2.c13
-rw-r--r--src/fruits/cmv/tui.c14
-rw-r--r--src/fruits/cmv/tui.h5
5 files changed, 84 insertions, 42 deletions
diff --git a/src/fruits/cap/cap.c b/src/fruits/cap/cap.c
index 2f60cb4..e1d9e13 100644
--- a/src/fruits/cap/cap.c
+++ b/src/fruits/cap/cap.c
@@ -36,28 +36,25 @@ static struct cch_entry *entry_for_unique_id(str *unique_id)
#if CAP_USE_PYTHON
struct sho_search s;
sho_search_init(&s);
+ str query;
+ al_str_from(&query, "");
if (al_str_cmp(unique_id, al_str_c("https://twitter.com"), 0, 19) == 0 ||
al_str_cmp(unique_id, al_str_c("https://x.com"), 0, 13) == 0) {
- str query;
- al_str_from(&query, "tweet:");
+ al_str_cat(&query, al_str_c("tweet:"));
al_str_cat(&query, unique_id);
if (!sho_search_more_results(&s, al_str_c("twitter"), &query)) {
}
- al_str_free(&query);
} else {
- str query;
if (is_search) {
- //al_str_from(&query, "\"");
- al_str_from(&query, "");
al_str_cat(&query, al_str_substr(unique_id, 1, unique_id->len));
- //al_str_cat(&query, al_str_c("\""));
} else {
- al_str_from(&query, "link:");
+ al_str_cat(&query, al_str_c("link:"));
al_str_cat(&query, unique_id);
}
if (!sho_search_more_results(&s, al_str_c("youtube"), &query)) {
}
}
+ al_str_free(&query);
entry = NULL;
struct sho_result_page *page;
al_array_foreach_ptr(s.result.pages, k, page) {
@@ -77,7 +74,7 @@ static struct cch_entry *entry_for_unique_id(str *unique_id)
#else
if (!is_search) entry = cch_handler_http_create(unique_id);
#endif
- entry->handler->maybe_spawn_worker(entry->handler, 0);
+ if (entry) entry->handler->maybe_spawn_worker(entry->handler, 0);
} else // {
#endif
entry = cch_handler_file_create(unique_id);
@@ -87,10 +84,11 @@ static struct cch_entry *entry_for_unique_id(str *unique_id)
static bool buffer_entry(struct cap_runner *cap, struct cap_list *list, struct cap_list_entry *entry)
{
+ if (entry->errored) return false;
if (entry->buffer_requested) return true;
- struct cch_entry *centry = entry_for_unique_id(&entry->unique_id);
- if (!centry) return false;
- if (!cap->callback(cap->userdata, CAP_BUFFER, &list->name, &entry->unique_id, centry)) {
+ entry->entry = entry_for_unique_id(&entry->unique_id);
+ if (!entry->entry) return false;
+ if (!cap->callback(cap->userdata, CAP_BUFFER, &list->name, &entry->unique_id, entry->entry)) {
entry->errored = true;
return false;
}
@@ -102,7 +100,7 @@ static void maybe_cleanup_entries(struct cap_runner *cap, struct cap_list *list)
{
struct cap_list_entry *entry;
al_array_foreach_ptr(list->entries, i, entry) {
- if (entry->buffer_requested && abs((s32)i - list->current) >= 3) {
+ if (entry->buffer_requested && abs(list->current - (s32)i) >= 3) {
cap->callback(cap->userdata, CAP_UNLOAD, &list->name, &entry->unique_id, NULL);
entry->buffer_requested = false;
}
@@ -111,28 +109,34 @@ static void maybe_cleanup_entries(struct cap_runner *cap, struct cap_list *list)
static bool list_skip_internal(struct cap_runner *cap, struct cap_list *list, s32 n);
-static void list_pump_internal(struct cap_runner *cap, struct cap_list *list)
+static void list_pump_internal(struct cap_runner *cap, struct cap_list *list, bool buffer)
{
s32 size = (s32)list->entries.size;
if (size <= list->current) return;
+ if (buffer) list->buffer = true;
if (list->set != list->current) {
struct cap_list_entry *entry = &al_array_at(list->entries, list->current);
+ if (list->swap && !entry->buffer_requested) {
+ list->swap = false;
+ return;
+ }
if (!buffer_entry(cap, list, entry)) {
- list_skip_internal(cap, list, 1);
+ list_skip_internal(cap, list, list->forward ? 1 : -1);
return;
}
+ cap->callback(cap->userdata, list->swap ? CAP_SWAP : CAP_SET, &list->name, &entry->unique_id, NULL);
list->set = list->current;
- if (list->swap && entry->buffer_requested) {
- cap->callback(cap->userdata, CAP_SWAP, &list->name, &entry->unique_id, NULL);
- } else {
- cap->callback(cap->userdata, CAP_SET, &list->name, &entry->unique_id, NULL);
- }
- }
- if (list->current + 1 < size) {
- buffer_entry(cap, list, &al_array_at(list->entries, list->current + 1));
}
- if (list->current - 1 >= 0) {
- buffer_entry(cap, list, &al_array_at(list->entries, list->current - 1));
+ if (list->buffer) {
+ for (s32 i = 1; i <= 2; i++) {
+ if (list->current + i < size) {
+ buffer_entry(cap, list, &al_array_at(list->entries, list->current + i));
+ list->buffer = false;
+ }
+ if (list->current - i >= 0) {
+ buffer_entry(cap, list, &al_array_at(list->entries, list->current - i));
+ }
+ }
}
maybe_cleanup_entries(cap, list);
}
@@ -144,7 +148,8 @@ bool list_skip_internal(struct cap_runner *cap, struct cap_list *list, s32 n)
return false;
}
list->current += n;
- list_pump_internal(cap, list);
+ list->forward = n >= 0;
+ list_pump_internal(cap, list, false);
return true;
}
@@ -153,9 +158,12 @@ void cap_make_list(struct cap_runner *cap, str *name)
struct cap_list list;
al_str_clone(&list.name, name);
list.current = 0;
+ list.forward = true;
list.set = -1;
list.idle = false;
+ list.buffer = false;
list.swap = false;
+ aki_mutex_init(&list.mutex);
al_array_init(list.entries);
al_array_push(cap->lists, list);
}
@@ -164,39 +172,51 @@ void cap_list_add(struct cap_runner *cap, str *name, str *unique_id)
{
struct cap_list *list = list_from_name(cap, name);
if (!list) return;
+ aki_mutex_lock(&list->mutex);
struct cap_list_entry entry;
al_str_clone(&entry.unique_id, unique_id);
- entry.buffer_requested = false;
+ entry.entry = NULL;
entry.errored = false;
+ entry.buffer_requested = false;
al_array_push(list->entries, entry);
if (list->idle && list_skip_internal(cap, list, 1)) {
list->idle = false;
- return;
+ } else {
+ list_pump_internal(cap, list, false);
}
- list_pump_internal(cap, list);
+ aki_mutex_unlock(&list->mutex);
}
bool cap_list_skip(struct cap_runner *cap, str *name, s32 n)
{
struct cap_list *list = list_from_name(cap, name);
if (!list) return false;
- return list_skip_internal(cap, list, n);
+ aki_mutex_lock(&list->mutex);
+ bool ret = list_skip_internal(cap, list, n);
+ aki_mutex_unlock(&list->mutex);
+ return ret;
}
-void cap_list_pump(struct cap_runner *cap, str *name)
+void cap_list_pump(struct cap_runner *cap, str *name, bool buffer)
{
struct cap_list *list = list_from_name(cap, name);
- if (list) list_pump_internal(cap, list);
+ if (!list) return;
+ aki_mutex_lock(&list->mutex);
+ list_pump_internal(cap, list, buffer);
+ aki_mutex_unlock(&list->mutex);
}
bool cap_list_set_completed(struct cap_runner *cap, str *name)
{
struct cap_list *list = list_from_name(cap, name);
if (!list) return false;
+ aki_mutex_lock(&list->mutex);
list->swap = true;
list->idle = !list_skip_internal(cap, list, 1);
+ bool ret = !list->idle && list->swap;
list->swap = false;
- return !list->idle;
+ aki_mutex_unlock(&list->mutex);
+ return ret;
}
static void list_close_internal(struct cap_list *list)
@@ -206,6 +226,7 @@ static void list_close_internal(struct cap_list *list)
al_str_free(&entry->unique_id);
}
al_array_free(list->entries);
+ aki_mutex_destroy(&list->mutex);
al_str_free(&list->name);
}
diff --git a/src/fruits/cap/cap.h b/src/fruits/cap/cap.h
index d522a82..07aa63b 100644
--- a/src/fruits/cap/cap.h
+++ b/src/fruits/cap/cap.h
@@ -4,9 +4,11 @@
#include <al/array.h>
#include <al/str.h>
+#include <aki/thread.h>
struct cap_list_entry {
str unique_id;
+ struct cch_entry *entry;
bool buffer_requested;
bool errored;
};
@@ -14,9 +16,12 @@ struct cap_list_entry {
struct cap_list {
str name;
s32 current;
+ bool forward;
s32 set;
bool idle;
+ bool buffer;
bool swap;
+ struct aki_mutex mutex;
array(struct cap_list_entry) entries;
};
@@ -37,6 +42,6 @@ void cap_init(struct cap_runner *cap, bool (*callback)(void *, u8, str *, str *,
void cap_make_list(struct cap_runner *cap, str *name);
void cap_list_add(struct cap_runner *cap, str *name, str *unique_id);
bool cap_list_skip(struct cap_runner *cap, str *name, s32 n);
-void cap_list_pump(struct cap_runner *cap, str *name);
+void cap_list_pump(struct cap_runner *cap, str *name, bool buffer);
bool cap_list_set_completed(struct cap_runner *cap, str *name);
void cap_close(struct cap_runner *cap);
diff --git a/src/fruits/cmv/cmv2.c b/src/fruits/cmv/cmv2.c
index d8f4fc2..3c70317 100644
--- a/src/fruits/cmv/cmv2.c
+++ b/src/fruits/cmv/cmv2.c
@@ -42,8 +42,6 @@ struct cmv {
#endif
};
-static struct cmv c;
-
static str *default_list = al_str_c("default");
static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
@@ -97,6 +95,10 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
}
}
break;
+ case CAMU_SINK_SET_BUFFERED: {
+ cap_list_pump(&c->cap, default_list, true);
+ break;
+ }
case CAMU_SINK_START:
switch (type) {
case CAMU_SINK_AUDIO: {
@@ -177,6 +179,7 @@ static bool cap_callback(void *userdata, u8 op, str *name, str *unique_id, void
return camu_sink_local_buffer(&c->sink, unique_id, (struct cch_entry *)opaque);
case CAP_SET:
camu_sink_local_set(&c->sink, unique_id);
+ al_log_info("cmv", "Now playing: %.*s.", AL_STR_PRINTF(unique_id));
break;
case CAP_SWAP:
camu_sink_local_swap(&c->sink, unique_id);
@@ -237,12 +240,14 @@ s32 main(s32 argc, char *argv[])
{
aki_common_init();
+ struct cmv c = { };
+
#if CMV_USE_TUI
if (!tui_init(&c.tui)) {
aki_common_close();
return EXIT_FAILURE;
}
- al_set_print(&c, log_callback);
+ al_set_print(log_callback, &c);
#ifdef HAVE_FFMPEG
camu_lav_set_log_callback(lav_log_callback);
#endif
@@ -297,7 +302,7 @@ s32 main(s32 argc, char *argv[])
#if CMV_USE_TUI
aki_timer_init(&c.timer, &c.loop, timer_callback, &c);
- aki_timer_set_repeat(&c.timer, 0.15);
+ aki_timer_set_repeat(&c.timer, 0.10);
aki_timer_again(&c.timer);
#endif
diff --git a/src/fruits/cmv/tui.c b/src/fruits/cmv/tui.c
index 84a1846..21aeac8 100644
--- a/src/fruits/cmv/tui.c
+++ b/src/fruits/cmv/tui.c
@@ -1,7 +1,6 @@
#include <aki/file.h>
#include <al/log.h>
#include <sys/ioctl.h>
-#include <termios.h>
#include "tui.h"
@@ -31,15 +30,22 @@ bool tui_init(struct cmv_tui *tui)
tui->height = 0;
//tui->prev_lines = 0;
- tui->fd = STDIN_FILENO;
+ tui->fd = fileno(stdin);
tui->out = fdopen(tui->fd, "w");
if (!tui->out) return false;
- setbuf(tui->out, NULL);
tui_global = tui;
aki_mutex_init(&tui->mutex);
signal(SIGWINCH, handle_winch);
+ // Disable buffer.
+ setbuf(tui->out, NULL);
+
+ // Disable echo.
+ tcgetattr(tui->fd, &tui->term);
+ tui->term.c_lflag &= ~ECHO;
+ tcsetattr(tui->fd, 0, &tui->term);
+
al_array_init(tui->log_buffer);
tui->last_pts = 0.0;
@@ -114,5 +120,7 @@ void tui_close(struct cmv_tui *tui)
aki_mutex_destroy(&tui->mutex);
fprintf(tui->out, "\n");
fflush(tui->out);
+ tui->term.c_lflag |= ECHO;
+ tcsetattr(tui->fd, 0, &tui->term);
fclose(tui->out);
}
diff --git a/src/fruits/cmv/tui.h b/src/fruits/cmv/tui.h
index 8cf58c0..fb4215e 100644
--- a/src/fruits/cmv/tui.h
+++ b/src/fruits/cmv/tui.h
@@ -1,18 +1,21 @@
#pragma once
+#include <termios.h>
+
#include "../../bimu/local.h"
#include "../../buffer/clock.h"
struct cmv_tui {
s32 fd;
FILE *out;
+ struct aki_mutex mutex;
+ struct termios term;
bool update_size;
u32 width;
u32 height;
//u32 prev_lines;
array(char *) log_buffer;
f64 last_pts;
- struct aki_mutex mutex;
};
bool tui_init(struct cmv_tui *tui);