From 8a6902d8f33d7c9e3abd4f23b492f3de1ec08f42 Mon Sep 17 00:00:00 2001 From: moxy <140682495+moxyvv@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:15:49 -0500 Subject: [PATCH 1/4] frontend: Add scene override for replay buffer output Adds the ability to configure the replay buffer to capture from a specific scene instead of the program output. This is useful for users who want clean gameplay clips without overlays, webcams, or other sources that are part of their streaming scene. Mirrors the existing virtual camera output selection pattern: - Gear button in the controls dock next to the replay buffer - Configuration dialog to select Program or a specific scene - Separate obs_view and video encoder when a scene is selected - Falls back to the default recording encoder when set to Program The replay buffer view and encoder are created on start and torn down on stop to avoid unnecessary rendering when idle. --- frontend/cmake/ui-dialogs.cmake | 2 + frontend/cmake/ui-qt.cmake | 1 + frontend/cmake/ui-utility.cmake | 1 + frontend/data/locale/en-US.ini | 5 ++ frontend/dialogs/OBSBasicRBConfig.cpp | 57 +++++++++++++ frontend/dialogs/OBSBasicRBConfig.hpp | 27 ++++++ frontend/forms/OBSBasicControls.ui | 26 ++++++ frontend/forms/OBSBasicRBConfig.ui | 97 ++++++++++++++++++++++ frontend/utility/AdvancedOutput.cpp | 32 ++++++- frontend/utility/BasicOutputHandler.cpp | 31 +++++++ frontend/utility/BasicOutputHandler.hpp | 9 +- frontend/utility/ReplayBufferConfig.hpp | 13 +++ frontend/utility/SimpleOutput.cpp | 21 ++++- frontend/widgets/OBSBasic.cpp | 1 + frontend/widgets/OBSBasic.hpp | 4 + frontend/widgets/OBSBasicControls.cpp | 5 ++ frontend/widgets/OBSBasicControls.hpp | 1 + frontend/widgets/OBSBasic_ReplayBuffer.cpp | 22 +++++ 18 files changed, 349 insertions(+), 6 deletions(-) create mode 100644 frontend/dialogs/OBSBasicRBConfig.cpp create mode 100644 frontend/dialogs/OBSBasicRBConfig.hpp create mode 100644 frontend/forms/OBSBasicRBConfig.ui create mode 100644 frontend/utility/ReplayBufferConfig.hpp diff --git a/frontend/cmake/ui-dialogs.cmake b/frontend/cmake/ui-dialogs.cmake index ec1c96c44ea83b..334db0239002fc 100644 --- a/frontend/cmake/ui-dialogs.cmake +++ b/frontend/cmake/ui-dialogs.cmake @@ -33,6 +33,8 @@ target_sources( dialogs/OBSBasicSourceSelect.hpp dialogs/OBSBasicTransform.cpp dialogs/OBSBasicTransform.hpp + dialogs/OBSBasicRBConfig.cpp + dialogs/OBSBasicRBConfig.hpp dialogs/OBSBasicVCamConfig.cpp dialogs/OBSBasicVCamConfig.hpp dialogs/OBSLogViewer.cpp diff --git a/frontend/cmake/ui-qt.cmake b/frontend/cmake/ui-qt.cmake index f730b86d6ff004..a2a88aa158b203 100644 --- a/frontend/cmake/ui-qt.cmake +++ b/frontend/cmake/ui-qt.cmake @@ -43,6 +43,7 @@ target_sources( forms/OBSBasicProperties.ui forms/OBSBasicSettings.ui forms/OBSBasicSourceSelect.ui + forms/OBSBasicRBConfig.ui forms/OBSBasicVCamConfig.ui forms/OBSExtraBrowsers.ui forms/OBSImporter.ui diff --git a/frontend/cmake/ui-utility.cmake b/frontend/cmake/ui-utility.cmake index 8b02d5ec75e051..7a6d916ecaa039 100644 --- a/frontend/cmake/ui-utility.cmake +++ b/frontend/cmake/ui-utility.cmake @@ -49,6 +49,7 @@ target_sources( utility/RemuxQueueModel.hpp utility/RemuxWorker.cpp utility/RemuxWorker.hpp + utility/ReplayBufferConfig.hpp utility/SceneRenameDelegate.cpp utility/SceneRenameDelegate.hpp utility/ScreenshotObj.cpp diff --git a/frontend/data/locale/en-US.ini b/frontend/data/locale/en-US.ini index 882380935c01d6..203853905360e1 100644 --- a/frontend/data/locale/en-US.ini +++ b/frontend/data/locale/en-US.ini @@ -797,6 +797,11 @@ Basic.VCam.OutputType.Program="Program (Default)" Basic.VCam.OutputSelection.NoSelection="No selection for this output type" Basic.VCam.RestartWarning="The virtual camera will be restarted to apply this change" +# replay buffer configuration +Basic.Main.ReplayBufferConfig="Configure Replay Buffer" +Basic.ReplayBuffer.Config="Replay Buffer Configuration" +Basic.ReplayBuffer.OutputType="Output Type" + # basic mode file menu Basic.MainMenu.File="&File" Basic.MainMenu.File.Export="&Export" diff --git a/frontend/dialogs/OBSBasicRBConfig.cpp b/frontend/dialogs/OBSBasicRBConfig.cpp new file mode 100644 index 00000000000000..781487eff25373 --- /dev/null +++ b/frontend/dialogs/OBSBasicRBConfig.cpp @@ -0,0 +1,57 @@ +#include "OBSBasicRBConfig.hpp" + +#include + +#include "moc_OBSBasicRBConfig.cpp" + +OBSBasicRBConfig::OBSBasicRBConfig(const ReplayBufferConfig &_config, bool _rbActive, QWidget *parent) + : config(_config), + rbActive(_rbActive), + QDialog(parent), + ui(new Ui::OBSBasicRBConfig) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + ui->setupUi(this); + + ui->outputType->addItem(QTStr("Basic.VCam.OutputType.Program"), (int)RBOutputProgramView); + ui->outputType->addItem(QTStr("Basic.Scene"), (int)RBOutputSceneView); + + ui->outputType->setCurrentIndex(ui->outputType->findData((int)config.type)); + OutputTypeChanged(); + connect(ui->outputType, &QComboBox::currentIndexChanged, this, &OBSBasicRBConfig::OutputTypeChanged); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &OBSBasicRBConfig::UpdateConfig); +} + +void OBSBasicRBConfig::OutputTypeChanged() +{ + ReplayBufferOutputType type = (ReplayBufferOutputType)ui->outputType->currentData().toInt(); + + ui->sceneSelection->clear(); + + if (type == RBOutputProgramView) { + ui->sceneSelection->setDisabled(true); + ui->sceneSelection->addItem(QTStr("Basic.VCam.OutputSelection.NoSelection")); + } else { + ui->sceneSelection->setDisabled(false); + BPtr scenes = obs_frontend_get_scene_names(); + for (char **temp = scenes; *temp; temp++) { + ui->sceneSelection->addItem(*temp); + + if (config.scene.compare(*temp) == 0) + ui->sceneSelection->setCurrentIndex(ui->sceneSelection->count() - 1); + } + } +} + +void OBSBasicRBConfig::UpdateConfig() +{ + ReplayBufferOutputType type = (ReplayBufferOutputType)ui->outputType->currentData().toInt(); + + config.type = type; + if (type == RBOutputSceneView) + config.scene = ui->sceneSelection->currentText().toStdString(); + + emit Accepted(config); +} diff --git a/frontend/dialogs/OBSBasicRBConfig.hpp b/frontend/dialogs/OBSBasicRBConfig.hpp new file mode 100644 index 00000000000000..696a3d4211d1c3 --- /dev/null +++ b/frontend/dialogs/OBSBasicRBConfig.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "ui_OBSBasicRBConfig.h" + +#include + +#include + +class OBSBasicRBConfig : public QDialog { + Q_OBJECT + + ReplayBufferConfig config; + bool rbActive; + +public: + explicit OBSBasicRBConfig(const ReplayBufferConfig &config, bool rbActive, QWidget *parent = 0); + +private slots: + void OutputTypeChanged(); + void UpdateConfig(); + +private: + std::unique_ptr ui; + +signals: + void Accepted(const ReplayBufferConfig &config); +}; diff --git a/frontend/forms/OBSBasicControls.ui b/frontend/forms/OBSBasicControls.ui index 9ee1fbbbfeb28d..5e7ddd919dd222 100644 --- a/frontend/forms/OBSBasicControls.ui +++ b/frontend/forms/OBSBasicControls.ui @@ -224,6 +224,32 @@ + + + + true + + + + 0 + 0 + + + + Basic.Main.ReplayBufferConfig + + + Basic.Main.ReplayBufferConfig + + + + :/settings/images/settings/general.svg:/settings/images/settings/general.svg + + + icon-gear + + + diff --git a/frontend/forms/OBSBasicRBConfig.ui b/frontend/forms/OBSBasicRBConfig.ui new file mode 100644 index 00000000000000..e979157a1d11e7 --- /dev/null +++ b/frontend/forms/OBSBasicRBConfig.ui @@ -0,0 +1,97 @@ + + + OBSBasicRBConfig + + + + 0 + 0 + 400 + 150 + + + + Basic.ReplayBuffer.Config + + + + + + Basic.ReplayBuffer.OutputType + + + + + + + + + + Basic.Scene + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + OBSBasicRBConfig + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + OBSBasicRBConfig + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/frontend/utility/AdvancedOutput.cpp b/frontend/utility/AdvancedOutput.cpp index aff3ad6231072b..cbb2a87ec26f06 100644 --- a/frontend/utility/AdvancedOutput.cpp +++ b/frontend/utility/AdvancedOutput.cpp @@ -354,8 +354,12 @@ inline void AdvancedOutput::SetupRecording() if (useStreamEncoder) { obs_output_set_video_encoder(fileOutput, videoStreaming); - if (replayBuffer) - obs_output_set_video_encoder(replayBuffer, videoStreaming); + if (replayBuffer) { + if (replayBufferVideoEncoder) + obs_output_set_video_encoder(replayBuffer, replayBufferVideoEncoder); + else + obs_output_set_video_encoder(replayBuffer, videoStreaming); + } } else { if (rescaleFilter != OBS_SCALE_DISABLE && rescaleRes && *rescaleRes) { if (sscanf(rescaleRes, "%ux%u", &cx, &cy) != 2) { @@ -367,8 +371,12 @@ inline void AdvancedOutput::SetupRecording() obs_encoder_set_scaled_size(videoRecording, cx, cy); obs_encoder_set_gpu_scale_type(videoRecording, (obs_scale_type)rescaleFilter); obs_output_set_video_encoder(fileOutput, videoRecording); - if (replayBuffer) - obs_output_set_video_encoder(replayBuffer, videoRecording); + if (replayBuffer) { + if (replayBufferVideoEncoder) + obs_output_set_video_encoder(replayBuffer, replayBufferVideoEncoder); + else + obs_output_set_video_encoder(replayBuffer, videoRecording); + } } if (!flv) { @@ -552,6 +560,9 @@ void AdvancedOutput::SetupOutputs() SetupFFmpeg(); else SetupRecording(); + + if (replayBufferVideoEncoder && replayBufferVideo) + obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); } int AdvancedOutput::GetAudioBitrate(size_t i, const char *id) const @@ -836,6 +847,19 @@ bool AdvancedOutput::StartRecording() bool AdvancedOutput::StartReplayBuffer() { + if (main->rbConfig.type == RBOutputSceneView) { + SetupReplayBufferView(main->rbConfig.scene); + if (replayBufferVideo) { + OBSEncoder enc = useStreamEncoder ? videoStreaming : videoRecording; + replayBufferVideoEncoder = obs_video_encoder_create(obs_encoder_get_id(enc), + "replay_buffer_video", nullptr, nullptr); + + OBSDataAutoRelease settings = obs_encoder_get_settings(enc); + obs_encoder_update(replayBufferVideoEncoder, settings); + obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); + } + } + const char *path; const char *recFormat; const char *filenameFormat; diff --git a/frontend/utility/BasicOutputHandler.cpp b/frontend/utility/BasicOutputHandler.cpp index 910867b33b1f42..088431e3d9dd54 100644 --- a/frontend/utility/BasicOutputHandler.cpp +++ b/frontend/utility/BasicOutputHandler.cpp @@ -384,6 +384,37 @@ void BasicOutputHandler::DestroyVirtualCameraScene() vCamSourceSceneItem = nullptr; } +void BasicOutputHandler::SetupReplayBufferView(const std::string &sceneName) +{ + DestroyReplayBufferView(); + + if (sceneName.empty()) + return; + + OBSSourceAutoRelease source = obs_get_source_by_name(sceneName.c_str()); + if (!source) + return; + + replayBufferView = obs_view_create(); + obs_view_set_source(replayBufferView, 0, source); + replayBufferVideo = obs_view_add(replayBufferView); +} + +void BasicOutputHandler::DestroyReplayBufferView() +{ + replayBufferVideoEncoder = nullptr; + + if (!replayBufferView) + return; + + obs_view_remove(replayBufferView); + obs_view_set_source(replayBufferView, 0, nullptr); + replayBufferVideo = nullptr; + + obs_view_destroy(replayBufferView); + replayBufferView = nullptr; +} + const char *FindAudioEncoderFromCodec(const char *type) { const char *alt_enc_id = nullptr; diff --git a/frontend/utility/BasicOutputHandler.hpp b/frontend/utility/BasicOutputHandler.hpp index 29300792a3afb8..02fe0df95d6bac 100644 --- a/frontend/utility/BasicOutputHandler.hpp +++ b/frontend/utility/BasicOutputHandler.hpp @@ -43,6 +43,10 @@ struct BasicOutputHandler { obs_scene_t *vCamSourceScene = nullptr; obs_sceneitem_t *vCamSourceSceneItem = nullptr; + obs_view_t *replayBufferView = nullptr; + video_t *replayBufferVideo = nullptr; + OBSEncoder replayBufferVideoEncoder; + std::unique_ptr whipSimulcastEncoders; std::string outputType; @@ -68,7 +72,7 @@ struct BasicOutputHandler { BasicOutputHandler(OBSBasic *main_); - virtual ~BasicOutputHandler() {}; + virtual ~BasicOutputHandler() { DestroyReplayBufferView(); } virtual std::shared_future SetupStreaming(obs_service_t *service, SetupStreamingContinuation_t continuation) = 0; @@ -92,6 +96,9 @@ struct BasicOutputHandler { virtual void DestroyVirtualCamView(); virtual void DestroyVirtualCameraScene(); + void SetupReplayBufferView(const std::string &sceneName); + void DestroyReplayBufferView(); + inline bool Active() const { return streamingActive || recordingActive || delayActive || replayBufferActive || virtualCamActive || diff --git a/frontend/utility/ReplayBufferConfig.hpp b/frontend/utility/ReplayBufferConfig.hpp new file mode 100644 index 00000000000000..8b228f995c9c5a --- /dev/null +++ b/frontend/utility/ReplayBufferConfig.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include + +enum ReplayBufferOutputType { + RBOutputProgramView, + RBOutputSceneView, +}; + +struct ReplayBufferConfig { + ReplayBufferOutputType type = RBOutputProgramView; + std::string scene; +}; diff --git a/frontend/utility/SimpleOutput.cpp b/frontend/utility/SimpleOutput.cpp index c3491fd91c9319..c44a8fdf4f7e9d 100644 --- a/frontend/utility/SimpleOutput.cpp +++ b/frontend/utility/SimpleOutput.cpp @@ -588,6 +588,9 @@ inline void SimpleOutput::SetupOutputs() } else { obs_encoder_set_audio(audioRecording, obs_get_audio()); } + + if (replayBufferVideoEncoder && replayBufferVideo) + obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); } std::shared_future SimpleOutput::SetupStreaming(obs_service_t *service, SetupStreamingContinuation_t continuation) @@ -782,7 +785,10 @@ void SimpleOutput::UpdateRecording() } } if (replayBuffer) { - obs_output_set_video_encoder(replayBuffer, videoRecording); + if (replayBufferVideoEncoder) + obs_output_set_video_encoder(replayBuffer, replayBufferVideoEncoder); + else + obs_output_set_video_encoder(replayBuffer, videoRecording); if (flv || strcmp(quality, "Stream") == 0) { obs_output_set_audio_encoder(replayBuffer, audioRecording, 0); } else { @@ -879,6 +885,19 @@ bool SimpleOutput::StartRecording() bool SimpleOutput::StartReplayBuffer() { + if (main->rbConfig.type == RBOutputSceneView) { + SetupReplayBufferView(main->rbConfig.scene); + if (replayBufferVideo) { + OBSEncoder enc = usingRecordingPreset ? videoRecording : videoStreaming; + replayBufferVideoEncoder = obs_video_encoder_create(obs_encoder_get_id(enc), + "replay_buffer_video", nullptr, nullptr); + + OBSDataAutoRelease settings = obs_encoder_get_settings(enc); + obs_encoder_update(replayBufferVideoEncoder, settings); + obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); + } + } + UpdateRecording(); if (!ConfigureRecording(true)) return false; diff --git a/frontend/widgets/OBSBasic.cpp b/frontend/widgets/OBSBasic.cpp index e3277eb5f445dc..a2d3c1749b3842 100644 --- a/frontend/widgets/OBSBasic.cpp +++ b/frontend/widgets/OBSBasic.cpp @@ -300,6 +300,7 @@ OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow(parent), undo_s(ui), ui(new connect(controls, &OBSBasicControls::ReplayBufferButtonClicked, this, &OBSBasic::ReplayBufferActionTriggered); connect(controls, &OBSBasicControls::SaveReplayBufferButtonClicked, this, &OBSBasic::ReplayBufferSave); + connect(controls, &OBSBasicControls::ReplayBufferConfigButtonClicked, this, &OBSBasic::OpenReplayBufferConfig); connect(controls, &OBSBasicControls::VirtualCamButtonClicked, this, &OBSBasic::VirtualCamActionTriggered); connect(controls, &OBSBasicControls::VirtualCamConfigButtonClicked, this, &OBSBasic::OpenVirtualCamConfig); diff --git a/frontend/widgets/OBSBasic.hpp b/frontend/widgets/OBSBasic.hpp index 2561a7c107fc47..9bdcf65146cbbc 100644 --- a/frontend/widgets/OBSBasic.hpp +++ b/frontend/widgets/OBSBasic.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -1027,6 +1028,7 @@ public slots: private: bool replayBufferStopping = false; std::string lastReplay; + ReplayBufferConfig rbConfig; public slots: void ShowReplayBufferPauseWarning(); @@ -1044,6 +1046,8 @@ public slots: private slots: /* Replay Buffer action (start/stop) slot */ void ReplayBufferActionTriggered(); + void OpenReplayBufferConfig(); + void UpdateReplayBufferConfig(const ReplayBufferConfig &config); signals: /* Replay Buffer signals */ diff --git a/frontend/widgets/OBSBasicControls.cpp b/frontend/widgets/OBSBasicControls.cpp index 5473fcdae55f1e..bd7e2427222f14 100644 --- a/frontend/widgets/OBSBasicControls.cpp +++ b/frontend/widgets/OBSBasicControls.cpp @@ -39,6 +39,9 @@ OBSBasicControls::OBSBasicControls(OBSBasic *main) : QFrame(nullptr), ui(new Ui: connect( ui->virtualCamConfigButton, &QPushButton::clicked, this, [this]() { emit this->VirtualCamConfigButtonClicked(); }, Qt::DirectConnection); + connect( + ui->replayBufferConfigButton, &QPushButton::clicked, this, + [this]() { emit this->ReplayBufferConfigButtonClicked(); }, Qt::DirectConnection); connect( ui->modeSwitch, &QPushButton::clicked, this, [this]() { emit this->StudioModeButtonClicked(); }, Qt::DirectConnection); @@ -64,6 +67,7 @@ OBSBasicControls::OBSBasicControls(OBSBasic *main) : QFrame(nullptr), ui(new Ui: ui->saveReplayButton->setVisible(false); ui->virtualCamButton->setVisible(false); ui->virtualCamConfigButton->setVisible(false); + ui->replayBufferConfigButton->setVisible(false); /* Set up state update connections */ connect(main, &OBSBasic::StreamingPreparing, this, &OBSBasicControls::StreamingPreparing); @@ -274,6 +278,7 @@ void OBSBasicControls::EnableBroadcastFlow(bool enabled) void OBSBasicControls::EnableReplayBufferButtons(bool enabled) { ui->replayBufferButton->setVisible(enabled); + ui->replayBufferConfigButton->setVisible(enabled); } void OBSBasicControls::EnableVirtualCamButtons() diff --git a/frontend/widgets/OBSBasicControls.hpp b/frontend/widgets/OBSBasicControls.hpp index 4dae83b61802c7..39c171f0b67f5b 100644 --- a/frontend/widgets/OBSBasicControls.hpp +++ b/frontend/widgets/OBSBasicControls.hpp @@ -62,6 +62,7 @@ private slots: void SaveReplayBufferButtonClicked(); void VirtualCamButtonClicked(); void VirtualCamConfigButtonClicked(); + void ReplayBufferConfigButtonClicked(); void StudioModeButtonClicked(); void SettingsButtonClicked(); diff --git a/frontend/widgets/OBSBasic_ReplayBuffer.cpp b/frontend/widgets/OBSBasic_ReplayBuffer.cpp index 8d95f2210677ba..9e44b6406a4ca0 100644 --- a/frontend/widgets/OBSBasic_ReplayBuffer.cpp +++ b/frontend/widgets/OBSBasic_ReplayBuffer.cpp @@ -20,6 +20,7 @@ #include "OBSBasic.hpp" #include +#include #include @@ -179,6 +180,8 @@ void OBSBasic::ReplayBufferStop(int code) if (!outputHandler || !outputHandler->replayBuffer) return; + outputHandler->DestroyReplayBufferView(); + emit ReplayBufStopped(); if (sysTrayReplayBuffer) @@ -216,3 +219,22 @@ bool OBSBasic::ReplayBufferActive() return false; return outputHandler->ReplayBufferActive(); } + +void OBSBasic::OpenReplayBufferConfig() +{ + OBSBasicRBConfig dialog(rbConfig, outputHandler->ReplayBufferActive(), this); + + connect(&dialog, &OBSBasicRBConfig::Accepted, this, &OBSBasic::UpdateReplayBufferConfig); + + dialog.exec(); +} + +void OBSBasic::UpdateReplayBufferConfig(const ReplayBufferConfig &config) +{ + rbConfig = config; + + if (config.type == RBOutputSceneView) + blog(LOG_INFO, "Replay buffer output set to scene: %s", config.scene.c_str()); + else + blog(LOG_INFO, "Replay buffer output set to program view"); +} From 75f2552269dadffeac48a35931d7b591797df6d5 Mon Sep 17 00:00:00 2001 From: moxy <140682495+moxyvv@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:26:14 -0500 Subject: [PATCH 2/4] frontend: Move rbConfig access to BasicOutputHandler SimpleOutput and AdvancedOutput cannot access OBSBasic private members directly since only BasicOutputHandler is declared as a friend. Move the replay buffer scene override setup into a shared method on BasicOutputHandler to fix compilation on clang. --- frontend/utility/AdvancedOutput.cpp | 13 +------------ frontend/utility/BasicOutputHandler.cpp | 17 +++++++++++++++++ frontend/utility/BasicOutputHandler.hpp | 1 + frontend/utility/SimpleOutput.cpp | 13 +------------ 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/frontend/utility/AdvancedOutput.cpp b/frontend/utility/AdvancedOutput.cpp index cbb2a87ec26f06..5b1575cc084ca4 100644 --- a/frontend/utility/AdvancedOutput.cpp +++ b/frontend/utility/AdvancedOutput.cpp @@ -847,18 +847,7 @@ bool AdvancedOutput::StartRecording() bool AdvancedOutput::StartReplayBuffer() { - if (main->rbConfig.type == RBOutputSceneView) { - SetupReplayBufferView(main->rbConfig.scene); - if (replayBufferVideo) { - OBSEncoder enc = useStreamEncoder ? videoStreaming : videoRecording; - replayBufferVideoEncoder = obs_video_encoder_create(obs_encoder_get_id(enc), - "replay_buffer_video", nullptr, nullptr); - - OBSDataAutoRelease settings = obs_encoder_get_settings(enc); - obs_encoder_update(replayBufferVideoEncoder, settings); - obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); - } - } + SetupReplayBufferSceneOverride(useStreamEncoder ? videoStreaming : videoRecording); const char *path; const char *recFormat; diff --git a/frontend/utility/BasicOutputHandler.cpp b/frontend/utility/BasicOutputHandler.cpp index 088431e3d9dd54..63e022368f75d0 100644 --- a/frontend/utility/BasicOutputHandler.cpp +++ b/frontend/utility/BasicOutputHandler.cpp @@ -400,6 +400,23 @@ void BasicOutputHandler::SetupReplayBufferView(const std::string &sceneName) replayBufferVideo = obs_view_add(replayBufferView); } +void BasicOutputHandler::SetupReplayBufferSceneOverride(OBSEncoder baseEncoder) +{ + if (main->rbConfig.type != RBOutputSceneView) + return; + + SetupReplayBufferView(main->rbConfig.scene); + if (!replayBufferVideo) + return; + + replayBufferVideoEncoder = + obs_video_encoder_create(obs_encoder_get_id(baseEncoder), "replay_buffer_video", nullptr, nullptr); + + OBSDataAutoRelease settings = obs_encoder_get_settings(baseEncoder); + obs_encoder_update(replayBufferVideoEncoder, settings); + obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); +} + void BasicOutputHandler::DestroyReplayBufferView() { replayBufferVideoEncoder = nullptr; diff --git a/frontend/utility/BasicOutputHandler.hpp b/frontend/utility/BasicOutputHandler.hpp index 02fe0df95d6bac..d303a8308c62cf 100644 --- a/frontend/utility/BasicOutputHandler.hpp +++ b/frontend/utility/BasicOutputHandler.hpp @@ -97,6 +97,7 @@ struct BasicOutputHandler { virtual void DestroyVirtualCameraScene(); void SetupReplayBufferView(const std::string &sceneName); + void SetupReplayBufferSceneOverride(OBSEncoder baseEncoder); void DestroyReplayBufferView(); inline bool Active() const diff --git a/frontend/utility/SimpleOutput.cpp b/frontend/utility/SimpleOutput.cpp index c44a8fdf4f7e9d..f1f0d010955030 100644 --- a/frontend/utility/SimpleOutput.cpp +++ b/frontend/utility/SimpleOutput.cpp @@ -885,18 +885,7 @@ bool SimpleOutput::StartRecording() bool SimpleOutput::StartReplayBuffer() { - if (main->rbConfig.type == RBOutputSceneView) { - SetupReplayBufferView(main->rbConfig.scene); - if (replayBufferVideo) { - OBSEncoder enc = usingRecordingPreset ? videoRecording : videoStreaming; - replayBufferVideoEncoder = obs_video_encoder_create(obs_encoder_get_id(enc), - "replay_buffer_video", nullptr, nullptr); - - OBSDataAutoRelease settings = obs_encoder_get_settings(enc); - obs_encoder_update(replayBufferVideoEncoder, settings); - obs_encoder_set_video(replayBufferVideoEncoder, replayBufferVideo); - } - } + SetupReplayBufferSceneOverride(usingRecordingPreset ? videoRecording : videoStreaming); UpdateRecording(); if (!ConfigureRecording(true)) From 8a6a186070062975db84e5ab82c194ef8ba4f205 Mon Sep 17 00:00:00 2001 From: moxy <140682495+moxyvv@users.noreply.github.com> Date: Tue, 3 Mar 2026 14:49:07 -0500 Subject: [PATCH 3/4] ci: retry From 78c969b9930ab24e199725d6bda6d87bc835a049 Mon Sep 17 00:00:00 2001 From: moxy <140682495+moxyvv@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:13:20 -0500 Subject: [PATCH 4/4] ci: retry flatpak validation