OBS源
+ -

OSB用户菜单枚举显示所有输入源类型

2024-03-21 41 0

在OBS中,任意右键,会弹出如下类似的菜单:
163302142677
通过本人的猜测,对应的函数应为:

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

其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="音频输入采集大西瓜"

音频输入采集大西瓜

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!