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