OBS源实例的添加
2024-03-22
10
0
上一节知道,在OBS中任右键,会弹出一菜单,可以添加通过插件模块注册的各种”源“
当在菜单中选中某种类型的”源“之后,就会调用:
void OBSBasic::AddSource(const char *id)
{
if (id && *id) {
OBSBasicSourceSelect sourceSelect(this, id, undo_s);
sourceSelect.exec();
if (should_show_properties(sourceSelect.newSource, id)) {
CreatePropertiesWindow(sourceSelect.newSource);
}
}
}
使用OBSBasicSourceSelect弹出结话框
点击确认后,执行的是函数
void OBSBasicSourceSelect::on_buttonBox_accepted()
该函数会根据是新建还是添加现在执行不同的流程,以新建为示例:
if (ui->sourceName->text().isEmpty()) {
//C:\Program Files\obs-studio\data\obs-studio\locale\zh_CN.ini
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),//请输入一个有效的名称
QTStr("NoNameEntered.Text")); //您不能使用空白名称。
return;
}
//成员变量 const char *id;
if (!AddNew(this, id, QT_TO_UTF8(ui->sourceName->text()),visible, newSource))
return;
使用AddNew添加新源,而newSource以引用的方式返回,即OBSBasicSourceSelect的成员变量newSource
所对应
OBSBasic::AddSource(const char *id)
函数中的
if (should_show_properties(sourceSelect.newSource, id)) {
CreatePropertiesWindow(sourceSelect.newSource);
}
最后,使用AddNew函数创建新的源。
AddNew的大概原理是:
1.通过source的名称查找是否名字冲突。函数使用的是obs_get_source_by_name
OBSSourceAutoRelease source = obs_get_source_by_name(name);
if (source && parent) {
OBSMessageBox::information(parent, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
}
如果未冲突,则:
2.使用函数obs_get_latest_input_type_id获取该id类型最新的版本(OBS可能存在新老ID其存的情况,这里取最新的)
const char *obs_get_latest_input_type_id(const char *unversioned_id)
{
struct obs_source_info *latest = NULL;
int version = -1;
if (!unversioned_id)
return NULL;
for (size_t i = 0; i < obs->source_types.num; i++) {
struct obs_source_info *info = &obs->source_types.array[i];
if (strcmp(info->unversioned_id, unversioned_id) == 0
&& (int)info->version > version) {
latest = info;
version = info->version;
}
}
assert(!!latest);
if (!latest)
return NULL;
return latest->id;
}
3.根据找到的最新的id,使用obs_source_create函数创建对象。
OBSSourceAutoRelease source = obs_source_create(v_id, name, NULL, nullptr);
如果创建成功,则将该source加入sence中
if (source) {
AddSourceData data;
data.source = source;
data.visible = visible;
obs_enter_graphics();
obs_scene_atomic_update(scene, AddSource, &data);
obs_leave_graphics();
...
success = true;
}
而这里的scene是当前主窗口的当前选中的场景
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
这里我们再梳理一下OBS-UI的框架
- OBSBasic main
- OBSScene scene
- OBSGroup OBS可以建组,组中可以包括多个OSBSource
- OSBSource
- OBSBasicSourceSelect 创建源对话框
- OBSScene scene