Beispiel #1
0
static inline obs_data_t *get_defaults(const struct obs_encoder_info *info)
{
	obs_data_t *settings = obs_data_create();
	if (info->get_defaults)
		info->get_defaults(settings);
	return settings;
}
Beispiel #2
0
obs_scene_t obs_scene_create(const char *name)
{
	struct obs_source *source = bmalloc(sizeof(struct obs_source));
	struct obs_scene  *scene;

	memset(source, 0, sizeof(struct obs_source));
	if (!obs_source_init_handlers(source)) {
		bfree(source);
		return NULL;
	}

	source->settings = obs_data_create();
	scene = scene_create(source->settings, source);
	source->data = scene;

	assert(scene);
	if (!scene) {
		obs_data_release(source->settings);
		bfree(source);
		return NULL;
	}

	source->name  = bstrdup(name);
	source->type  = SOURCE_SCENE;

	scene->source = source;
	obs_source_init(source, &scene_info);
	memcpy(&source->callbacks, &scene_info, sizeof(struct source_info));
	return scene;
}
static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder) {

	obs_data_t       *saveData = obs_data_create();
	obs_data_array_t *sourcesArray = obs_save_sources();
	obs_source_t     *currentScene = obs_get_output_source(0);
	const char       *sceneName = obs_source_get_name(currentScene);

	const char *sceneCollection = config_get_string(App()->mGetGlobalConfig(),
		"Basic", "SceneCollection");

	SaveAudioDevice(DESKTOP_AUDIO_1, 1, saveData);
	SaveAudioDevice(DESKTOP_AUDIO_2, 2, saveData);
	SaveAudioDevice(AUX_AUDIO_1, 3, saveData);
	SaveAudioDevice(AUX_AUDIO_2, 4, saveData);
	SaveAudioDevice(AUX_AUDIO_3, 5, saveData);

	obs_data_set_string(saveData, "current_scene", sceneName);
	obs_data_set_array(saveData, "scene_order", sceneOrder);
	obs_data_set_string(saveData, "name", sceneCollection);
	obs_data_set_array(saveData, "sources", sourcesArray);
	obs_data_array_release(sourcesArray);
	obs_source_release(currentScene);

	return saveData;
}
Beispiel #4
0
static inline bool save_bindings_helper(void *data,
		size_t idx, obs_hotkey_binding_t *binding)
{
	UNUSED_PARAMETER(idx);
	struct save_bindings_helper_t *h = data;

	if (h->hotkey->id != binding->hotkey_id)
		return true;

	obs_data_t *hotkey = obs_data_create();

	uint32_t modifiers = binding->key.modifiers;
	save_modifier(modifiers, hotkey, "shift", INTERACT_SHIFT_KEY);
	save_modifier(modifiers, hotkey, "control", INTERACT_CONTROL_KEY);
	save_modifier(modifiers, hotkey, "alt", INTERACT_ALT_KEY);
	save_modifier(modifiers, hotkey, "command", INTERACT_COMMAND_KEY);

	obs_data_set_string(hotkey, "key", obs_key_to_name(binding->key.key));

	obs_data_array_push_back(h->array, hotkey);

	obs_data_release(hotkey);

	return true;
}
Beispiel #5
0
static inline obs_data_t get_defaults(const struct obs_output_info *info)
{
	obs_data_t settings = obs_data_create();
	if (info->defaults)
		info->defaults(settings);
	return settings;
}
obs_data_array_t *BiLiOBSMainWid::mSaveSceneListOrder() {

	obs_data_array_t *sceneOrder = obs_data_array_create();

#if 1
	obs_source_t* currentScene = obs_get_output_source(0);
	std::list<std::string> tmpSceneOrder;

	//获取所有场景
	for (OBSSource& src : OBSEnumSources())
	{
		if (strcmp(obs_source_get_id(src), "scene") == 0)
			tmpSceneOrder.push_back(obs_source_get_name(src));
	}

	//当前场景放在第一个
	if (currentScene)
	{
		std::string currentSceneName = obs_source_get_name(currentScene);
		auto x = std::find(tmpSceneOrder.begin(), tmpSceneOrder.end(), currentSceneName);
		assert(x != tmpSceneOrder.end());
		tmpSceneOrder.erase(x);
		tmpSceneOrder.push_front(obs_source_get_name(currentScene));
	}

	//保存场景顺序
	for (auto& x : tmpSceneOrder) {
		obs_data_t *data = obs_data_create();
		obs_data_set_string(data, "name", x.c_str());
		obs_data_array_push_back(sceneOrder, data);
		obs_data_release(data);
	}

	obs_source_release(currentScene);
#else
	for (int i = 0; i < ui->scenes->count(); i++) {
		obs_data_t *data = obs_data_create();
		obs_data_set_string(data, "name",
				QT_TO_UTF8(ui->scenes->item(i)->text()));
		obs_data_array_push_back(sceneOrder, data);
		obs_data_release(data);
	}
#endif

	return sceneOrder;
}
Beispiel #7
0
static inline obs_data_t *save_context_hotkeys(struct obs_context_data *context)
{
	if (!context->hotkeys.num)
		return NULL;

	obs_data_t *result = obs_data_create();
	enum_context_hotkeys(context, enum_save_hotkey, result);
	return result;
}
Beispiel #8
0
obs_data_t obs_output_defaults(const char *id)
{
	const struct obs_output_info *info = find_output(id);
	if (info) {
		obs_data_t settings = obs_data_create();
		if (info->defaults)
			info->defaults(settings);
		return settings;
	}

	return NULL;
}
Beispiel #9
0
obs_data_t obs_encoder_defaults(const char *id)
{
	const struct obs_encoder_info *info = get_encoder_info(id);
	if (info) {
		obs_data_t settings = obs_data_create();
		if (info->defaults)
			info->defaults(settings);
		return settings;
	}

	return NULL;
}
Beispiel #10
0
static OBSSource CreateLabel(const char *name, size_t h)
{
	obs_data_t *settings = obs_data_create();
	obs_data_t *font     = obs_data_create();

	std::string text;
	text += " ";
	text += name;
	text += " ";

#if defined(_WIN32)
	obs_data_set_string(font, "face", "Arial");
#elif defined(__APPLE__)
	obs_data_set_string(font, "face", "Helvetica");
#else
	obs_data_set_string(font, "face", "Monospace");
#endif
	obs_data_set_int(font, "flags", 1); // Bold text
	obs_data_set_int(font, "size", int(h / 9.81));

	obs_data_set_obj(settings, "font", font);
	obs_data_set_string(settings, "text", text.c_str());
	obs_data_set_bool(settings, "outline", false);

#ifdef _WIN32
	const char *text_source_id = "text_gdiplus";
#else
	const char *text_source_id = "text_ft2_source";
#endif

	OBSSource txtSource = obs_source_create_private(text_source_id, name,
			settings);
	obs_source_release(txtSource);

	obs_data_release(font);
	obs_data_release(settings);

	return txtSource;
}
void AutoConfigStreamPage::LoadServices(bool showAll)
{
	obs_properties_t *props = obs_get_service_properties("rtmp_common");

	OBSData settings = obs_data_create();
	obs_data_release(settings);

	obs_data_set_bool(settings, "show_all", showAll);

	obs_property_t *prop = obs_properties_get(props, "show_all");
	obs_property_modified(prop, settings);

	ui->service->blockSignals(true);
	ui->service->clear();

	QStringList names;

	obs_property_t *services = obs_properties_get(props, "service");
	size_t services_count = obs_property_list_item_count(services);
	for (size_t i = 0; i < services_count; i++) {
		const char *name = obs_property_list_item_string(services, i);
		names.push_back(name);
	}

	if (showAll)
		names.sort();

	for (QString &name : names)
		ui->service->addItem(name);

	if (!showAll) {
		ui->service->addItem(
			QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"),
			QVariant((int)ListOpt::ShowAll));
	}

	ui->service->insertItem(0,
			QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
			QVariant((int)ListOpt::Custom));

	if (!lastService.isEmpty()) {
		int idx = ui->service->findText(lastService);
		if (idx != -1)
			ui->service->setCurrentIndex(idx);
	}

	obs_properties_destroy(props);

	ui->service->blockSignals(false);
}
Beispiel #12
0
static void* python_source_create(obs_data_t* settings, obs_source_t* source)
{

    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();

    //    PyRun_SimpleString("libobs.log('python_source_create with python YAYPyRun_SimpleString')");

    UNUSED_PARAMETER(source);
    //Create the new source here




    obs_data_t* font_obj = obs_data_create();
    obs_data_set_default_string(settings, "text","The lazy.");
    obs_data_release(font_obj);




    /*
        obs_register_source(py_module.tmp->src_info);

        // This creates a new source.
        obs_source_t* source = obs_get_output_source(0); //gets output source?
        obs_scene_t* current_scene = obs_scene_from_source(source);
        char* name = "TESTING";
        source = obs_get_source_by_name(name);
        if(source) {
      //source already exists, just add to scene
            obs_scene_add(current_scene,source);

        } else {
            source = obs_source_create(OBS_SOURCE_TYPE_INPUT,"python_source",name,NULL);
            obs_add_source(source);
            obs_scene_add(current_scene,source);

        }

        obs_source_release(source);
        obs_scene_release(current_scene);

    */
    PyGILState_Release(gstate);
    return &python_source_info;
}
Beispiel #13
0
void obs_data_set_qfont(obs_data_t* data, const char* name, QFont font){

	obs_data_t *fontObj = obs_data_create();
	obs_data_set_string(fontObj, "face", (font.family()).toUtf8().data());
	obs_data_set_string(fontObj, "style", (font.styleName()).toUtf8().data());
	obs_data_set_int(fontObj, "size", font.pointSize());

	int flags  = font.bold() ? OBS_FONT_BOLD : 0;
	flags |= font.italic() ? OBS_FONT_ITALIC : 0;
	flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
	flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
	obs_data_set_int(fontObj, "flags", flags);

	obs_data_set_obj(data, "font", fontObj);
	obs_data_release(fontObj);
	return;
}
void AutoConfig::SaveStreamSettings()
{
	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());

	/* ---------------------------------- */
	/* save service                       */

	const char *service_id = customServer
		? "rtmp_custom"
		: "rtmp_common";

	obs_service_t *oldService = main->GetService();
	OBSData hotkeyData = obs_hotkeys_save_service(oldService);
	obs_data_release(hotkeyData);

	OBSData settings = obs_data_create();
	obs_data_release(settings);

	if (!customServer)
		obs_data_set_string(settings, "service", serviceName.c_str());
	obs_data_set_string(settings, "server", server.c_str());
	obs_data_set_string(settings, "key", key.c_str());

	OBSService newService = obs_service_create(service_id,
			"default_service", settings, hotkeyData);
	obs_service_release(newService);

	if (!newService)
		return;

	main->SetService(newService);
	main->SaveService();
	main->auth = streamPage->auth;
	if (!!main->auth)
		main->auth->LoadUI();

	/* ---------------------------------- */
	/* save stream settings               */

	config_set_int(main->Config(), "SimpleOutput", "VBitrate",
			idealBitrate);
	config_set_string(main->Config(), "SimpleOutput", "StreamEncoder",
			GetEncoderId(streamingEncoder));
	config_remove_value(main->Config(), "SimpleOutput", "UseAdvanced");
}
Beispiel #15
0
void ScriptsTool::ReloadScript(const char *path)
{
	for (OBSScript &script : scriptData->scripts) {
		const char *script_path = obs_script_get_path(script);
		if (strcmp(script_path, path) == 0) {
			obs_script_reload(script);

			OBSData settings = obs_data_create();
			obs_data_release(settings);

			obs_properties_t *prop =
				obs_script_get_properties(script);
			obs_properties_apply_settings(prop, settings);

			break;
		}
	}
}
Beispiel #16
0
static void scene_save_item(obs_data_array_t *array,
		struct obs_scene_item *item)
{
	obs_data_t *item_data = obs_data_create();
	const char *name     = obs_source_get_name(item->source);

	obs_data_set_string(item_data, "name",         name);
	obs_data_set_bool  (item_data, "visible",      item->user_visible);
	obs_data_set_double(item_data, "rot",          item->rot);
	obs_data_set_vec2 (item_data, "pos",          &item->pos);
	obs_data_set_vec2 (item_data, "scale",        &item->scale);
	obs_data_set_int   (item_data, "align",        (int)item->align);
	obs_data_set_int   (item_data, "bounds_type",  (int)item->bounds_type);
	obs_data_set_int   (item_data, "bounds_align", (int)item->bounds_align);
	obs_data_set_vec2 (item_data, "bounds",       &item->bounds);

	obs_data_array_push_back(array, item_data);
	obs_data_release(item_data);
}
Beispiel #17
0
obs_data_t *obs_save_source(obs_source_t *source)
{
	obs_data_t *source_data = obs_data_create();
	obs_data_t *settings    = obs_source_get_settings(source);
	float      volume      = obs_source_get_volume(source);
	const char *name       = obs_source_get_name(source);
	const char *id         = obs_source_get_id(source);

	obs_source_save(source);

	obs_data_set_string(source_data, "name",     name);
	obs_data_set_string(source_data, "id",       id);
	obs_data_set_obj   (source_data, "settings", settings);
	obs_data_set_double(source_data, "volume",   volume);

	obs_data_release(settings);

	return source_data;
}
static void stinger_update(void *data, obs_data_t *settings)
{
	struct stinger_info *s = data;
	const char *path = obs_data_get_string(settings, "path");

	obs_data_t *media_settings = obs_data_create();
	obs_data_set_string(media_settings, "local_file", path);

	obs_source_release(s->media_source);
	s->media_source = obs_source_create_private("ffmpeg_source", NULL,
			media_settings);
	obs_data_release(media_settings);

	int64_t point = obs_data_get_int(settings, "transition_point");

	s->transition_point_is_frame =
			obs_data_get_int(settings, "tp_type") == TIMING_FRAME;

	if (s->transition_point_is_frame)
		s->transition_point_frame = (uint64_t)point;
	else
		s->transition_point_ns = (uint64_t)(point * 1000000LL);

	s->monitoring_type = (int)obs_data_get_int(settings,"audio_monitoring");
	obs_source_set_monitoring_type(s->media_source, s->monitoring_type);

	s->fade_style = (enum fade_style)obs_data_get_int(settings,
			"audio_fade_style");

	switch (s->fade_style) {
	default:
	case FADE_STYLE_FADE_OUT_FADE_IN:
		s->mix_a = mix_a_fade_in_out;
		s->mix_b = mix_b_fade_in_out;
		break;
	case FADE_STYLE_CROSS_FADE:
		s->mix_a = mix_a_cross_fade;
		s->mix_b = mix_b_cross_fade;
		break;
	}
}
void BiLiTextSourcePropertyDlg::mSltFontComboxChanged(const QString &text) {

	QFont font = qobject_cast<QFontComboBox *>(sender())->currentFont();

	obs_data_t *fontObj = obs_data_create();

	obs_data_set_string(fontObj, "face", (font.family()).toUtf8().data());
	obs_data_set_string(fontObj, "style", (font.styleName()).toUtf8().data());
	obs_data_set_int(fontObj, "size", font.pointSize());

	int flags  = font.bold() ? OBS_FONT_BOLD : 0;
	flags |= font.italic() ? OBS_FONT_ITALIC : 0;
	flags |= font.underline() ? OBS_FONT_UNDERLINE : 0;
	flags |= font.strikeOut() ? OBS_FONT_STRIKEOUT : 0;
	obs_data_set_int(fontObj, "flags", flags);

	obs_data_t *settingFont = obs_source_get_settings(mSrc);
	obs_data_set_obj(settingFont, "font", fontObj);
	obs_data_release(fontObj);
	obs_data_release(settingFont);
}
Beispiel #20
0
obs_data_t obs_save_source(obs_source_t source)
{
	obs_data_t source_data = obs_data_create();
	obs_data_t settings    = obs_source_getsettings(source);
	float      volume      = obs_source_getvolume(source);
	const char *name       = obs_source_getname(source);
	const char *id;

	obs_source_save(source);

	obs_source_gettype(source, NULL, &id);

	obs_data_setstring(source_data, "name",     name);
	obs_data_setstring(source_data, "id",       id);
	obs_data_setobj   (source_data, "settings", settings);
	obs_data_setdouble(source_data, "volume",   volume);

	obs_data_release(settings);

	return source_data;
}
Beispiel #21
0
static void *ft2_source_create(obs_data_t settings, obs_source_t source)
{
	struct ft2_source *srcdata = bzalloc(sizeof(struct ft2_source));
	obs_data_t font_obj = obs_data_create();
	srcdata->src = source;

	srcdata->font_size = 32;

	obs_data_set_default_string(font_obj, "face", DEFAULT_FACE);
	obs_data_set_default_int(font_obj, "size", 32);
	obs_data_set_default_obj(settings, "font", font_obj);

	obs_data_set_default_int(settings, "color1", 0xFFFFFFFF);
	obs_data_set_default_int(settings, "color2", 0xFFFFFFFF);
	obs_data_set_default_string(settings, "text",
		"The lazy snake jumps over the happy MASKEN.");

	ft2_source_update(srcdata, settings);

	obs_data_release(font_obj);

	return srcdata;
}
Beispiel #22
0
static void save_script_data(obs_data_t *save_data, bool saving, void *)
{
	if (!saving)
		return;

	obs_data_array_t *array = obs_data_array_create();

	for (OBSScript &script : scriptData->scripts) {
		const char *script_path = obs_script_get_path(script);
		obs_data_t *settings = obs_script_save(script);

		obs_data_t *obj = obs_data_create();
		obs_data_set_string(obj, "path", script_path);
		obs_data_set_obj(obj, "settings", settings);
		obs_data_array_push_back(array, obj);
		obs_data_release(obj);

		obs_data_release(settings);
	}

	obs_data_set_array(save_data, "scripts-tool", array);
	obs_data_array_release(array);
}
Beispiel #23
0
static void scene_save_item(obs_data_array_t *array,
		struct obs_scene_item *item)
{
	obs_data_t *item_data = obs_data_create();
	const char *name     = obs_source_get_name(item->source);
	const char *scale_filter;

