mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-04 10:33:30 +00:00
UI: Refactor Virtual Camera source selector dialog
This commit is contained in:
parent
dc5813c947
commit
501a3e926d
|
@ -259,6 +259,7 @@ target_sources(
|
|||
window-basic-transform.cpp
|
||||
window-basic-transform.hpp
|
||||
window-basic-preview.hpp
|
||||
window-basic-vcam.hpp
|
||||
window-basic-vcam-config.cpp
|
||||
window-basic-vcam-config.hpp
|
||||
window-dock.cpp
|
||||
|
|
|
@ -181,7 +181,7 @@ static void OBSStopVirtualCam(void *data, calldata_t *params)
|
|||
Q_ARG(int, code));
|
||||
|
||||
obs_output_set_media(output->virtualCam, nullptr, nullptr);
|
||||
OBSBasicVCamConfig::StopVideo();
|
||||
output->DestroyVirtualCamView();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
@ -229,23 +229,30 @@ inline BasicOutputHandler::BasicOutputHandler(OBSBasic *main_) : main(main_)
|
|||
|
||||
bool BasicOutputHandler::StartVirtualCam()
|
||||
{
|
||||
if (main->vcamEnabled) {
|
||||
video_t *video = OBSBasicVCamConfig::StartVideo();
|
||||
if (!video)
|
||||
if (!main->vcamEnabled)
|
||||
return false;
|
||||
|
||||
if (!virtualCamView)
|
||||
virtualCamView = obs_view_create();
|
||||
|
||||
UpdateVirtualCamOutputSource();
|
||||
|
||||
if (!virtualCamVideo) {
|
||||
virtualCamVideo = obs_view_add(virtualCamView);
|
||||
|
||||
if (!virtualCamVideo)
|
||||
return false;
|
||||
|
||||
obs_output_set_media(virtualCam, video, obs_get_audio());
|
||||
if (!Active())
|
||||
SetupOutputs();
|
||||
|
||||
bool success = obs_output_start(virtualCam);
|
||||
|
||||
if (!success)
|
||||
OBSBasicVCamConfig::StopVideo();
|
||||
|
||||
return success;
|
||||
}
|
||||
return false;
|
||||
|
||||
obs_output_set_media(virtualCam, virtualCamVideo, obs_get_audio());
|
||||
if (!Active())
|
||||
SetupOutputs();
|
||||
|
||||
bool success = obs_output_start(virtualCam);
|
||||
if (!success)
|
||||
DestroyVirtualCamView();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void BasicOutputHandler::StopVirtualCam()
|
||||
|
@ -263,6 +270,85 @@ bool BasicOutputHandler::VirtualCamActive() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void BasicOutputHandler::UpdateVirtualCamOutputSource()
|
||||
{
|
||||
if (!main->vcamEnabled || !virtualCamView)
|
||||
return;
|
||||
|
||||
OBSSourceAutoRelease source;
|
||||
|
||||
switch (main->vcamConfig.type) {
|
||||
case VCamOutputType::InternalOutput:
|
||||
switch (main->vcamConfig.internal) {
|
||||
case VCamInternalType::Default:
|
||||
source = obs_get_output_source(0);
|
||||
break;
|
||||
case VCamInternalType::Preview:
|
||||
OBSSource s = main->GetCurrentSceneSource();
|
||||
obs_source_get_ref(s);
|
||||
source = s.Get();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VCamOutputType::SceneOutput:
|
||||
source = obs_get_source_by_name(main->vcamConfig.scene.c_str());
|
||||
break;
|
||||
case VCamOutputType::SourceOutput:
|
||||
OBSSource s =
|
||||
obs_get_source_by_name(main->vcamConfig.source.c_str());
|
||||
|
||||
if (!vCamSourceScene)
|
||||
vCamSourceScene =
|
||||
obs_scene_create_private("vcam_source");
|
||||
source = obs_source_get_ref(
|
||||
obs_scene_get_source(vCamSourceScene));
|
||||
|
||||
if (vCamSourceSceneItem &&
|
||||
(obs_sceneitem_get_source(vCamSourceSceneItem) != s)) {
|
||||
obs_sceneitem_remove(vCamSourceSceneItem);
|
||||
vCamSourceSceneItem = nullptr;
|
||||
}
|
||||
|
||||
if (!vCamSourceSceneItem) {
|
||||
vCamSourceSceneItem = obs_scene_add(vCamSourceScene, s);
|
||||
obs_source_release(s);
|
||||
|
||||
obs_sceneitem_set_bounds_type(vCamSourceSceneItem,
|
||||
OBS_BOUNDS_SCALE_INNER);
|
||||
obs_sceneitem_set_bounds_alignment(vCamSourceSceneItem,
|
||||
OBS_ALIGN_CENTER);
|
||||
|
||||
const struct vec2 size = {
|
||||
(float)obs_source_get_width(source),
|
||||
(float)obs_source_get_height(source),
|
||||
};
|
||||
obs_sceneitem_set_bounds(vCamSourceSceneItem, &size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease current = obs_view_get_source(virtualCamView, 0);
|
||||
if (source != current)
|
||||
obs_view_set_source(virtualCamView, 0, source);
|
||||
}
|
||||
|
||||
void BasicOutputHandler::DestroyVirtualCamView()
|
||||
{
|
||||
obs_view_remove(virtualCamView);
|
||||
obs_view_set_source(virtualCamView, 0, nullptr);
|
||||
virtualCamVideo = nullptr;
|
||||
|
||||
obs_view_destroy(virtualCamView);
|
||||
virtualCamView = nullptr;
|
||||
|
||||
if (!vCamSourceScene)
|
||||
return;
|
||||
|
||||
obs_scene_release(vCamSourceScene);
|
||||
vCamSourceScene = nullptr;
|
||||
vCamSourceSceneItem = nullptr;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
struct SimpleOutput : BasicOutputHandler {
|
||||
|
|
|
@ -16,6 +16,11 @@ struct BasicOutputHandler {
|
|||
bool virtualCamActive = false;
|
||||
OBSBasic *main;
|
||||
|
||||
obs_view_t *virtualCamView = nullptr;
|
||||
video_t *virtualCamVideo = nullptr;
|
||||
obs_scene_t *vCamSourceScene = nullptr;
|
||||
obs_sceneitem_t *vCamSourceSceneItem = nullptr;
|
||||
|
||||
std::string outputType;
|
||||
std::string lastError;
|
||||
|
||||
|
@ -57,6 +62,9 @@ struct BasicOutputHandler {
|
|||
virtual void Update() = 0;
|
||||
virtual void SetupOutputs() = 0;
|
||||
|
||||
virtual void UpdateVirtualCamOutputSource();
|
||||
virtual void DestroyVirtualCamView();
|
||||
|
||||
inline bool Active() const
|
||||
{
|
||||
return streamingActive || recordingActive || delayActive ||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <QMessageBox>
|
||||
#include <util/dstr.hpp>
|
||||
#include "window-basic-main.hpp"
|
||||
#include "window-basic-main-outputs.hpp"
|
||||
#include "window-basic-vcam-config.hpp"
|
||||
#include "display-helpers.hpp"
|
||||
#include "window-namedialog.hpp"
|
||||
|
@ -286,7 +287,8 @@ void OBSBasic::OverrideTransition(OBSSource transition)
|
|||
obs_transition_swap_end(transition, oldTransition);
|
||||
|
||||
// Transition overrides don't raise an event so we need to call update directly
|
||||
OBSBasicVCamConfig::UpdateOutputSource();
|
||||
if (vcamEnabled)
|
||||
outputHandler->UpdateVirtualCamOutputSource();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,6 +430,9 @@ void OBSBasic::SetTransition(OBSSource transition)
|
|||
ui->transitionRemove->setEnabled(configurable);
|
||||
ui->transitionProps->setEnabled(configurable);
|
||||
|
||||
if (vcamEnabled && vcamConfig.internal == VCamInternalType::Default)
|
||||
outputHandler->UpdateVirtualCamOutputSource();
|
||||
|
||||
if (api)
|
||||
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_CHANGED);
|
||||
}
|
||||
|
@ -695,6 +700,13 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force)
|
|||
currentScene = itemScene.Get();
|
||||
ui->scenes->setCurrentItem(item);
|
||||
ui->scenes->blockSignals(false);
|
||||
|
||||
if (vcamEnabled &&
|
||||
vcamConfig.internal ==
|
||||
VCamInternalType::Preview)
|
||||
outputHandler
|
||||
->UpdateVirtualCamOutputSource();
|
||||
|
||||
if (api)
|
||||
api->on_event(
|
||||
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
|
||||
|
|
|
@ -763,8 +763,27 @@ void OBSBasic::Save(const char *file)
|
|||
obs_data_set_double(saveData, "scaling_off_y",
|
||||
ui->preview->GetScrollY());
|
||||
|
||||
if (vcamEnabled)
|
||||
OBSBasicVCamConfig::SaveData(saveData, true);
|
||||
if (vcamEnabled) {
|
||||
OBSDataAutoRelease obj = obs_data_create();
|
||||
|
||||
obs_data_set_int(obj, "type", (int)vcamConfig.type);
|
||||
switch (vcamConfig.type) {
|
||||
case VCamOutputType::InternalOutput:
|
||||
obs_data_set_int(obj, "internal",
|
||||
(int)vcamConfig.internal);
|
||||
break;
|
||||
case VCamOutputType::SceneOutput:
|
||||
obs_data_set_string(obj, "scene",
|
||||
vcamConfig.scene.c_str());
|
||||
break;
|
||||
case VCamOutputType::SourceOutput:
|
||||
obs_data_set_string(obj, "source",
|
||||
vcamConfig.source.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
obs_data_set_obj(saveData, "virtual-camera", obj);
|
||||
}
|
||||
|
||||
if (api) {
|
||||
OBSDataAutoRelease moduleObj = obs_data_create();
|
||||
|
@ -1178,8 +1197,16 @@ retryScene:
|
|||
ui->preview->SetFixedScaling(fixedScaling);
|
||||
emit ui->preview->DisplayResized();
|
||||
|
||||
if (vcamEnabled)
|
||||
OBSBasicVCamConfig::SaveData(data, false);
|
||||
if (vcamEnabled) {
|
||||
OBSDataAutoRelease obj =
|
||||
obs_data_get_obj(data, "virtual-camera");
|
||||
|
||||
vcamConfig.type = (VCamOutputType)obs_data_get_int(obj, "type");
|
||||
vcamConfig.internal =
|
||||
(VCamInternalType)obs_data_get_int(obj, "internal");
|
||||
vcamConfig.scene = obs_data_get_string(obj, "scene");
|
||||
vcamConfig.source = obs_data_get_string(obj, "source");
|
||||
}
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
|
@ -1225,6 +1252,9 @@ retryScene:
|
|||
|
||||
disableSaving--;
|
||||
|
||||
if (vcamEnabled && vcamConfig.internal == VCamInternalType::Preview)
|
||||
outputHandler->UpdateVirtualCamOutputSource();
|
||||
|
||||
if (api) {
|
||||
api->on_event(OBS_FRONTEND_EVENT_SCENE_CHANGED);
|
||||
api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
|
||||
|
@ -1696,8 +1726,6 @@ void OBSBasic::ReplayBufferClicked()
|
|||
|
||||
void OBSBasic::AddVCamButton()
|
||||
{
|
||||
OBSBasicVCamConfig::Init();
|
||||
|
||||
vcamButton = new ControlsSplitButton(
|
||||
QTStr("Basic.Main.StartVirtualCam"), "vcamButton",
|
||||
&OBSBasic::VCamButtonClicked);
|
||||
|
@ -2752,8 +2780,6 @@ OBSBasic::~OBSBasic()
|
|||
delete cef;
|
||||
cef = nullptr;
|
||||
#endif
|
||||
|
||||
OBSBasicVCamConfig::DestroyView();
|
||||
}
|
||||
|
||||
void OBSBasic::SaveProjectNow()
|
||||
|
@ -5098,6 +5124,9 @@ void OBSBasic::on_scenes_currentItemChanged(QListWidgetItem *current,
|
|||
|
||||
SetCurrentScene(source);
|
||||
|
||||
if (vcamEnabled && vcamConfig.internal == VCamInternalType::Preview)
|
||||
outputHandler->UpdateVirtualCamOutputSource();
|
||||
|
||||
if (api)
|
||||
api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
|
||||
|
||||
|
@ -7855,8 +7884,19 @@ void OBSBasic::VCamButtonClicked()
|
|||
|
||||
void OBSBasic::VCamConfigButtonClicked()
|
||||
{
|
||||
OBSBasicVCamConfig config(this);
|
||||
config.exec();
|
||||
OBSBasicVCamConfig dialog(vcamConfig, this);
|
||||
|
||||
connect(&dialog, &OBSBasicVCamConfig::Accepted, this,
|
||||
&OBSBasic::UpdateVirtualCamConfig);
|
||||
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void OBSBasic::UpdateVirtualCamConfig(const VCamConfig &config)
|
||||
{
|
||||
vcamConfig = config;
|
||||
|
||||
outputHandler->UpdateVirtualCamOutputSource();
|
||||
}
|
||||
|
||||
void OBSBasic::on_settingsButton_clicked()
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <memory>
|
||||
#include "window-main.hpp"
|
||||
#include "window-basic-interaction.hpp"
|
||||
#include "window-basic-vcam.hpp"
|
||||
#include "window-basic-properties.hpp"
|
||||
#include "window-basic-transform.hpp"
|
||||
#include "window-basic-adv-audio.hpp"
|
||||
|
@ -51,6 +52,7 @@ class QMessageBox;
|
|||
class QListWidgetItem;
|
||||
class VolControl;
|
||||
class OBSBasicStats;
|
||||
class OBSBasicVCamConfig;
|
||||
|
||||
#include "ui_OBSBasic.h"
|
||||
#include "ui_ColorSelect.h"
|
||||
|
@ -309,6 +311,7 @@ private:
|
|||
|
||||
QPointer<ControlsSplitButton> vcamButton;
|
||||
bool vcamEnabled = false;
|
||||
VCamConfig vcamConfig;
|
||||
|
||||
QScopedPointer<QSystemTrayIcon> trayIcon;
|
||||
QPointer<QAction> sysTrayStream;
|
||||
|
@ -819,6 +822,8 @@ private slots:
|
|||
void LockVolumeControl(bool lock);
|
||||
void ResetProxyStyleSliders();
|
||||
|
||||
void UpdateVirtualCamConfig(const VCamConfig &config);
|
||||
|
||||
private:
|
||||
/* OBS Callbacks */
|
||||
static void SceneReordered(void *data, calldata_t *params);
|
||||
|
|
|
@ -5,43 +5,21 @@
|
|||
#include <util/util.hpp>
|
||||
#include <util/platform.h>
|
||||
|
||||
enum class VCamOutputType {
|
||||
Internal,
|
||||
Scene,
|
||||
Source,
|
||||
};
|
||||
|
||||
enum class VCamInternalType {
|
||||
Default,
|
||||
Preview,
|
||||
};
|
||||
|
||||
struct VCamConfig {
|
||||
VCamOutputType type = VCamOutputType::Internal;
|
||||
VCamInternalType internal = VCamInternalType::Default;
|
||||
std::string scene;
|
||||
std::string source;
|
||||
};
|
||||
|
||||
static VCamConfig *vCamConfig = nullptr;
|
||||
|
||||
OBSBasicVCamConfig::OBSBasicVCamConfig(QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::OBSBasicVCamConfig)
|
||||
OBSBasicVCamConfig::OBSBasicVCamConfig(const VCamConfig &_config,
|
||||
QWidget *parent)
|
||||
: config(_config), QDialog(parent), ui(new Ui::OBSBasicVCamConfig)
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
auto type = (int)vCamConfig->type;
|
||||
ui->outputType->setCurrentIndex(type);
|
||||
OutputTypeChanged(type);
|
||||
connect(ui->outputType,
|
||||
static_cast<void (QComboBox::*)(int)>(
|
||||
&QComboBox::currentIndexChanged),
|
||||
this, &OBSBasicVCamConfig::OutputTypeChanged);
|
||||
ui->outputType->setCurrentIndex(config.type);
|
||||
OutputTypeChanged(config.type);
|
||||
connect(ui->outputType, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(OutputTypeChanged(int)));
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
|
||||
&OBSBasicVCamConfig::Save);
|
||||
&OBSBasicVCamConfig::UpdateConfig);
|
||||
}
|
||||
|
||||
void OBSBasicVCamConfig::OutputTypeChanged(int type)
|
||||
|
@ -50,25 +28,25 @@ void OBSBasicVCamConfig::OutputTypeChanged(int type)
|
|||
list->clear();
|
||||
|
||||
switch ((VCamOutputType)type) {
|
||||
case VCamOutputType::Internal:
|
||||
case VCamOutputType::InternalOutput:
|
||||
list->addItem(QTStr("Basic.VCam.InternalDefault"));
|
||||
list->addItem(QTStr("Basic.VCam.InternalPreview"));
|
||||
list->setCurrentIndex((int)vCamConfig->internal);
|
||||
list->setCurrentIndex(config.internal);
|
||||
break;
|
||||
|
||||
case VCamOutputType::Scene: {
|
||||
case VCamOutputType::SceneOutput: {
|
||||
// Scenes in default order
|
||||
BPtr<char *> scenes = obs_frontend_get_scene_names();
|
||||
for (char **temp = scenes; *temp; temp++) {
|
||||
list->addItem(*temp);
|
||||
|
||||
if (vCamConfig->scene.compare(*temp) == 0)
|
||||
if (config.scene.compare(*temp) == 0)
|
||||
list->setCurrentIndex(list->count() - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VCamOutputType::Source: {
|
||||
case VCamOutputType::SourceOutput: {
|
||||
// Sources in alphabetical order
|
||||
std::vector<std::string> sources;
|
||||
auto AddSource = [&](obs_source_t *source) {
|
||||
|
@ -97,7 +75,7 @@ void OBSBasicVCamConfig::OutputTypeChanged(int type)
|
|||
for (auto &&source : sources) {
|
||||
list->addItem(source.c_str());
|
||||
|
||||
if (vCamConfig->source == source)
|
||||
if (config.source == source)
|
||||
list->setCurrentIndex(list->count() - 1);
|
||||
}
|
||||
break;
|
||||
|
@ -105,193 +83,27 @@ void OBSBasicVCamConfig::OutputTypeChanged(int type)
|
|||
}
|
||||
}
|
||||
|
||||
void OBSBasicVCamConfig::Save()
|
||||
void OBSBasicVCamConfig::UpdateConfig()
|
||||
{
|
||||
auto type = (VCamOutputType)ui->outputType->currentIndex();
|
||||
auto out = ui->outputSelection;
|
||||
VCamOutputType type = (VCamOutputType)ui->outputType->currentIndex();
|
||||
switch (type) {
|
||||
case VCamOutputType::Internal:
|
||||
vCamConfig->internal = (VCamInternalType)out->currentIndex();
|
||||
case VCamOutputType::InternalOutput:
|
||||
config.internal =
|
||||
(VCamInternalType)ui->outputSelection->currentIndex();
|
||||
break;
|
||||
case VCamOutputType::Scene:
|
||||
vCamConfig->scene = out->currentText().toStdString();
|
||||
case VCamOutputType::SceneOutput:
|
||||
config.scene = ui->outputSelection->currentText().toStdString();
|
||||
break;
|
||||
case VCamOutputType::Source:
|
||||
vCamConfig->source = out->currentText().toStdString();
|
||||
case VCamOutputType::SourceOutput:
|
||||
config.source =
|
||||
ui->outputSelection->currentText().toStdString();
|
||||
break;
|
||||
default:
|
||||
// unknown value, don't save type
|
||||
return;
|
||||
}
|
||||
|
||||
vCamConfig->type = type;
|
||||
config.type = type;
|
||||
|
||||
// If already running just update the source
|
||||
if (obs_frontend_virtualcam_active())
|
||||
UpdateOutputSource();
|
||||
}
|
||||
|
||||
void OBSBasicVCamConfig::SaveData(obs_data_t *data, bool saving)
|
||||
{
|
||||
if (saving) {
|
||||
OBSDataAutoRelease obj = obs_data_create();
|
||||
|
||||
obs_data_set_int(obj, "type", (int)vCamConfig->type);
|
||||
obs_data_set_int(obj, "internal", (int)vCamConfig->internal);
|
||||
obs_data_set_string(obj, "scene", vCamConfig->scene.c_str());
|
||||
obs_data_set_string(obj, "source", vCamConfig->source.c_str());
|
||||
|
||||
obs_data_set_obj(data, "virtual-camera", obj);
|
||||
} else {
|
||||
OBSDataAutoRelease obj =
|
||||
obs_data_get_obj(data, "virtual-camera");
|
||||
|
||||
vCamConfig->type =
|
||||
(VCamOutputType)obs_data_get_int(obj, "type");
|
||||
vCamConfig->internal =
|
||||
(VCamInternalType)obs_data_get_int(obj, "internal");
|
||||
vCamConfig->scene = obs_data_get_string(obj, "scene");
|
||||
vCamConfig->source = obs_data_get_string(obj, "source");
|
||||
}
|
||||
}
|
||||
|
||||
static void EventCallback(enum obs_frontend_event event, void *)
|
||||
{
|
||||
if (vCamConfig->type != VCamOutputType::Internal)
|
||||
return;
|
||||
|
||||
// Update output source if the preview scene changes
|
||||
// or if the default transition is changed
|
||||
switch (event) {
|
||||
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
|
||||
if (vCamConfig->internal != VCamInternalType::Preview)
|
||||
return;
|
||||
break;
|
||||
case OBS_FRONTEND_EVENT_TRANSITION_CHANGED:
|
||||
if (vCamConfig->internal != VCamInternalType::Default)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
OBSBasicVCamConfig::UpdateOutputSource();
|
||||
}
|
||||
|
||||
static auto staticConfig = VCamConfig{};
|
||||
|
||||
void OBSBasicVCamConfig::Init()
|
||||
{
|
||||
if (vCamConfig)
|
||||
return;
|
||||
|
||||
vCamConfig = &staticConfig;
|
||||
|
||||
obs_frontend_add_event_callback(EventCallback, nullptr);
|
||||
}
|
||||
|
||||
static obs_view_t *view = nullptr;
|
||||
static video_t *video = nullptr;
|
||||
|
||||
static obs_scene_t *sourceScene = nullptr;
|
||||
static obs_sceneitem_t *sourceSceneItem = nullptr;
|
||||
|
||||
video_t *OBSBasicVCamConfig::StartVideo()
|
||||
{
|
||||
if (!view)
|
||||
view = obs_view_create();
|
||||
|
||||
UpdateOutputSource();
|
||||
|
||||
if (!video)
|
||||
video = obs_view_add(view);
|
||||
return video;
|
||||
}
|
||||
|
||||
void OBSBasicVCamConfig::StopVideo()
|
||||
{
|
||||
obs_view_remove(view);
|
||||
obs_view_set_source(view, 0, nullptr);
|
||||
video = nullptr;
|
||||
|
||||
if (sourceScene) {
|
||||
obs_scene_release(sourceScene);
|
||||
sourceScene = nullptr;
|
||||
sourceSceneItem = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasicVCamConfig::DestroyView()
|
||||
{
|
||||
StopVideo();
|
||||
obs_view_destroy(view);
|
||||
view = nullptr;
|
||||
}
|
||||
|
||||
void OBSBasicVCamConfig::UpdateOutputSource()
|
||||
{
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
obs_source_t *source = nullptr;
|
||||
|
||||
switch ((VCamOutputType)vCamConfig->type) {
|
||||
case VCamOutputType::Internal:
|
||||
switch (vCamConfig->internal) {
|
||||
case VCamInternalType::Default:
|
||||
source = obs_get_output_source(0);
|
||||
break;
|
||||
case VCamInternalType::Preview:
|
||||
OBSSource s = OBSBasic::Get()->GetCurrentSceneSource();
|
||||
obs_source_get_ref(s);
|
||||
source = s;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case VCamOutputType::Scene:
|
||||
source = obs_get_source_by_name(vCamConfig->scene.c_str());
|
||||
break;
|
||||
|
||||
case VCamOutputType::Source:
|
||||
auto rawSource =
|
||||
obs_get_source_by_name(vCamConfig->source.c_str());
|
||||
if (!rawSource)
|
||||
break;
|
||||
|
||||
// Use a scene transform to fit the source size to the canvas
|
||||
if (!sourceScene)
|
||||
sourceScene = obs_scene_create_private(nullptr);
|
||||
source = obs_source_get_ref(obs_scene_get_source(sourceScene));
|
||||
|
||||
if (sourceSceneItem) {
|
||||
if (obs_sceneitem_get_source(sourceSceneItem) !=
|
||||
rawSource) {
|
||||
obs_sceneitem_remove(sourceSceneItem);
|
||||
sourceSceneItem = nullptr;
|
||||
}
|
||||
}
|
||||
if (!sourceSceneItem) {
|
||||
sourceSceneItem = obs_scene_add(sourceScene, rawSource);
|
||||
obs_source_release(rawSource);
|
||||
|
||||
obs_sceneitem_set_bounds_type(sourceSceneItem,
|
||||
OBS_BOUNDS_SCALE_INNER);
|
||||
obs_sceneitem_set_bounds_alignment(sourceSceneItem,
|
||||
OBS_ALIGN_CENTER);
|
||||
|
||||
const struct vec2 size = {
|
||||
(float)obs_source_get_width(source),
|
||||
(float)obs_source_get_height(source),
|
||||
};
|
||||
obs_sceneitem_set_bounds(sourceSceneItem, &size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
auto current = obs_view_get_source(view, 0);
|
||||
if (source != current)
|
||||
obs_view_set_source(view, 0, source);
|
||||
obs_source_release(source);
|
||||
obs_source_release(current);
|
||||
emit Accepted(config);
|
||||
}
|
||||
|
|
|
@ -4,27 +4,28 @@
|
|||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
#include "window-basic-vcam.hpp"
|
||||
|
||||
#include "ui_OBSBasicVCamConfig.h"
|
||||
|
||||
struct VCamConfig;
|
||||
|
||||
class OBSBasicVCamConfig : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
VCamConfig config;
|
||||
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
static video_t *StartVideo();
|
||||
static void StopVideo();
|
||||
static void DestroyView();
|
||||
|
||||
static void UpdateOutputSource();
|
||||
static void SaveData(obs_data_t *data, bool saving);
|
||||
|
||||
explicit OBSBasicVCamConfig(QWidget *parent = 0);
|
||||
explicit OBSBasicVCamConfig(const VCamConfig &config,
|
||||
QWidget *parent = 0);
|
||||
|
||||
private slots:
|
||||
void OutputTypeChanged(int type);
|
||||
void Save();
|
||||
void UpdateConfig();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::OBSBasicVCamConfig> ui;
|
||||
|
||||
signals:
|
||||
void Accepted(const VCamConfig &config);
|
||||
};
|
||||
|
|
21
UI/window-basic-vcam.hpp
Normal file
21
UI/window-basic-vcam.hpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
enum VCamOutputType {
|
||||
InternalOutput,
|
||||
SceneOutput,
|
||||
SourceOutput,
|
||||
};
|
||||
|
||||
enum VCamInternalType {
|
||||
Default,
|
||||
Preview,
|
||||
};
|
||||
|
||||
struct VCamConfig {
|
||||
VCamOutputType type = VCamOutputType::InternalOutput;
|
||||
VCamInternalType internal = VCamInternalType::Default;
|
||||
std::string scene;
|
||||
std::string source;
|
||||
};
|
Loading…
Reference in a new issue