Skip to content

Desuq Cafe

文档菜单

此翻译可能落后于最新的英文版本。 查看英文版

架构与开发者参考

本页面是面向开发者的”底层原理”参考文档,供需要扩展插件的开发者使用。内容涵盖模块结构、基于处理器的客户端、Sequencer 集成、编辑器细节面板系统、关键类型,以及新增功能的实现模式。

如需查看原生 C++ 委托的完整列表(即带有 Native 后缀、支持 lambda 绑定的事件),请参阅 原生委托

模块结构

该插件由三个模块组成:

模块类型用途
InhyeongOBSWebSocketRuntime核心功能、Subsystem、组件、Sequencer 集成
InhyeongOBSWebSocketEditorEditor细节面板定制、Editor Subsystem、Sequencer 轨道编辑器
InhyeongOBSWebSocketTakeRecorderEditorTake Recorder 同步(在 PostEngineInit 时加载,仅当 Takes plugin 启用时)

Take Recorder 同步配置

设置存储于 Config/DefaultInhyeongOBS.ini

[/Script/InhyeongOBSWebSocketTakeRecorder.InhyeongOBSTakeRecorderSync]
bEnabled=True
bShowNotifications=True
bWarnIfOBSNotConnected=True
bAutoStartRecord=True
bAutoStopRecord=True
PostRollSeconds=0.000000
bAutoStartVirtualCam=False
bAutoStopVirtualCam=False
bAutoStartStream=False
bAutoStopStream=False
bSwitchSceneOnStart=False
StartSceneName=
bSwitchSceneOnStop=False
StopSceneName=
bCreateChaptersOnMarkedFrames=True
bAddStartChapterWithMetadata=True
bMatchRecordDirectory=False
bLogFileCorrelation=True

工具类

位置用途
FOBSRequestBatchBuilderUtilities/流式构建批处理请求
FOBSJsonBuilderUtilities/流式构建 JSON 对象

请求类型常量

所有 OBS WebSocket 请求类型与字段名均集中定义于 Core/Types/InhyeongOBSRequestTypes.h

#include "Core/Types/InhyeongOBSRequestTypes.h"

// Request types
OBSRequests::GetSceneList            // "GetSceneList"
OBSRequests::SetCurrentProgramScene  // "SetCurrentProgramScene"
OBSRequests::StartRecord             // "StartRecord"

// Field names
OBSFields::SceneName                 // "sceneName"
OBSFields::InputName                 // "inputName"
OBSFields::SceneItemId               // "sceneItemId"

这样可以避免拼写错误,也便于管理协议升级。

JSON 构建工具

FOBSJsonBuilder 为 OBS 请求提供流式 JSON 构建能力:

#include "Utilities/InhyeongOBSJsonBuilder.h"

// Basic usage
TSharedPtr<FJsonObject> Data = FOBSJsonBuilder::Create()
    .Add(TEXT("sceneName"), SceneName)
    .Add(TEXT("sceneItemId"), SceneItemId)
    .Add(TEXT("sceneItemEnabled"), true)
    .Build();

// Conditional additions
TSharedPtr<FJsonObject> Settings = FOBSJsonBuilder::Create()
    .Add(TEXT("sourceName"), SourceName)
    .Add(TEXT("imageFormat"), TEXT("png"))
    .AddIfPositive(TEXT("imageWidth"), Width)      // Only adds if > 0
    .AddIfPositive(TEXT("imageHeight"), Height)
    .AddIfInRange(TEXT("imageCompressionQuality"), Quality, 0, 100)
    .Build();

// Nested objects
TSharedPtr<FJsonObject> Transform = FOBSJsonBuilder::Create()
    .Add(TEXT("positionX"), 100.0f)
    .Add(TEXT("positionY"), 200.0f)
    .Build();

TSharedPtr<FJsonObject> Request = FOBSJsonBuilder::Create()
    .Add(TEXT("sceneName"), SceneName)
    .Add(TEXT("sceneItemId"), ItemId)
    .Add(TEXT("sceneItemTransform"), Transform)
    .Build();

可用方法:

方法说明
Add(Key, Value)添加 string、int32、int64、float、double、bool 或 JSON 对象
AddIfNotEmpty(Key, String)仅在字符串非空时添加
AddIfPositive(Key, Number)仅在数值 > 0 时添加
AddIfInRange(Key, Value, Min, Max)仅在值处于范围内时添加
Build()返回构建完成的 TSharedPtr<FJsonObject>
HasFields()检查是否已添加任何字段

