rtmp-services: Only update Twitch ingests when necessary
(This commit also modifies UI) Instead of pinging Twitch every time the program starts up, only pings for new servers when the ingests are actually being used, and when the UI uses the auto-configuration dialog. If ingests have not been cached when using the "Auto" server, it will wait for 3 seconds max to query the Twitch ingest API. If it takes longer than 3 seconds or fails, it will defer to SF. If ingests were already cached, then it will use the existing cache immediately.master
parent
3dc96fbe43
commit
d768717b8c
|
@ -545,6 +545,13 @@ void AutoConfigStreamPage::UpdateCompleted()
|
|||
AutoConfig::AutoConfig(QWidget *parent)
|
||||
: QWizard(parent)
|
||||
{
|
||||
calldata_t cd = {0};
|
||||
calldata_set_int(&cd, "seconds", 5);
|
||||
|
||||
proc_handler_t *ph = obs_get_proc_handler();
|
||||
proc_handler_call(ph, "twitch_ingests_refresh", &cd);
|
||||
calldata_free(&cd);
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(parent);
|
||||
main->EnableOutputs(false);
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ static json_t *open_services_file(void);
|
|||
static inline json_t *find_service(json_t *root, const char *name);
|
||||
static inline const char *get_string_val(json_t *service, const char *key);
|
||||
|
||||
extern void twitch_ingests_refresh(int seconds);
|
||||
|
||||
static void rtmp_common_update(void *data, obs_data_t *settings)
|
||||
{
|
||||
struct rtmp_common *service = data;
|
||||
|
@ -247,12 +249,12 @@ static bool fill_twitch_servers_locked(obs_property_t *servers_prop)
|
|||
{
|
||||
size_t count = twitch_ingest_count();
|
||||
|
||||
if (count <= 1)
|
||||
return false;
|
||||
|
||||
obs_property_list_add_string(servers_prop,
|
||||
obs_module_text("Server.Auto"), "auto");
|
||||
|
||||
if (count <= 1)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
struct twitch_ingest ing = twitch_ingest(i);
|
||||
obs_property_list_add_string(servers_prop, ing.name, ing.url);
|
||||
|
@ -508,6 +510,8 @@ static const char *rtmp_common_url(void *data)
|
|||
if (service->server && strcmp(service->server, "auto") == 0) {
|
||||
struct twitch_ingest ing;
|
||||
|
||||
twitch_ingests_refresh(3);
|
||||
|
||||
twitch_ingests_lock();
|
||||
ing = twitch_ingest(0);
|
||||
twitch_ingests_unlock();
|
||||
|
|
|
@ -18,6 +18,12 @@ extern struct obs_service_info rtmp_common_service;
|
|||
extern struct obs_service_info rtmp_custom_service;
|
||||
|
||||
static update_info_t *update_info = NULL;
|
||||
static struct dstr module_name = {0};
|
||||
|
||||
const char *get_module_name(void)
|
||||
{
|
||||
return module_name.array;
|
||||
}
|
||||
|
||||
static bool confirm_service_file(void *param, struct file_download_data *file)
|
||||
{
|
||||
|
@ -41,22 +47,39 @@ static bool confirm_service_file(void *param, struct file_download_data *file)
|
|||
}
|
||||
|
||||
extern void init_twitch_data(void);
|
||||
extern void load_twitch_data(const char *module_str);
|
||||
extern void load_twitch_data(void);
|
||||
extern void unload_twitch_data(void);
|
||||
extern void twitch_ingests_refresh(int seconds);
|
||||
|
||||
static void refresh_callback(void *unused, calldata_t *cd)
|
||||
{
|
||||
int seconds = calldata_int(cd, "seconds");
|
||||
if (seconds <= 0)
|
||||
seconds = 3;
|
||||
if (seconds > 10)
|
||||
seconds = 10;
|
||||
|
||||
twitch_ingests_refresh(seconds);
|
||||
|
||||
UNUSED_PARAMETER(unused);
|
||||
}
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
init_twitch_data();
|
||||
|
||||
#if !defined(_WIN32) || CHECK_FOR_SERVICE_UPDATES
|
||||
char *local_dir = obs_module_file("");
|
||||
char *cache_dir = obs_module_config_path("");
|
||||
struct dstr module_name = {0};
|
||||
|
||||
dstr_copy(&module_name, "rtmp-services plugin (libobs ");
|
||||
dstr_cat(&module_name, obs_get_version_string());
|
||||
dstr_cat(&module_name, ")");
|
||||
|
||||
proc_handler_t *ph = obs_get_proc_handler();
|
||||
proc_handler_add(ph, "void twitch_ingests_refresh(int seconds)",
|
||||
refresh_callback, NULL);
|
||||
|
||||
#if !defined(_WIN32) || CHECK_FOR_SERVICE_UPDATES
|
||||
char *local_dir = obs_module_file("");
|
||||
char *cache_dir = obs_module_config_path("");
|
||||
|
||||
if (cache_dir) {
|
||||
update_info = update_info_create(
|
||||
RTMP_SERVICES_LOG_STR,
|
||||
|
@ -67,11 +90,10 @@ bool obs_module_load(void)
|
|||
confirm_service_file, NULL);
|
||||
}
|
||||
|
||||
load_twitch_data(module_name.array);
|
||||
load_twitch_data();
|
||||
|
||||
bfree(local_dir);
|
||||
bfree(cache_dir);
|
||||
dstr_free(&module_name);
|
||||
#endif
|
||||
|
||||
obs_register_service(&rtmp_common_service);
|
||||
|
@ -83,4 +105,5 @@ void obs_module_unload(void)
|
|||
{
|
||||
update_info_destroy(update_info);
|
||||
unload_twitch_data();
|
||||
dstr_free(&module_name);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
static update_info_t *twitch_update_info = NULL;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static bool ingests_refreshed = false;
|
||||
static bool ingests_refreshing = false;
|
||||
static bool ingests_loaded = false;
|
||||
|
||||
struct ingest {
|
||||
char *name;
|
||||
|
@ -28,7 +31,7 @@ static void free_ingests(void)
|
|||
da_free(cur_ingests);
|
||||
}
|
||||
|
||||
static void load_ingests(const char *json, bool write_file)
|
||||
static bool load_ingests(const char *json, bool write_file)
|
||||
{
|
||||
json_t *root;
|
||||
json_t *ingests;
|
||||
|
@ -79,7 +82,12 @@ static void load_ingests(const char *json, bool write_file)
|
|||
da_push_back(cur_ingests, &ingest);
|
||||
}
|
||||
|
||||
if (!write_file || !cur_ingests.num)
|
||||
if (!cur_ingests.num)
|
||||
goto finish;
|
||||
|
||||
success = true;
|
||||
|
||||
if (!write_file)
|
||||
goto finish;
|
||||
|
||||
cache_old = obs_module_config_path("twitch_ingests.json");
|
||||
|
@ -94,14 +102,22 @@ static void load_ingests(const char *json, bool write_file)
|
|||
finish:
|
||||
if (root)
|
||||
json_decref(root);
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool twitch_ingest_update(void *param, struct file_download_data *data)
|
||||
{
|
||||
bool success;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
load_ingests(data->buffer.array, true);
|
||||
success = load_ingests(data->buffer.array, true);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
if (success) {
|
||||
os_atomic_set_bool(&ingests_refreshed, true);
|
||||
os_atomic_set_bool(&ingests_loaded, true);
|
||||
}
|
||||
|
||||
UNUSED_PARAMETER(param);
|
||||
return true;
|
||||
}
|
||||
|
@ -141,26 +157,62 @@ void init_twitch_data(void)
|
|||
pthread_mutex_init(&mutex, NULL);
|
||||
}
|
||||
|
||||
void load_twitch_data(const char *module_str)
|
||||
extern const char *get_module_name(void);
|
||||
|
||||
void twitch_ingests_refresh(int seconds)
|
||||
{
|
||||
if (os_atomic_load_bool(&ingests_refreshed))
|
||||
return;
|
||||
|
||||
if (!os_atomic_load_bool(&ingests_refreshing)) {
|
||||
os_atomic_set_bool(&ingests_refreshing, true);
|
||||
|
||||
twitch_update_info = update_info_create_single(
|
||||
"[twitch ingest update] ",
|
||||
get_module_name(),
|
||||
"https://ingest.twitch.tv/api/v2/ingests",
|
||||
twitch_ingest_update, NULL);
|
||||
}
|
||||
|
||||
/* wait five seconds max when loading ingests for the first time */
|
||||
if (!os_atomic_load_bool(&ingests_loaded)) {
|
||||
for (int i = 0; i < seconds * 100; i++) {
|
||||
if (os_atomic_load_bool(&ingests_refreshed)) {
|
||||
break;
|
||||
}
|
||||
os_sleep_ms(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void load_twitch_data(void)
|
||||
{
|
||||
char *twitch_cache = obs_module_config_path("twitch_ingests.json");
|
||||
|
||||
struct ingest def = {
|
||||
.name = bstrdup("Default"),
|
||||
.url = bstrdup("rtmp://live.twitch.tv/app")
|
||||
};
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
da_push_back(cur_ingests, &def);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
if (os_file_exists(twitch_cache)) {
|
||||
char *data = os_quick_read_utf8_file(twitch_cache);
|
||||
bool success;
|
||||
|
||||
pthread_mutex_lock(&mutex);
|
||||
load_ingests(data, false);
|
||||
success = load_ingests(data, false);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
if (success) {
|
||||
os_atomic_set_bool(&ingests_loaded, true);
|
||||
}
|
||||
|
||||
bfree(data);
|
||||
}
|
||||
|
||||
twitch_update_info = update_info_create_single(
|
||||
"[twitch ingest update] ",
|
||||
module_str,
|
||||
"https://ingest.twitch.tv/api/v2/ingests",
|
||||
twitch_ingest_update, NULL);
|
||||
|
||||
bfree(twitch_cache);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue