diff options
| author | 2023-11-11 17:51:49 -0500 | |
|---|---|---|
| committer | 2023-11-11 17:51:49 -0500 | |
| commit | 7e5043a2505efa383ae372662fa4849051cd9799 (patch) | |
| tree | e7736218b7ab323579a440f24d899ed00beb9f73 /src/fruits | |
| parent | 113eb3b481417364f84350e90be252355d807f06 (diff) | |
| download | camu-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.c | 87 | ||||
| -rw-r--r-- | src/fruits/cap/cap.h | 7 | ||||
| -rw-r--r-- | src/fruits/cmv/cmv2.c | 13 | ||||
| -rw-r--r-- | src/fruits/cmv/tui.c | 14 | ||||
| -rw-r--r-- | src/fruits/cmv/tui.h | 5 |
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); |