아키텍처 및 개발자 참조
이 페이지는 플러그인을 확장하는 개발자를 위한 “내부 동작 방식” 참조 문서입니다. 모듈 구조, 핸들러 기반 클라이언트, Sequencer 통합, 에디터 디테일 패널 시스템, 주요 타입, 그리고 새 기능을 추가하는 패턴을 다룹니다.
람다 바인딩을 지원하는 네이티브 C++ 델리게이트(Native 접미사 이벤트)의 전체 목록은 Native Delegates를 참조하십시오.
모듈 구조
플러그인은 세 개의 모듈로 구성됩니다.
| 모듈 | 유형 | 목적 |
|---|---|---|
InhyeongOBSWebSocket | Runtime | 핵심 기능, Subsystem, 컴포넌트, Sequencer 통합 |
InhyeongOBSWebSocketEditor | Editor | 디테일 패널 커스터마이징, Editor Subsystem, Sequencer 트랙 에디터 |
InhyeongOBSWebSocketTakeRecorder | Editor | Take 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
유틸리티 클래스
| 클래스 | 위치 | 목적 |
|---|---|---|
FOBSRequestBatchBuilder | Utilities/ | 배치 요청을 위한 플루언트 빌더 |
FOBSJsonBuilder | Utilities/ | 플루언트 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 또는 Game Subsystem)로 라우팅 |
새 Sequencer 동작 추가하기
InhyeongOBSSequencerTypes.h의EOBSSequencerAction에 열거형 값을 추가합니다.InhyeongOBSSequencerTypes.cpp에REGISTER_ACTION블록을 추가합니다.OBSSequencerActionExecutor.cpp에 실행 케이스를 추가합니다.- 배치 처리를 사용하는 경우
OBSSequencerActionQueue.cpp에 배치 요청 빌드를 추가합니다.
애니메이션 이전 상태 지원 추가하기
OBS 설정을 수정하는 State 유형 동작의 경우 복원 기능을 구현합니다.
Sequencer/EventTriggersTrack/에FOBS[Handler]PreAnimatedState를 생성합니다.IPersistentEvaluationData를 상속합니다.- 핸들러의 캐시된 값을 사용하여
CaptureFrom()을 구현합니다(비동기 금지). - 150ms 디바운스를 적용하여
RestoreTo()를 구현합니다. MovieSceneOBSTemplate::SupportsPreAnimatedState()를 업데이트하여 해당 카테고리를 포함합니다.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/.cpp | Setup이 캡처, Evaluate가 적용, TearDown이 복원 |
중요 구현 규칙:
- PreAnimatedState는
IPersistentEvaluationData를 상속합니다(USTRUCT 금지). ApplyState()는 반드시 멱등이어야 합니다(전송 전bStateIsApplied확인).Track::CreateTemplateForSection은 직접 반환을 사용합니다(*new금지).- Section에는
FMovieSceneFloatChannel이 없으며, 단순 프로퍼티만 있습니다. - Section 생성자는
EvalOptions.CompletionMode = RestoreState로 설정합니다. - 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 | 연속 평가, 델타 임계값 전송 |
중요 구현 규칙:
- PreAnimatedState는
IPersistentEvaluationData를 상속합니다(USTRUCT 금지). Track::CreateTemplateForSection은 직접 반환을 사용합니다(*new금지).- Template은 영구 데이터에
GetOrAddSectionData<>()/FindSectionData<>()를 사용합니다. Setup()은FOBSSequencerActionExecutor::GetClientForContext()를 통해 클라이언트를 PreAnimatedState에 캐시합니다.Evaluate()는State->CachedClient.Get()에서 클라이언트를 가져옵니다(Evaluate에서 사용할 수 없는 Player 컨텍스트를 사용하지 않습니다).Evaluate()는 스로틀링/배치 처리를 위해FOBSSequencerActionQueue::Get().EnqueueAction()을 통해 라우팅합니다.- 델타 임계값 확인은 불필요한 동작 생성을 방지하기 위해 큐에 추가하기 전에 수행합니다.
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, ConnectedEOBSOutputState: Starting, Started, Stopping, Stopped, Paused, Resumed 등EOBSMediaInputAction: None, Play, Pause, Stop, Restart, Next, PreviousEOBSMediaState: Unknown, None, Playing, Paused, Stopped, Buffering, Ended, Error, OpeningEOBSTriggerActionType: 지원되는 모든 트리거 동작EOBSTriggerShape: Box, SphereEOBSTriggerEvent: OnEnter, OnExit, BothEOBSRequestBatchExecutionType: SerialRealtime, SerialFrame, ParallelEOBSMonitorType: 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, MaxOnlyEOBSBlendMode: Normal, Additive, Subtract, Screen, Multiply, Lighten, DarkenFOBSScreenshotRequest: 스크린샷 캡처 매개변수(소스, 형식, 크기, 품질, 경로)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가 바뀝니다. Core/InhyeongOBSIdentityResolver.h(OBSIdentity::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
});
사용 가능한 배치 메서드:
- Scene:
GetSceneList(),SetCurrentProgramScene(),GetCurrentProgramScene(),CreateScene(),RemoveScene(),SetSceneName(),GetSceneSceneTransitionOverride(),SetSceneSceneTransitionOverride(),SetSceneItemEnabled(),CreateSceneItem(),RemoveSceneItem(),DuplicateSceneItem(),GetSceneItemLocked(),SetSceneItemLocked(),GetSceneItemIndex(),SetSceneItemIndex(),GetSceneItemBlendMode(),SetSceneItemBlendMode() - Config:
GetSceneCollectionList(),SetCurrentSceneCollection(),CreateSceneCollection(),GetProfileList(),SetCurrentProfile(),CreateProfile(),RemoveProfile(),GetProfileParameter(),SetProfileParameter(),GetVideoSettings(),SetVideoSettings(),SetBaseResolution(),SetOutputResolution(),SetFPS() - Stream:
StartStream(),StopStream(),ToggleStream(),GetStreamStatus() - Record:
StartRecord(),StopRecord(),ToggleRecord(),PauseRecord(),ResumeRecord(),GetRecordStatus() - VirtualCam:
StartVirtualCam(),StopVirtualCam(),ToggleVirtualCam(),GetVirtualCamStatus() - ReplayBuffer:
StartReplayBuffer(),StopReplayBuffer(),ToggleReplayBuffer(),SaveReplayBuffer(),GetReplayBufferStatus() - Record Directory:
GetRecordDirectory(),SetRecordDirectory() - Record Split/Chapters:
SplitRecordFile(),CreateRecordChapter() - Generic Outputs:
GetOutputList(),GetOutputStatus(),GetOutputSettings(),SetOutputSettings(),StartOutput(),StopOutput(),ToggleOutput() - Stream Captions:
SendStreamCaption() - Audio:
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() - Input Settings:
GetInputSettings(),SetInputSettings(),GetInputDefaultSettings(),SetTextSourceText(),SetBrowserSourceUrl(),SetImageSourceFile(),SetMediaSourceFile(),SetColorSourceColor() - Media:
TriggerMediaInputAction(),GetMediaInputStatus(),SetMediaInputCursor(),OffsetMediaInputCursor() - StudioMode:
GetStudioModeEnabled(),SetStudioModeEnabled(),GetCurrentPreviewScene(),SetCurrentPreviewScene(),SetCurrentPreviewSceneByUuid(),TriggerStudioModeTransition() - Transitions:
GetSceneTransitionList(),GetCurrentSceneTransition(),SetCurrentSceneTransition(),SetCurrentSceneTransitionDuration(),SetCurrentSceneTransitionSettings(),GetCurrentSceneTransitionCursor() - Screenshots:
GetSourceScreenshot(),GetSourceScreenshotByUuid(),GetSourceScreenshotWithOptions(),SaveSourceScreenshot(),SaveSourceScreenshotByUuid(),SaveSourceScreenshotWithOptions() - Filters:
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.cpp | Studio Mode 및 전환 |
InhyeongOBSRequestBatch_Config.cpp | 스크린샷, 프로필, 장면 모음, 비디오 설정 |
새 기능 추가하기
InhyeongOBSTypes.h에 타입/델리게이트를 추가합니다.- 적절한 핸들러(
Outputs,Scenes,Inputs,MediaInputs)에 구현합니다. - 필요한 경우
Client,Subsystem,Component에 편의 메서드를 추가합니다. - 클라이언트의
ProcessOBSEvent()에서 이벤트를 처리합니다. - 적절한 섹션 빌더에 UI를 추가합니다.
새 에디터 섹션 추가하기
FOBSSectionBuilderBase또는FOBSTriggerVolumeSectionBuilderBase를 상속하는 새 섹션 빌더 클래스를 생성합니다.BuildSection(),GetSectionTitle()을 구현하고, 필요에 따라IsInitiallyCollapsed()도 구현합니다.- 섹션에 실시간 업데이트가 필요한 경우
BindToEvents()및UnbindFromEvents()를 오버라이드합니다. - 커스터마이징 클래스의
CreateSectionBuilders()메서드에 빌더를 추가합니다. - 일관된 스타일링을 위해
FOBSDetailsPanelStyle을 사용합니다.