	obs_data_set_string(item_data, "name",         name);
	obs_data_set_bool  (item_data, "visible",      item->user_visible);
	obs_data_set_double(item_data, "rot",          item->rot);
	obs_data_set_vec2 (item_data, "pos",          &item->pos);
	obs_data_set_vec2 (item_data, "scale",        &item->scale);
	obs_data_set_int   (item_data, "align",        (int)item->align);
	obs_data_set_int   (item_data, "bounds_type",  (int)item->bounds_type);
	obs_data_set_int   (item_data, "bounds_align", (int)item->bounds_align);
	obs_data_set_vec2 (item_data, "bounds",       &item->bounds);
	obs_data_set_int  (item_data, "crop_left",    (int)item->crop.left);
	obs_data_set_int  (item_data, "crop_top",     (int)item->crop.top);
	obs_data_set_int  (item_data, "crop_right",   (int)item->crop.right);
	obs_data_set_int  (item_data, "crop_bottom",  (int)item->crop.bottom);

	if (item->scale_filter == OBS_SCALE_POINT)
		scale_filter = "point";
	else if (item->scale_filter == OBS_SCALE_BILINEAR)
		scale_filter = "bilinear";
	else if (item->scale_filter == OBS_SCALE_BICUBIC)
		scale_filter = "bicubic";
	else if (item->scale_filter == OBS_SCALE_LANCZOS)
		scale_filter = "lanczos";
	else
		scale_filter = "disable";