处理器架构

WebSocket 客户端采用模块化处理器进行组织:

UInhyeongOBSWebSocketClient
├── UInhyeongOBSOutputs       (Stream, Record, VirtualCam, ReplayBuffer)
├── UInhyeongOBSScenes        (Scene switching, scene items)
├── UInhyeongOBSAudio         (Audio inputs, volume, mute)
├── UInhyeongOBSInputSettings (Text, browser, image, media source settings)
├── UInhyeongOBSMediaInputs   (Media playback control)
├── UInhyeongOBSStudioMode    (Preview scene, studio transitions)
├── UInhyeongOBSTransitions   (Scene transitions, duration, settings)
├── UInhyeongOBSFilters       (Source filter management)
├── UInhyeongOBSScreenshots   (Screenshot capture and texture conversion)
├── UInhyeongOBSConfig        (Scene collections, profiles, video settings, persistent data)
└── UInhyeongOBSGeneral       (Stats, hotkeys, vendor requests, custom events)

通过以下方式访问各处理器:

Client->GetOutputs()
Client->GetScenes()
Client->GetAudio()
Client->GetInputSettings()
Client->GetMediaInputs()
Client->GetStudioMode()
Client->GetTransitions()
Client->GetFilters()
Client->GetScreenshots()
Client->GetConfig()
Client->GetGeneral()

Sequencer 架构

Sequencer 集成遵循 Unreal 的 movie scene 模式:

