OSB用户菜单枚举显示所有输入源类型
2024-03-21
41
0
在OBS中,任意右键,会弹出如下类似的菜单:
通过本人的猜测,对应的函数应为:
void OBSBasic::on_sources_customContextMenuRequested(const QPoint &pos)
{
if (ui->scenes->count()) {
QModelIndex idx = ui->sources->indexAt(pos);
CreateSourcePopupMenu(idx.row(), false);
}
}
最终调用的是CreateSourcePopupMenu,在它里面有动态创建右键菜单的功能。
函数调用关系如下:
- on_sources_customContextMenuRequested
- CreateSourcePopupMenu
-CreateAddSourcePopupMenu
- CreateSourcePopupMenu
其CreateAddSourcePopupMenu函数中添加”源“的菜单中的代码如下:
QMenu popup(this);
...
//创建【添加】子菜单
QPointer<QMenu> addSourceMenu = CreateAddSourcePopupMenu();
if (addSourceMenu)
popup.addMenu(addSourceMenu);
CreateAddSourcePopupMenu函数中枚举所有的源,并添加:
while (obs_enum_input_types2(idx++, &type, &unversioned_type)) {
const char *name = obs_source_get_display_name(type);
uint32_t caps = obs_get_source_output_flags(type);
if ((caps & OBS_SOURCE_CAP_DISABLED) != 0)
continue;
if ((caps & OBS_SOURCE_DEPRECATED) == 0) {
addSource(popup, unversioned_type, name);
} else {
addSource(deprecated, unversioned_type, name);
foundDeprecated = true;
}
foundValues = true;
}
其中obs_enum_input_types2这个函数,就是从数组中找到通过obs_register_source注册的添,并获取指定索引源的相关信息。
bool obs_enum_input_types2(size_t idx, const char **id,
const char **unversioned_id)
{
if (idx >= obs->input_types.num)
return false;
if (id)
*id = obs->input_types.array[idx].id;
if (unversioned_id)
*unversioned_id = obs->input_types.array[idx].unversioned_id;
return true;
}
函数中:
- idx:表示在数组中的索引位置。从0开始到input_types.num。
- id:各个源注册时,自己提供的ID,字符串类型。 如.id = “color_source”,
- unversioned_id:
/* set internally, don't set manually */
另外,这里只是枚举的是输入类型的input_types,而不是全部source_types。所以只有类型是OBS_SOURCE_TYPE_INPUT会枚举到。
最后在CreateAddSourcePopupMenu中调用
const char *name = obs_source_get_display_name(type);
uint32_t caps = obs_get_source_output_flags(type);
获取名称和标识。
const char *obs_source_get_display_name(const char *id)
{
const struct obs_source_info *info = get_source_info(id);
return (info != NULL) ? info->get_name(info->type_data) : NULL;
}
uint32_t obs_get_source_output_flags(const char *id)
{
const struct obs_source_info *info = get_source_info(id);
return info ? info->output_flags : 0;
}
将这些信息通过addSource添加到菜单中。
auto addSource = [this, getActionAfter](QMenu *popup, const char *type,
const char *name) {
QString qname = QT_UTF8(name);
QAction *popupItem = new QAction(qname, this);
connect(popupItem, &QAction::triggered, [this, type]() { AddSource(type); });
QIcon icon;
if (strcmp(type, "scene") == 0)
icon = GetSceneIcon();
else
icon = GetSourceIcon(type);
popupItem->setIcon(icon);
QAction *after = getActionAfter(popup, qname);
popup->insertAction(after, popupItem);
};
最后,也增加了场景scene到菜单中。
addSource(popup, "scene", Str("Basic.Scene"));
WASAPI插件
WASAPI模块插件其get_name对应的函数分别为:
void RegisterWASAPIInput(){
info.get_name = GetWASAPIInputName;
}
void RegisterWASAPIDeviceOutput()
{
info.get_name = GetWASAPIDeviceOutputName;
}
static const char *GetWASAPIInputName(void *)
{
return obs_module_text("AudioInput");
}
static const char *GetWASAPIDeviceOutputName(void *)
{
return obs_module_text("AudioOutput");
}
我们在OBS的资源中:
"C:\Program Files\obs-studio\data\obs-plugins\win-wasapi\locale\zh-CN.ini"
文件中可以看到如下内容:
AudioInput="音频输入采集"
AudioOutput="音频输出采集"
ApplicationAudioCapture="应用音频采集"
Device="设备"
Default="默认"
UseDeviceTiming="使用设备时间戳"
Window="窗口"
Priority="窗口匹配优先级"
Priority.Title="窗口标题必须匹配"
Priority.Class="匹配标题,否则查找相同类型的窗口"
Priority.Exe="匹配标题,否则查找相同可执行程序的窗口"
当我试着把AudioInput的内容改了之后,再重启OBS就变成了这样
AudioInput="音频输入采集大西瓜"