	obs_data_set_string(item_data, "scale_filter", scale_filter);

	obs_data_array_push_back(array, item_data);
	obs_data_release(item_data);
}
void AutoConfigStreamPage::UpdateServerList()
{
	QString serviceName = ui->service->currentText();
	bool showMore =
		ui->service->currentData().toInt() == (int)ListOpt::ShowAll;

	if (showMore) {
		LoadServices(true);
		ui->service->showPopup();
		return;
	} else {
		lastService = serviceName;
	}

	obs_properties_t *props = obs_get_service_properties("rtmp_common");
	obs_property_t *services = obs_properties_get(props, "service");

	OBSData settings = obs_data_create();
	obs_data_release(settings);

	obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
	obs_property_modified(services, settings);

	obs_property_t *servers = obs_properties_get(props, "server");

	ui->server->clear();

	size_t servers_count = obs_property_list_item_count(servers);
	for (size_t i = 0; i < servers_count; i++) {
		const char *name = obs_property_list_item_name(servers, i);
		const char *server = obs_property_list_item_string(servers, i);
		ui->server->addItem(name, server);
	}

	obs_properties_destroy(props);
}
AutoConfig::AutoConfig(QWidget *parent)
	: QWizard(parent)
{
	EnableThreadedMessageBoxes(true);

	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);

	installEventFilter(CreateShortcutFilter());

	std::string serviceType;
	GetServiceInfo(serviceType, serviceName, server, key);
#ifdef _WIN32
	setWizardStyle(QWizard::ModernStyle);
#endif
	streamPage = new AutoConfigStreamPage();

	setPage(StartPage, new AutoConfigStartPage());
	setPage(VideoPage, new AutoConfigVideoPage());
	setPage(StreamPage, streamPage);
	setPage(TestPage, new AutoConfigTestPage());
	setWindowTitle(QTStr("Basic.AutoConfig"));
	setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);

	obs_video_info ovi;
	obs_get_video_info(&ovi);

	baseResolutionCX = ovi.base_width;
	baseResolutionCY = ovi.base_height;

	/* ----------------------------------------- */
	/* check to see if Twitch's "auto" available */

	OBSData twitchSettings = obs_data_create();
	obs_data_release(twitchSettings);

	obs_data_set_string(twitchSettings, "service", "Twitch");

	obs_properties_t *props = obs_get_service_properties("rtmp_common");
	obs_properties_apply_settings(props, twitchSettings);

	obs_property_t *p = obs_properties_get(props, "server");
	const char *first = obs_property_list_item_string(p, 0);
	twitchAuto = strcmp(first, "auto") == 0;

	obs_properties_destroy(props);

	/* ----------------------------------------- */
	/* load service/servers                      */

	customServer = serviceType == "rtmp_custom";

	QComboBox *serviceList = streamPage->ui->service;

	if (!serviceName.empty()) {
		serviceList->blockSignals(true);

		int count = serviceList->count();
		bool found = false;

		for (int i = 0; i < count; i++) {
			QString name = serviceList->itemText(i);

			if (name == serviceName.c_str()) {
				serviceList->setCurrentIndex(i);
				found = true;
				break;
			}
		}

		if (!found) {
			serviceList->insertItem(0, serviceName.c_str());
			serviceList->setCurrentIndex(0);
		}

		serviceList->blockSignals(false);
	}

	streamPage->UpdateServerList();
	streamPage->UpdateKeyLink();
	streamPage->lastService.clear();

	if (!customServer) {
		QComboBox *serverList = streamPage->ui->server;
		int idx = serverList->findData(QString(server.c_str()));
		if (idx == -1)
			idx = 0;

		serverList->setCurrentIndex(idx);
	} else {
		streamPage->ui->customServer->setText(server.c_str());
		int idx = streamPage->ui->service->findData(
				QVariant((int)ListOpt::Custom));
		streamPage->ui->service->setCurrentIndex(idx);
	}

	if (!key.empty())
		streamPage->ui->key->setText(key.c_str());

	int bitrate = config_get_int(main->Config(), "SimpleOutput", "VBitrate");
	streamPage->ui->bitrate->setValue(bitrate);
	streamPage->ServiceChanged();

	TestHardwareEncoding();
	if (!hardwareEncodingAvailable) {
		delete streamPage->ui->preferHardware;
		streamPage->ui->preferHardware = nullptr;
	} else {
		/* Newer generations of NVENC have a high enough quality to
		 * bitrate ratio that if NVENC is available, it makes sense to
		 * just always prefer hardware encoding by default */
		bool preferHardware = nvencAvailable ||
		                      os_get_physical_cores() <= 4;
		streamPage->ui->preferHardware->setChecked(preferHardware);
	}

	setOptions(0);
	setButtonText(QWizard::FinishButton,
			QTStr("Basic.AutoConfig.ApplySettings"));
	setButtonText(QWizard::BackButton, QTStr("Back"));
	setButtonText(QWizard::NextButton, QTStr("Next"));
	setButtonText(QWizard::CancelButton, QTStr("Cancel"));
}
static bool update_remote_files(void *param, obs_data_t *remote_file)
{
	struct update_info *info = param;

	struct file_update_data data = {
		.name = obs_data_get_string(remote_file, "name"),
		.version = (int)obs_data_get_int(remote_file, "version")
	};

	enum_files(info->cache_package, newer_than_cache, &data);
	if (!data.newer && data.found)
		return true;

	if (!do_relative_http_request(info, info->remote_url, data.name))
		return true;

	if (info->callback) {
		struct file_download_data download_data;
		bool confirm;

		download_data.name = data.name;
		download_data.version = data.version;
		download_data.buffer.da = info->file_data.da;

		confirm = info->callback(info->param, &download_data);

		info->file_data.da = download_data.buffer.da;

		if (!confirm) {
			info("Update file '%s' (version %d) rejected",
					data.name, data.version);
			return true;
		}
	}

	write_file_data(info, info->temp, data.name);
	replace_file(info->temp, info->cache, data.name);

	info("Successfully updated file '%s' (version %d)",
			data.name, data.version);
	return true;
}