Runtime Module (InhyeongOBSWebSocket)
├── EventTriggersTrack/                   Discrete action tracks
│   ├── UMovieSceneOBSTrack              Track container with playback settings
│   ├── UMovieSceneOBSSection            Section with action parameters
│   ├── FMovieSceneOBSTemplate           Evaluation template (boundary detection)
│   ├── FOBSExecutionToken               Execution token for firing actions
│   └── PreAnimatedState/                State restoration handlers
│       ├── FOBSOutputPreAnimatedState
│       ├── FOBSScenesPreAnimatedState
│       ├── FOBSAudioPreAnimatedState
│       ├── FOBSTransitionsPreAnimatedState
│       ├── FOBSStudioModePreAnimatedState
│       ├── FOBSFiltersPreAnimatedState
│       └── FOBSSourcesPreAnimatedState
├── KeyframeableTrack/                   Interpolated property tracks
│   ├── Audio/
│   │   ├── UMovieSceneOBSVolumeTrack    Volume track (targets InputName)
│   │   ├── UMovieSceneOBSVolumeSection  Float channel for volume dB
│   │   ├── FMovieSceneOBSVolumeTemplate Continuous evaluation
│   │   ├── FOBSVolumePreAnimatedState   Capture/restore volume
│   │   ├── UMovieSceneOBSBalanceTrack   Balance track (targets InputName)
│   │   ├── UMovieSceneOBSBalanceSection Float channel for L/R balance
│   │   ├── FMovieSceneOBSBalanceTemplate Continuous evaluation
│   │   └── FOBSBalancePreAnimatedState  Capture/restore balance
│   ├── Scene/
│   │   ├── UMovieSceneOBSTransformTrack Transform track (targets Scene+Source)
│   │   ├── UMovieSceneOBSTransformSection Float/Int channels for transform
│   │   ├── FMovieSceneOBSTransformTemplate Continuous evaluation
│   │   └── FOBSTransformPreAnimatedState Capture/restore transform
│   ├── Sources/
│   │   ├── UMovieSceneOBSColorSourceTrack    Color source track (targets InputName)
│   │   ├── UMovieSceneOBSColorSourceSection  4 float channels for RGBA
│   │   ├── FMovieSceneOBSColorSourceTemplate Continuous evaluation, ABGR conversion
│   │   └── FOBSColorSourcePreAnimatedState   Capture/restore with format conversion
│   ├── Media/
│   │   ├── UMovieSceneOBSMediaCursorTrack    Media cursor track (targets InputName)
│   │   ├── UMovieSceneOBSMediaCursorSection  Single float channel for cursor (ms)
│   │   ├── FMovieSceneOBSMediaCursorTemplate Continuous evaluation, float→int64
│   │   └── FOBSMediaCursorPreAnimatedState   Capture/restore cursor position
│   ├── Filters/
│   │   ├── UMovieSceneOBSFilterSettingTrack    Generic filter setting track (targets Source+Filter+Setting)
│   │   ├── UMovieSceneOBSFilterSettingSection  Float channel for any numeric setting
│   │   ├── FMovieSceneOBSFilterSettingTemplate Continuous evaluation with JSON overlay
│   │   ├── FOBSFilterSettingPreAnimatedState   Capture/restore from filter cache
│   │   └── FOBSCommonFilterSettings            UI hints for known filter types
│   └── Transitions/
│       ├── UMovieSceneOBSTransitionDurationTrack    Duration track (current transition)
│       ├── UMovieSceneOBSTransitionDurationSection  Float channel for duration ms
│       ├── FMovieSceneOBSTransitionDurationTemplate Continuous evaluation, handles fixed transitions
│       └── FOBSTransitionDurationPreAnimatedState   Capture/restore duration
├── ContinuousStateTrack/                State-holding tracks (no keyframes)
│   ├── Audio/
│   │   ├── OBSMuteStatePreAnimatedState             Capture/restore mute state
│   │   ├── MovieSceneOBSMuteStateSection            Section with bMuteState property
│   │   ├── MovieSceneOBSMuteStateTrack              Track targeting InputName
│   │   ├── MovieSceneOBSMuteStateTemplate           Setup/Evaluate/TearDown
│   │   ├── OBSMonitorTypeStatePreAnimatedState      Capture/restore monitor type
│   │   ├── MovieSceneOBSMonitorTypeStateSection     Section with MonitorType enum
│   │   ├── MovieSceneOBSMonitorTypeStateTrack       Track targeting InputName
│   │   └── MovieSceneOBSMonitorTypeStateTemplate    Setup/Evaluate/TearDown
│   ├── Scene/
│   │   ├── OBSVisibilityStatePreAnimatedState       Capture/restore visibility
│   │   ├── MovieSceneOBSVisibilityStateSection      Section with bVisible property
│   │   ├── MovieSceneOBSVisibilityStateTrack        Track targeting Scene+ItemId
│   │   ├── MovieSceneOBSVisibilityStateTemplate     Setup/Evaluate/TearDown
│   │   ├── OBSBlendModeStatePreAnimatedState        Capture/restore blend mode
│   │   ├── MovieSceneOBSBlendModeStateSection       Section with BlendMode enum
│   │   ├── MovieSceneOBSBlendModeStateTrack         Track targeting Scene+ItemId
│   │   ├── MovieSceneOBSBlendModeStateTemplate      Setup/Evaluate/TearDown
│   │   ├── OBSLockStatePreAnimatedState             Capture/restore lock state
│   │   ├── MovieSceneOBSLockStateSection            Section with bLocked property
│   │   ├── MovieSceneOBSLockStateTrack              Track targeting Scene+ItemId
│   │   └── MovieSceneOBSLockStateTemplate           Setup/Evaluate/TearDown
│   ├── Filter/
│   │   ├── OBSFilterEnabledStatePreAnimatedState    Capture/restore filter enabled
│   │   ├── MovieSceneOBSFilterEnabledStateSection   Section with bEnabled property
│   │   ├── MovieSceneOBSFilterEnabledStateTrack     Track targeting Source+Filter
│   │   └── MovieSceneOBSFilterEnabledStateTemplate  Setup/Evaluate/TearDown
│   ├── StudioMode/
│   │   ├── OBSStudioModeStatePreAnimatedState       Capture/restore studio mode
│   │   ├── MovieSceneOBSStudioModeStateSection      Section with bEnabled property
│   │   ├── MovieSceneOBSStudioModeStateTrack        Global track (no target)
│   │   └── MovieSceneOBSStudioModeStateTemplate     Setup/Evaluate/TearDown
│   └── Transitions/
│       ├── OBSTransitionStatePreAnimatedState       Capture/restore current transition
│       ├── MovieSceneOBSTransitionStateSection      Section (presence = apply)
│       ├── MovieSceneOBSTransitionStateTrack        Track with TransitionName target
│       └── MovieSceneOBSTransitionStateTemplate     Setup/Evaluate/TearDown
├── MediaSyncTrack/                      Timeline-synchronized media playback
│   ├── OBSMediaSyncPreAnimatedState                 Capture/restore media state+position
│   ├── MovieSceneOBSMediaSyncSection                Section defines sync window
│   ├── MovieSceneOBSMediaSyncTrack                  Track targeting MediaInputName
│   └── MovieSceneOBSMediaSyncTemplate               Play/pause/seek synchronization
Editor Module (InhyeongOBSWebSocketEditor)
├── Sequencer/
│   ├── Shared/
│   │   └── OBSSequencerMenuRegistry         Centralized menu building (prevents duplicates)
│   ├── EventTriggersTrack/
│   │   ├── FMovieSceneOBSTrackEditor        Track editor for event trigger
│   │   └── FMovieSceneOBSSectionInterface   Section display
│   ├── KeyframeableTrack/
│   │   ├── FOBSKeyframeableTrackEditorBase  Shared base for all keyframeable editors
│   │   └── [Category]/FOBSXxxTrackEditor    Per-track editors (Volume, Balance, etc.)
│   ├── ContinuousStateTrack/
│   │   ├── FOBSContinuousStateTrackEditorBase    Shared base for all continuous state editors
│   │   ├── FOBSContinuousStateSectionInterface   Shared section display (colored bar)
│   │   └── [Category]/FOBSXxxStateTrackEditor    Per-track editors (Mute, Visibility, etc.)
│   └── MediaSyncTrack/
│       ├── FOBSMediaSyncTrackEditor         Track editor with media input picker
│       └── FOBSMediaSyncSectionInterface    Section display with offset indicator
└── DetailsCustomization/
    └── Sequencer/
        ├── EventTriggersTrack/               Action params customization
        ├── KeyframeableTrack/               Target pickers (Input, Scene+Item, etc.)
        ├── ContinuousStateTrack/            Target pickers per track type
        └── MediaSyncTrack/                  Track + Section customizations
├── FOBSSequencerActionExecutor          Routes to correct OBS client
├── FOBSSequencerActionQueue             Throttling, deduplication, batching
└── FOBSSequencerActionRegistry          Action metadata registry

关键类:

用途
FOBSSequencerActionRegistry包含 40 余个动作及其元数据的静态注册表
FOBSSequencerActionQueue单例队列,具备 33ms 节流(约 30fps)、去重及批处理优化(每批最多 48 个动作)
FOBSOutputPreAnimatedState在播放前捕获输出状态以便恢复
FOBSSequencerActionExecutor将动作路由到正确的 OBS 客户端(Editor Subsystem 或 Game Subsystem)

新增 Sequencer 动作

  1. InhyeongOBSSequencerTypes.hEOBSSequencerAction 中添加枚举值。
  2. InhyeongOBSSequencerTypes.cpp 中添加 REGISTER_ACTION 块。
  3. OBSSequencerActionExecutor.cpp 中添加执行分支。
  4. 如需使用批处理,在 OBSSequencerActionQueue.cpp 中添加批处理请求构建逻辑。

新增动画前状态支持

对于会修改 OBS 设置的 State 类型动作,需实现状态恢复:

  1. Sequencer/EventTriggersTrack/ 中创建 FOBS[Handler]PreAnimatedState
  2. 继承自 IPersistentEvaluationData
  3. 使用处理器的缓存值(不得使用异步!)实现 CaptureFrom()
  4. 实现带有 150ms 防抖的 RestoreTo()
  5. 更新 MovieSceneOBSTemplate::SupportsPreAnimatedState() 以包含对应分类。
  6. MovieSceneOBSTemplate.cpp 中添加 Setup/TearDown 块。

动画前状态模式:

// In Setup() - capture before section modifies OBS
FOBS[Handler]PreAnimatedState& State = PersistentData.GetOrAddSectionData();
if (!State.bHasCapturedState)
{
    State.CaptureFrom(Handler, EntryAction);
}

// In TearDown() - restore when section becomes inactive
FOBS[Handler]PreAnimatedState* State = PersistentData.FindSectionData();
if (State && State->bHasCapturedState)
{
    State->RestoreTo(Handler);
}

新增 Continuous State Track

每个 Continuous State Track 需在 Sequencer/ContinuousStateTrack/[Handler]/ 下创建 4 个文件:

文件用途
OBS[State]PreAnimatedState.h/.cpp捕获/恢复,幂等的 ApplyState()
MovieSceneOBS[State]Section.h/.cpp简单属性(bool/enum),无通道
MovieSceneOBS[State]Track.h/.cpp包含目标标识的容器
MovieSceneOBS[State]Template.h/.cppSetup 捕获状态,Evaluate 应用状态,TearDown 恢复状态

关键实现规则:

  1. PreAnimatedState 继承自 IPersistentEvaluationData(不得使用 USTRUCT)。
  2. ApplyState() 必须是幂等的(发送前检查 bStateIsApplied)。
  3. Track::CreateTemplateForSection 使用直接返回(不得使用 *new)。
  4. Section 不含 FMovieSceneFloatChannel,仅有简单属性。
  5. Section 构造函数将 EvalOptions.CompletionMode 设为 RestoreState
  6. Template 使用 GetOrAddTrackData<>() / FindTrackData<>() 管理持久化数据。

新增 Keyframeable Track

每个可关键帧属性需在 Sequencer/KeyframeableTrack/[Category]/ 下创建 4 个文件:

文件用途
OBS[Property]PreAnimatedState.h/.cpp捕获/恢复原始 OBS 状态
MovieSceneOBS[Property]Section.h/.cpp存储 FMovieSceneFloatChannel 关键帧
MovieSceneOBS[Property]Track.h/.cpp包含目标标识的容器
MovieSceneOBS[Property]Template.h/.cpp持续求值,增量阈值发送

关键实现规则:

  1. PreAnimatedState 继承自 IPersistentEvaluationData(不得使用 USTRUCT)。
  2. Track::CreateTemplateForSection 使用直接返回(不得使用 *new)。
  3. Template 使用 GetOrAddSectionData<>() / FindSectionData<>() 管理持久化数据。
  4. Setup() 通过 FOBSSequencerActionExecutor::GetClientForContext() 将客户端缓存至 PreAnimatedState。
  5. Evaluate()State->CachedClient.Get() 获取客户端(不使用 Player 上下文,该上下文在 Evaluate 中不可用)。
  6. Evaluate() 通过 FOBSSequencerActionQueue::Get().EnqueueAction() 路由,以实现节流/批处理。
  7. 增量阈值检查在入队之前进行,以避免创建不必要的动作。

Sequencer 编辑器 UI

所有轨道均提供完善的编辑器体验:

轨道大纲:

  • 连接状态指示器(绿/红状态指示点)
  • 快速”+“按钮,可在播放头处添加分段
  • 通过 FMovieSceneFloatChannel 自动集成曲线编辑器

细节面板定制:

轨道目标选择备注
Volume / Balance音频输入下拉菜单仅筛选支持音频的输入
Transform场景 → 场景项目级联选择场景项目显示”SourceName (ID: 123)“格式
Filter Setting来源 → 滤镜级联选择设置名称手动输入(OBS 内部键名)
Transition Duration无(影响当前转场)已连接时显示当前转场信息
Color Source色源下拉菜单仅筛选 color_source 输入
Media Cursor媒体输入下拉菜单仅筛选 ffmpeg_source/vlc_source

下拉菜单填充:

  • 所有下拉菜单数据均来自 OBS 客户端缓存。
  • 刷新按钮会触发从 OBS 全量刷新数据。
  • 断开连接时显示占位文本”(Connect to OBS first)”。
  • 级联选择在父级变更时会清空子级选项。

编辑器模块架构

编辑器模块采用分段构建器模式实现细节面板定制:

FInhyeongOBSComponentCustomization
├── FOBSConnectionSectionBuilder
├── FOBSScenesSectionBuilder
├── FOBSSceneItemTransformsSectionBuilder
├── FOBSStudioModeSectionBuilder
├── FOBSTransitionsSectionBuilder
├── FOBSRecordingStreamingSectionBuilder
├── FOBSVirtualCamSectionBuilder
├── FOBSReplayBufferSectionBuilder
├── FOBSAdvancedOutputsSectionBuilder
├── FOBSAudioInputsSectionBuilder
├── FOBSMediaInputsSectionBuilder
├── FOBSInputSettingsSectionBuilder
├── FOBSFiltersSectionBuilder
├── FOBSScreenshotsSectionBuilder
├── FOBSWatchedScenesSectionBuilder
└── FOBSConfigSectionBuilder

FInhyeongOBSTriggerVolumeCustomization
├── FOBSTriggerShapeSectionBuilder
├── FOBSTriggerSettingsSectionBuilder
├── FOBSTriggerConditionsSectionBuilder
├── FOBSTriggerActionsSectionBuilder
└── FOBSTriggerTestSectionBuilder

分段构建器基类

FOBSSectionBuilderBase:OBS Component 分段的基类:

class FOBSSectionBuilderBase : public TSharedFromThis<FOBSSectionBuilderBase>
{
public:
    void Initialize(const TSharedRef<FOBSSectionContext>& InContext);
    virtual void BuildSection(IDetailCategoryBuilder& Category) = 0;
    virtual FText GetSectionTitle() const = 0;
    virtual bool IsInitiallyCollapsed() const { return false; }
    virtual void BindToEvents() {}
    virtual void UnbindFromEvents() {}
    void RequestRefresh();

protected:
    bool IsConnected() const;
    UInhyeongOBSEditorSubsystem* GetSubsystem() const;
    UInhyeongOBSWebSocketClient* GetClient() const;
    TAttribute<bool> MakeEnabledWhenConnected() const;
};

FOBSTriggerVolumeSectionBuilderBase:Trigger Volume 分段的基类:

class FOBSTriggerVolumeSectionBuilderBase : public TSharedFromThis<FOBSTriggerVolumeSectionBuilderBase>
{
public:
    void Initialize(const TSharedRef<FOBSTriggerVolumeSectionContext>& InContext);
    virtual void BuildSection(IDetailCategoryBuilder& Category) = 0;
    virtual FText GetSectionTitle() const = 0;

protected:
    AInhyeongOBSTriggerVolume* GetTriggerVolume() const;
    // ... same helpers as FOBSSectionBuilderBase
};

分段上下文结构体

FOBSSectionContext:组件分段的共享数据:

struct FOBSSectionContext
{
    UInhyeongOBSEditorSubsystem* Subsystem;
    UInhyeongOBSWebSocketClient* Client;
    TWeakObjectPtr<UInhyeongOBSComponent> Component;
    IDetailLayoutBuilder* DetailBuilder;
    TSharedPtr<bool> ValidityFlag;  // Set false on destruction

    bool IsValid() const;
    bool IsConnected() const;
    UInhyeongOBSOutputs* GetOutputs() const;
    UInhyeongOBSScenes* GetScenes() const;
    UInhyeongOBSAudio* GetAudio() const;
    UInhyeongOBSInputSettings* GetInputSettings() const;
    UInhyeongOBSMediaInputs* GetMediaInputs() const;
};

FOBSTriggerVolumeSectionContext:Trigger Volume 分段的共享数据:

struct FOBSTriggerVolumeSectionContext
{
    UInhyeongOBSEditorSubsystem* Subsystem;
    UInhyeongOBSWebSocketClient* Client;
    TWeakObjectPtr<AInhyeongOBSTriggerVolume> TriggerVolume;
    IDetailLayoutBuilder* DetailBuilder;
    TSharedPtr<bool> ValidityFlag;

    bool IsValid() const;
    bool IsConnected() const;
    // ... handler accessors
};

关键类型

枚举:

  • EOBSConnectionState:Disconnected、Connecting、Authenticating、Connected
  • EOBSOutputState:Starting、Started、Stopping、Stopped、Paused、Resumed 等
  • EOBSMediaInputAction:None、Play、Pause、Stop、Restart、Next、Previous
  • EOBSMediaState:Unknown、None、Playing、Paused、Stopped、Buffering、Ended、Error、Opening
  • EOBSTriggerActionType:所有受支持的触发动作
  • EOBSTriggerShape:Box、Sphere
  • EOBSTriggerEvent:OnEnter、OnExit、Both
  • EOBSRequestBatchExecutionType:SerialRealtime、SerialFrame、Parallel
  • EOBSMonitorType:None、MonitorOnly、MonitorAndOutput