static void update_save_metadata(struct update_info *info)
{
	struct dstr path = { 0 };

	if (!info->etag_remote)
		return;

	dstr_copy(&path, info->cache);
	dstr_cat(&path, "meta.json");

	obs_data_t *data;
	data = obs_data_create();
	obs_data_set_string(data, "etag", info->etag_remote);
	obs_data_save_json(data, path.array);
	obs_data_release(data);
}

static void update_remote_version(struct update_info *info, int cur_version)
{
	int remote_version;
	long response_code;

	if (!do_http_request(info, info->url, &response_code))
		return;

	if (response_code == 304)
		return;

	if (!info->file_data.array || info->file_data.array[0] != '{') {
		warn("Remote package does not exist or is not valid json");
		return;
	}

	update_save_metadata(info);

	info->remote_package = obs_data_create_from_json(
			(char*)info->file_data.array);
	if (!info->remote_package) {
		warn("Failed to initialize remote package json");
		return;
	}

	remote_version = (int)obs_data_get_int(info->remote_package, "version");
	if (remote_version <= cur_version)
		return;

	write_file_data(info, info->temp, "package.json");

	info->remote_url = obs_data_get_string(info->remote_package, "url");
	if (!info->remote_url) {
		warn("No remote url in package file");
		return;
	}

	/* download new files */
	enum_files(info->remote_package, update_remote_files, info);

	replace_file(info->temp, info->cache, "package.json");

	info("Successfully updated package (version %d)", remote_version);
	return;
}
Beispiel #27
0
void ScriptsTool::on_addScripts_clicked()
{
	const char **formats = obs_scripting_supported_formats();
	const char **cur_format = formats;
	QString extensions;
	QString filter;

	while (*cur_format) {
		if (!extensions.isEmpty())
			extensions += QStringLiteral(" ");

		extensions += QStringLiteral("*.");
		extensions += *cur_format;

		cur_format++;
	}

	if (!extensions.isEmpty()) {
		filter += obs_module_text("FileFilter.ScriptFiles");
		filter += QStringLiteral(" (");
		filter += extensions;
		filter += QStringLiteral(")");
	}

	if (filter.isEmpty())
		return;

	static std::string lastBrowsedDir;

	if (lastBrowsedDir.empty()) {
		BPtr<char> baseScriptPath = obs_module_file("scripts");
		lastBrowsedDir = baseScriptPath;
	}

	QFileDialog dlg(this, obs_module_text("AddScripts"));
	dlg.setFileMode(QFileDialog::ExistingFiles);
	dlg.setDirectory(QDir(lastBrowsedDir.c_str()));
	dlg.setNameFilter(filter);
	dlg.exec();

	QStringList files = dlg.selectedFiles();
	if (!files.count())
		return;

	lastBrowsedDir = dlg.directory().path().toUtf8().constData();

	for (const QString &file : files) {
		QByteArray pathBytes = file.toUtf8();
		const char *path = pathBytes.constData();

		if (scriptData->ScriptOpened(path)) {
			continue;
		}

		obs_script_t *script = obs_script_create(path, NULL);
		if (script) {
			const char *script_file = obs_script_get_file(script);

			scriptData->scripts.emplace_back(script);

			QListWidgetItem *item = new QListWidgetItem(script_file);
			item->setData(Qt::UserRole, QString(file));
			ui->scripts->addItem(item);

			OBSData settings = obs_data_create();
			obs_data_release(settings);

			obs_properties_t *prop =
				obs_script_get_properties(script);
			obs_properties_apply_settings(prop, settings);
		}
	}
}
void BiLiTextSourcePropertyDlg::setupSourcePropertiesUI() {
	//注意:添加控件时,记得根据需要在最后添加控件的变动通知监视!
	//否则可能导致点了确定之后设置没有保存进去

	ui.PropertyNameLab->setText(tr("Text Property")); 


	//select from file
	auto FileTxtLayout = new QHBoxLayout();
	FileTxtLayout->setSpacing(0);
    FileTxtLayout->setContentsMargins(0, 0, 0, 0);

	FromFileCheckBox = new QCheckBox(ui.PropertyWid);
    FromFileCheckBox->setFixedHeight(13);
	FromFileCheckBox->setObjectName(QStringLiteral("FromFileCheckBox"));
	FromFileCheckBox->setProperty("FromFileCheckBox", qVPtr<QCheckBox>::toVariant(FromFileCheckBox) );

	auto BrowseFileBtn = new QPushButton(ui.PropertyWid);
	BrowseFileBtn->setObjectName(QStringLiteral("BrowseFileBtn"));
	QSizePolicy sizePolicyBrowseFileBtn(QSizePolicy::Fixed, QSizePolicy::Fixed);
	sizePolicyBrowseFileBtn.setHeightForWidth(BrowseFileBtn->sizePolicy().hasHeightForWidth());
	BrowseFileBtn->setSizePolicy(sizePolicyBrowseFileBtn);
	BrowseFileBtn->setMinimumSize(QSize(50, 25));
	BrowseFileBtn->setMaximumSize(QSize(50, 25));

	FilePathEdit = new QPlainTextEdit();
	FilePathEdit->setObjectName(QStringLiteral("FilePathEdit"));
	QSizePolicy sizePolicyFilePathEdit(QSizePolicy::Expanding, QSizePolicy::Fixed);
	sizePolicyFilePathEdit.setHorizontalStretch(0);
	sizePolicyFilePathEdit.setVerticalStretch(0);
	sizePolicyFilePathEdit.setHeightForWidth(FilePathEdit->sizePolicy().hasHeightForWidth());
	FilePathEdit->setSizePolicy(sizePolicyFilePathEdit);
	FilePathEdit->setFixedHeight(30);
	FilePathEdit->setReadOnly(true);
	connect(BrowseFileBtn, &QPushButton::clicked, [this](){
		QString path = QFileDialog::getOpenFileName(this, tr("Select File"),
			QDir::currentPath(), tr("TxtFile (*.txt *.int *.log )"));
		if (path.isEmpty())
			return;
		QFileInfo fileInfo(path);
		if (!fileInfo.isFile())
			return;
		FilePathEdit->setPlainText(path);
	});

    QSpacerItem *fileSpacer0 = new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *fileSpacer1 = new QSpacerItem(10, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    //QSpacerItem *fileSpacer2 = new QSpacerItem(4, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
	FileTxtLayout->addWidget(FromFileCheckBox);
    FileTxtLayout->addItem(fileSpacer0);
	FileTxtLayout->addWidget(BrowseFileBtn);
    FileTxtLayout->addItem(fileSpacer1);
	FileTxtLayout->addWidget(FilePathEdit);

	PlainTextEdit = new QPlainTextEdit();
	PlainTextEdit->setObjectName(QStringLiteral("PlainTextEdit"));
	QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
	sizePolicy.setHorizontalStretch(0);
	sizePolicy.setVerticalStretch(0);
	sizePolicy.setHeightForWidth(PlainTextEdit->sizePolicy().hasHeightForWidth());
	PlainTextEdit->setSizePolicy(sizePolicy);
	PlainTextEdit->setFixedHeight(60);
	connect(PlainTextEdit, SIGNAL(textChanged()), this, SLOT(mSltTxtChanged()));

	auto FontHLayout = new QHBoxLayout();
    FontHLayout->setSpacing(0);
    FontHLayout->setContentsMargins(0, 0, 27, 0);
	auto FontLab = new QLabel(ui.PropertyWid);
	FontLab->setObjectName(QStringLiteral("FontLab"));
	QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Fixed);
	sizePolicy1.setHorizontalStretch(0);
	sizePolicy1.setVerticalStretch(0);
	sizePolicy1.setHeightForWidth(FontLab->sizePolicy().hasHeightForWidth());
	FontLab->setSizePolicy(sizePolicy1);
	FontLab->setMinimumSize(QSize(62, 30));
	FontLab->setMaximumSize(QSize(62, 30));
	FontLab->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
	FontHLayout->addWidget(FontLab);

    QSpacerItem *FontHLayout_spacer_h0 = new QSpacerItem(4, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    FontHLayout->addItem(FontHLayout_spacer_h0);

	FontComboBox = new QFontComboBox(ui.PropertyWid);
    FontComboBox->setFixedSize(142, 30);
	FontComboBox->setObjectName(QStringLiteral("FontComboBox"));
	FontComboBox->setStyleSheet(QStringLiteral(""));
	FontHLayout->addWidget(FontComboBox);
	connect(FontComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(mSltFontComboxChanged(const QString &)));

    QSpacerItem *FontHLayout_spacer_h1 = new QSpacerItem(30, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    FontHLayout->addItem(FontHLayout_spacer_h1);

	auto ColorLab = new QLabel(ui.PropertyWid);
	ColorLab->setObjectName(QStringLiteral("ColorLab"));
	sizePolicy1.setHeightForWidth(ColorLab->sizePolicy().hasHeightForWidth());
	ColorLab->setSizePolicy(sizePolicy1);
    ColorLab->setMinimumSize(QSize(40, 30));
    ColorLab->setMaximumSize(QSize(40, 30));
	ColorLab->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
	FontHLayout->addWidget(ColorLab);

    QSpacerItem *FontHLayout_spacer_h2 = new QSpacerItem(4, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    FontHLayout->addItem(FontHLayout_spacer_h2);

    QVBoxLayout *ColorChangeBtn_layout = new QVBoxLayout();
    ColorChangeBtn_layout->setSpacing(0);
    ColorChangeBtn_layout->setContentsMargins(0, 5, 0, 5);
	ColorChangeBtn = new QPushButton(ui.PropertyWid);
	ColorChangeBtn->setObjectName(QStringLiteral("ColorChangeBtn"));
	sizePolicy1.setHeightForWidth(ColorChangeBtn->sizePolicy().hasHeightForWidth());
	ColorChangeBtn->setSizePolicy(sizePolicy1);
	ColorChangeBtn->setMinimumSize(QSize(30, 20));
	ColorChangeBtn->setMaximumSize(QSize(30, 20));
    ColorChangeBtn_layout->addWidget(ColorChangeBtn);
    FontHLayout->addLayout(ColorChangeBtn_layout);
	connect(ColorChangeBtn, &QPushButton::clicked, this, &BiLiTextSourcePropertyDlg::mSltColorChangeBtn);

    auto StyleHSpacer1 = new QSpacerItem(4, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    auto StyleHSpacer2 = new QSpacerItem(30, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
	auto StyleHLayout = new QHBoxLayout();
    StyleHLayout->setContentsMargins(0, 0, 151, 0);
    StyleHLayout->setSpacing(0);
	auto StyleLab = new QLabel(ui.PropertyWid);
	StyleLab->setObjectName(QStringLiteral("StyleLab"));
	sizePolicy1.setHeightForWidth(StyleLab->sizePolicy().hasHeightForWidth());
	StyleLab->setSizePolicy(sizePolicy1);
	StyleLab->setMinimumSize(QSize(62, 13));
	StyleLab->setMaximumSize(QSize(62, 13));
	StyleLab->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
	StyleHLayout->addWidget(StyleLab);
	StyleHLayout->addItem(StyleHSpacer1);

	auto BoldStyleCheckBox = new QCheckBox(ui.PropertyWid);
    BoldStyleCheckBox->setFixedHeight(13);
	BoldStyleCheckBox->setObjectName(QStringLiteral("BoldStyleCheckBox"));
	StyleHLayout->addWidget(BoldStyleCheckBox);
	auto ItalicCheckBox = new QCheckBox(ui.PropertyWid);
    ItalicCheckBox->setFixedHeight(13);
	ItalicCheckBox->setObjectName(QStringLiteral("ItalicCheckBox"));
	StyleHLayout->addItem(StyleHSpacer2);
	StyleHLayout->addWidget(ItalicCheckBox);
	FontComboBox->setProperty("BoldStyleCheckBox", qVPtr<QCheckBox>::toVariant(BoldStyleCheckBox) );
	FontComboBox->setProperty("ItalicCheckBox", qVPtr<QCheckBox>::toVariant(ItalicCheckBox) );

	auto OpacitySliderHLayout = new QHBoxLayout();
    OpacitySliderHLayout->setSpacing(0);
    OpacitySliderHLayout->setContentsMargins(0, 0, 0, 0);
	auto OpacityLabel = new QLabel();
	OpacityLabel->setObjectName("OpacityLabel");
	OpacityLabel->setText(QApplication::translate("TextAddForm", "Opacity:", 0));
	OpacityLabel->setMinimumSize(QSize(62, 16));
	OpacityLabel->setMaximumSize(QSize(62, 16));
	OpacityLabel->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
	OpacityValLabel = new QLabel();
	OpacityValLabel->setObjectName("OpacityValLabel");
	OpacityValLabel->setFixedSize(38, 16);
	OpacityValLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
	auto OpacitySlider = new CircleSliderSlider(this);
    OpacitySlider->setFixedWidth(150);
	OpacitySlider->setRange(0, 255, 0); 
    QSpacerItem *OpacitySliderHLayout_spacer0 = new QSpacerItem(4, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *OpacitySliderHLayout_spacer1 = new QSpacerItem(8, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *OpacitySliderHLayout_spacer2 = new QSpacerItem(8, 10, QSizePolicy::Expanding, QSizePolicy::Fixed);

	OpacitySliderHLayout->addWidget(OpacityLabel);
    OpacitySliderHLayout->addItem(OpacitySliderHLayout_spacer0);
	OpacitySliderHLayout->addWidget(OpacitySlider);
    OpacitySliderHLayout->addItem(OpacitySliderHLayout_spacer1);
	OpacitySliderHLayout->addWidget(OpacityValLabel);
    OpacitySliderHLayout->addItem(OpacitySliderHLayout_spacer2);
	ColorChangeBtn->setProperty("OpacitySlider", qVPtr<CircleSliderSlider>::toVariant(OpacitySlider));
	ColorChangeBtn->setProperty("OpacityValLabel", qVPtr<QLabel>::toVariant(OpacityValLabel) );

    QSpacerItem *ScrollSpeedSliderHLayout_spacer0 = new QSpacerItem(4, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *ScrollSpeedSliderHLayout_spacer1 = new QSpacerItem(8, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *ScrollSpeedSliderHLayout_spacer2 = new QSpacerItem(8, 10, QSizePolicy::Expanding, QSizePolicy::Fixed);
	auto ScrollSpeedSliderHLayout = new QHBoxLayout();
    ScrollSpeedSliderHLayout->setSpacing(0);
    ScrollSpeedSliderHLayout->setContentsMargins(0, 0, 0, 0);
	auto ScrollSpeedLabel = new QLabel();
	ScrollSpeedLabel->setObjectName("ScrollSpeedLabel");
	ScrollSpeedLabel->setText(QApplication::translate("TextAddForm", "ScrollSpeed:", 0));
	ScrollSpeedLabel->setMinimumSize(QSize(62, 16));
	ScrollSpeedLabel->setMaximumSize(QSize(62, 16));
	ScrollSpeedLabel->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);

	ScrollSpeedValLabel = new QLabel();
	ScrollSpeedValLabel->setObjectName("ScrollSpeedValLabel");
	ScrollSpeedSlider = new CircleSliderSlider(nullptr);
    ScrollSpeedSlider->setFixedWidth(150);
	ScrollSpeedValLabel->setFixedWidth(38);
    ScrollSpeedValLabel->setFixedHeight(16);
	ScrollSpeedValLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
	ScrollSpeedSlider->setRange(0, 300, 0);

	ScrollSpeedSliderHLayout->addWidget(ScrollSpeedLabel);
    ScrollSpeedSliderHLayout->addItem(ScrollSpeedSliderHLayout_spacer0);
	ScrollSpeedSliderHLayout->addWidget(ScrollSpeedSlider);
    ScrollSpeedSliderHLayout->addItem(ScrollSpeedSliderHLayout_spacer1);
	ScrollSpeedSliderHLayout->addWidget(ScrollSpeedValLabel);
    ScrollSpeedSliderHLayout->addItem(ScrollSpeedSliderHLayout_spacer2);

	auto MainVLayout = new QVBoxLayout(ui.PropertyWid);
	MainVLayout->setObjectName(QStringLiteral("MainVLayout"));
	MainVLayout->setContentsMargins(14, 20, 14, 30);
    MainVLayout->setSpacing(0);

	QSpacerItem *spacer_v0 = new QSpacerItem(10, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *spacer_v1 = new QSpacerItem(10, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *spacer_v2 = new QSpacerItem(10, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *spacer_v3 = new QSpacerItem(10, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);
    QSpacerItem *spacer_v4 = new QSpacerItem(10, 20, QSizePolicy::Fixed, QSizePolicy::Fixed);

	MainVLayout->addWidget(PlainTextEdit);
	MainVLayout->addItem(spacer_v0);
	MainVLayout->addLayout(FileTxtLayout);
	MainVLayout->addItem(spacer_v4);
	MainVLayout->addLayout(FontHLayout);
    MainVLayout->addItem(spacer_v1);
	MainVLayout->addLayout(StyleHLayout);
    MainVLayout->addItem(spacer_v2);
	MainVLayout->addLayout(OpacitySliderHLayout);
    MainVLayout->addItem(spacer_v3);
	MainVLayout->addLayout(ScrollSpeedSliderHLayout);

	FontLab->setText(QApplication::translate("TextAddForm", "Font:", 0));
	ColorLab->setText(QApplication::translate("TextAddForm", "Color:", 0));
	StyleLab->setText(QApplication::translate("TextAddForm", "Style:", 0));
	BoldStyleCheckBox->setText(QApplication::translate("TextAddForm", "Bold", 0));
	ItalicCheckBox->setText(QApplication::translate("TextAddForm", "Italic", 0));
	FromFileCheckBox->setText(QApplication::translate("TextAddForm", "FromFile", 0));
	BrowseFileBtn->setText(QApplication::translate("TextAddForm", "Browse", 0));

	QMetaObject::connectSlotsByName(ui.PropertyWid);

	obs_data_t* settings = obs_source_get_settings(mSrc);
	DataToWidget(BILI_DATA_FONT(), FontComboBox, settings, "font");
	DataToWidget(BILI_DATA_INT(), ColorChangeBtn, settings, "color1");
	DataToWidget(BILI_DATA_STRING(), PlainTextEdit, settings, "text");
	DataToWidget(BILI_DATA_STRING(), FilePathEdit, settings, "text_file");
	DataToWidget(BILI_DATA_BOOL(), FromFileCheckBox, settings, "from_file");
	obs_data_release(settings);

	//为文字源创建filter
	scrollFilter = obs_source_get_filter_by_name(mSrc, scroll_filter_id);
	if (!scrollFilter)
	{
		scrollFilter = obs_source_create(OBS_SOURCE_TYPE_FILTER, scroll_filter_id, scroll_filter_id, 0, 0);
		obs_source_filter_add(mSrc, scrollFilter);
		obs_data_t* settings = obs_data_create();
		obs_data_set_bool(settings, "disable_repeat_if_no_speed", true);
		obs_source_update(scrollFilter, settings);
		obs_data_release(settings);
	}

	QObject::connect(ScrollSpeedSlider, &CircleSliderSlider::valueChanged, this, &BiLiTextSourcePropertyDlg::OnScrollSpeedSliderChanged);

	QObject::connect(OpacitySlider, &CircleSliderSlider::valueChanged, this, &BiLiTextSourcePropertyDlg::OnOpacitySliderChanged);

	//读取filter设置
	FilterDataToWidget(BILI_DATA_DOUBLE(), ScrollSpeedSlider, mSrc, scroll_filter_id, "speed_x");
	//读取透明度设置
	settings = obs_source_get_settings(mSrc);
	int64_t color1 = obs_data_get_int(settings, "color1");
	obs_data_release(settings);
	int opacity = (color1 >> 24) & 0xff;
	OpacitySlider->setValue(opacity);

	ScrollSpeedValLabel->setText(QString("%1%").arg(ScrollSpeedSlider->value()));
	OpacityValLabel->setText(QString("%1%").arg(OpacitySlider->value() * 100 / 255));

	//添加监听控件变动
	mChangeEvnetFilter->Watch({ PlainTextEdit, FontComboBox, /*ColorChangeBtn, */BoldStyleCheckBox, ItalicCheckBox, OpacitySlider, ScrollSpeedSlider, FromFileCheckBox, FilePathEdit  });
	connect(mChangeEvnetFilter.get(), SIGNAL(OnChangedSignal()), this, SLOT(mSltOnSettingChanged()));
}
bool AutoConfigStreamPage::validatePage()
{
	OBSData service_settings = obs_data_create();
	obs_data_release(service_settings);

	wiz->customServer = IsCustom();

	const char *serverType = wiz->customServer
		? "rtmp_custom"
		: "rtmp_common";

	if (!wiz->customServer) {
		obs_data_set_string(service_settings, "service",
				QT_TO_UTF8(ui->service->currentText()));
	}

	OBSService service = obs_service_create(serverType, "temp_service",
			service_settings, nullptr);
	obs_service_release(service);

	int bitrate = 10000;
	if (!ui->doBandwidthTest->isChecked()) {
		bitrate = ui->bitrate->value();
		wiz->idealBitrate = bitrate;
	}

	OBSData settings = obs_data_create();
	obs_data_release(settings);
	obs_data_set_int(settings, "bitrate", bitrate);
	obs_service_apply_encoder_settings(service, settings, nullptr);

	if (wiz->customServer) {
		QString server = ui->customServer->text();
		wiz->server = wiz->serverName = QT_TO_UTF8(server);
	} else {
		wiz->serverName = QT_TO_UTF8(ui->server->currentText());
		wiz->server = QT_TO_UTF8(ui->server->currentData().toString());
	}

	wiz->bandwidthTest = ui->doBandwidthTest->isChecked();
	wiz->startingBitrate = (int)obs_data_get_int(settings, "bitrate");
	wiz->idealBitrate = wiz->startingBitrate;
	wiz->regionUS = ui->regionUS->isChecked();
	wiz->regionEU = ui->regionEU->isChecked();
	wiz->regionAsia = ui->regionAsia->isChecked();
	wiz->regionOther = ui->regionOther->isChecked();
	wiz->serviceName = QT_TO_UTF8(ui->service->currentText());
	if (ui->preferHardware)
		wiz->preferHardware = ui->preferHardware->isChecked();
	wiz->key = QT_TO_UTF8(ui->key->text());

	if (!wiz->customServer) {
		if (wiz->serviceName == "Twitch")
			wiz->service = AutoConfig::Service::Twitch;
		else if (wiz->serviceName == "Smashcast")
			wiz->service = AutoConfig::Service::Smashcast;
		else
			wiz->service = AutoConfig::Service::Other;
	} else {
		wiz->service = AutoConfig::Service::Other;
	}

	if (wiz->service != AutoConfig::Service::Twitch && wiz->bandwidthTest) {
		QMessageBox::StandardButton button;
#define WARNING_TEXT(x) QTStr("Basic.AutoConfig.StreamPage.StreamWarning." x)
		button = OBSMessageBox::question(this,
				WARNING_TEXT("Title"),
				WARNING_TEXT("Text"));
#undef WARNING_TEXT

		if (button == QMessageBox::No)
			return false;
	}

	return true;
}