结构体:

  • FOBSScene:场景名称、UUID、索引
  • FOBSSceneItem:场景内的来源信息(包含锁定状态、混合模式)
  • FOBSSceneWithItems:场景及其所有项目
  • FOBSInput:包含音量/静音信息的输入
  • FOBSStreamStatus / FOBSRecordStatus:带时间码的输出状态
  • FOBSMediaInputStatus:媒体状态、时长、游标位置
  • FOBSTriggerAction:Trigger Volume 的动作配置
  • FOBSTriggerConditions:触发器的条件配置
  • FOBSBatchRequest / FOBSBatchResult:批处理请求/响应数据
  • FOBSTransition:转场名称、UUID、类型、可配置标志、固定标志
  • FOBSSourceFilter:滤镜名称、类型、索引、启用状态、设置
  • FOBSCurrentTransitionInfo:包含设置在内的完整转场详情
  • FOBSSceneItemTransform:位置、缩放、旋转、裁剪、边界、来源尺寸
  • EOBSBoundsType:None、Stretch、ScaleInner、ScaleOuter、ScaleToWidth、ScaleToHeight、MaxOnly
  • EOBSBlendMode:Normal、Additive、Subtract、Screen、Multiply、Lighten、Darken
  • FOBSScreenshotRequest:截图捕获参数(来源、格式、尺寸、质量、路径)
  • FOBSScreenshotResult:包含 base64 图像数据的捕获结果
  • FOBSScreenshotSavedResult:包含文件路径确认信息的保存结果
  • FOBSSceneTransitionOverride:每场景转场覆盖(名称、时长、bHasOverride)
  • FOBSProfileParameter:参数值与默认值
  • FOBSStreamServiceSettings:推流目标配置(服务器、推流密钥、身份验证)
  • FOBSAudioTracks:轨道 1 至 6 的启用状态及辅助方法
  • FOBSSpecialInputs:默认音频设备名称(Desktop1/2、Mic1 至 4)
  • FOBSOutput:通用输出信息(名称、类型、尺寸、活动状态、标志)
  • FOBSOutputStatus:通用输出状态(名称、活动状态、重连状态、时间码、时长、拥塞、字节数、帧数)

缓存:

  • 输入设置在通过 GetInputSettings() 获取后缓存于 UInhyeongOBSInputSettings 中。
  • 使用 GetCachedInputSettings() / GetCachedInputSettingsString() 访问已缓存数据。
  • 使用 HasCachedSettings() 检查数据是否可用。
  • 使用 ClearCachedSettings() / ClearAllCachedSettings() 使缓存失效。

细节面板定制

该插件采用模块化分段构建器模式实现细节面板:

  • FOBSSectionBuilderBase:OBS Component 分段的基类
  • FOBSTriggerVolumeSectionBuilderBase:Trigger Volume 分段的基类
  • FOBSDetailsPanelStyle:共享样式常量与控件构建器

每个分段(连接、场景、录制等)均作为独立的构建器类实现。

身份解析器(名称 → UUID 重绑定)

OBS 使用数字 SceneItemId 作为场景项目的键,设计师通常不会接触该 ID,且该 ID 在来源被改名后会发生变化。Core/InhyeongOBSIdentityResolver.hOBSIdentity::FindSceneItemByName / FindSceneItemByUuids 以及 FOBSIdentityBindingCache)通过名称解析来源,记录其场景/来源 UUID,并在后续按名称查找失败时通过 UUID 进行重绑定。这样,以名称为目标的触发器在来源改名后仍可正常工作。该功能已集成至 Trigger Volume 的”Set Source Visibility”动作中。缓存仅在运行时有效,在场景集合切换时会重置。

身份验证

该插件在内部实现了 SHA256 身份验证,无需平台依赖。实现细节请参阅 InhyeongOBSAuth.h

请求批处理

使用 FOBSRequestBatchBuilder 进行高效批处理请求:

FOBSRequestBatchBuilder::Create(Client)
    .SetCurrentProgramScene("Scene1")
    .StartRecord()
    .SetInputMute("Mic", false)
    .HaltOnFailure(true)
    .SetExecutionType(EOBSRequestBatchExecutionType::SerialRealtime)
    .ExecuteWithCallback([](const FOBSBatchResult& Result) {
        // Handle results
    });

可用批处理方法:

  • 场景: GetSceneList()SetCurrentProgramScene()GetCurrentProgramScene()CreateScene()RemoveScene()SetSceneName()GetSceneSceneTransitionOverride()SetSceneSceneTransitionOverride()SetSceneItemEnabled()CreateSceneItem()RemoveSceneItem()DuplicateSceneItem()GetSceneItemLocked()SetSceneItemLocked()GetSceneItemIndex()SetSceneItemIndex()GetSceneItemBlendMode()SetSceneItemBlendMode()
  • 配置文件: GetSceneCollectionList()SetCurrentSceneCollection()CreateSceneCollection()GetProfileList()SetCurrentProfile()CreateProfile()RemoveProfile()GetProfileParameter()SetProfileParameter()GetVideoSettings()SetVideoSettings()SetBaseResolution()SetOutputResolution()SetFPS()
  • 推流: StartStream()StopStream()ToggleStream()GetStreamStatus()
  • 录制: StartRecord()StopRecord()ToggleRecord()PauseRecord()ResumeRecord()GetRecordStatus()
  • Virtual Camera: StartVirtualCam()StopVirtualCam()ToggleVirtualCam()GetVirtualCamStatus()
  • Replay Buffer: StartReplayBuffer()StopReplayBuffer()ToggleReplayBuffer()SaveReplayBuffer()GetReplayBufferStatus()
  • 录制目录: GetRecordDirectory()SetRecordDirectory()
  • 录制分割/章节: SplitRecordFile()CreateRecordChapter()
  • 通用输出: GetOutputList()GetOutputStatus()GetOutputSettings()SetOutputSettings()StartOutput()StopOutput()ToggleOutput()
  • 推流字幕: SendStreamCaption()
  • 音频: GetInputList()SetInputMute()ToggleInputMute()SetInputVolume()GetInputKindList()CreateInput()RemoveInput()RemoveInputByUuid()SetInputName()GetInputAudioBalance()GetInputAudioBalanceByUuid()SetInputAudioBalance()SetInputAudioBalanceByUuid()GetInputAudioSyncOffset()GetInputAudioSyncOffsetByUuid()SetInputAudioSyncOffset()SetInputAudioSyncOffsetByUuid()GetInputAudioMonitorType()GetInputAudioMonitorTypeByUuid()SetInputAudioMonitorType()SetInputAudioMonitorTypeByUuid()GetInputAudioTracks()GetInputAudioTracksByUuid()SetInputAudioTracks()SetInputAudioTracksByUuid()GetSpecialInputs()
  • 输入设置: GetInputSettings()SetInputSettings()GetInputDefaultSettings()SetTextSourceText()SetBrowserSourceUrl()SetImageSourceFile()SetMediaSourceFile()SetColorSourceColor()
  • 媒体: TriggerMediaInputAction()GetMediaInputStatus()SetMediaInputCursor()OffsetMediaInputCursor()
  • Studio Mode: GetStudioModeEnabled()SetStudioModeEnabled()GetCurrentPreviewScene()SetCurrentPreviewScene()SetCurrentPreviewSceneByUuid()TriggerStudioModeTransition()
  • 转场: GetSceneTransitionList()GetCurrentSceneTransition()SetCurrentSceneTransition()SetCurrentSceneTransitionDuration()SetCurrentSceneTransitionSettings()GetCurrentSceneTransitionCursor()
  • 截图: GetSourceScreenshot()GetSourceScreenshotByUuid()GetSourceScreenshotWithOptions()SaveSourceScreenshot()SaveSourceScreenshotByUuid()SaveSourceScreenshotWithOptions()
  • 滤镜: GetSourceFilterKindList()GetSourceFilterList()GetSourceFilterListByUuid()GetSourceFilter()GetSourceFilterDefaultSettings()CreateSourceFilter()RemoveSourceFilter()SetSourceFilterName()SetSourceFilterIndex()SetSourceFilterEnabled()SetSourceFilterSettings()

内部组织:

批处理构建器的实现为便于维护拆分至多个文件:

文件内容
InhyeongOBSRequestBatch.cpp核心逻辑、配置、执行
InhyeongOBSRequestBatch_Scenes.cpp场景与场景项目请求
InhyeongOBSRequestBatch_Outputs.cpp推流、录制、虚拟摄像头、Replay Buffer
InhyeongOBSRequestBatch_Audio.cpp音频、媒体输入、输入设置
InhyeongOBSRequestBatch_Filters.cpp来源滤镜管理
InhyeongOBSRequestBatch_StudioMode.cppStudio Mode 与转场
InhyeongOBSRequestBatch_Config.cpp截图、配置文件、场景集合、视频设置

新增功能

  1. InhyeongOBSTypes.h 中添加类型/委托。
  2. 在相应处理器(OutputsScenesInputsMediaInputs)中实现功能。
  3. 如有需要,为 ClientSubsystemComponent 添加便捷方法。
  4. 在客户端的 ProcessOBSEvent() 中处理事件。
  5. 在相应的分段构建器中添加 UI。

新增编辑器分段

  1. 创建继承自 FOBSSectionBuilderBaseFOBSTriggerVolumeSectionBuilderBase 的新分段构建器类。
  2. 实现 BuildSection()GetSectionTitle(),以及可选的 IsInitiallyCollapsed()
  3. 如果分段需要实时更新,覆写 BindToEvents()UnbindFromEvents()
  4. 将构建器添加至定制类的 CreateSectionBuilders() 方法中。
  5. 使用 FOBSDetailsPanelStyle 保持样式一致。