UI: Add virtual camera to UI
Adds a virtual camera button to the main user interface. If virtual camera is not installed, it will not add the button. On Windows, it detects whether the virtual camera filters are properly registered, and will only add the button if the virtual camera filter is confirmed registered. Also adds a virtual camera option to the auto-configuration wizard, which will just simply set the user's resolution/scale to 1920x1080 at 30 FPS.master
parent
6377fe3177
commit
a72a52fa38
|
@ -150,6 +150,7 @@ Basic.AutoConfig.StartPage="Usage Information"
|
|||
Basic.AutoConfig.StartPage.SubTitle="Specify what you want to use the program for"
|
||||
Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimize for streaming, recording is secondary"
|
||||
Basic.AutoConfig.StartPage.PrioritizeRecording="Optimize just for recording, I will not be streaming"
|
||||
Basic.AutoConfig.StartPage.PrioritizeVirtualCam="I will only be using the virtual camera"
|
||||
Basic.AutoConfig.VideoPage="Video Settings"
|
||||
Basic.AutoConfig.VideoPage.SubTitle="Specify the desired video settings you would like to use"
|
||||
Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Use Current (%1x%2)"
|
||||
|
@ -520,6 +521,7 @@ Basic.Main.StartRecording="Start Recording"
|
|||
Basic.Main.StartReplayBuffer="Start Replay Buffer"
|
||||
Basic.Main.SaveReplay="Save Replay"
|
||||
Basic.Main.StartStreaming="Start Streaming"
|
||||
Basic.Main.StartVirtualCam="Start Virtual Camera"
|
||||
Basic.Main.StopRecording="Stop Recording"
|
||||
Basic.Main.PauseRecording="Pause Recording"
|
||||
Basic.Main.UnpauseRecording="Unpause Recording"
|
||||
|
@ -529,6 +531,7 @@ Basic.Main.StoppingReplayBuffer="Stopping Replay Buffer..."
|
|||
Basic.Main.StopStreaming="Stop Streaming"
|
||||
Basic.Main.StoppingStreaming="Stopping Stream..."
|
||||
Basic.Main.ForceStopStreaming="Stop Streaming (discard delay)"
|
||||
Basic.Main.StopVirtualCam="Stop Virtual Camera"
|
||||
Basic.Main.Group="Group %1"
|
||||
Basic.Main.GroupItems="Group Selected Items"
|
||||
Basic.Main.Ungroup="Ungroup"
|
||||
|
|
|
@ -373,6 +373,14 @@ Section -FinishSection
|
|||
ClearErrors
|
||||
WriteRegDWORD HKLM "Software\Khronos\Vulkan\ImplicitLayers" "$APPDATA\obs-studio-hook\obs-vulkan32.json" 0
|
||||
|
||||
# ---------------------------------------
|
||||
# Register virtual camera dlls
|
||||
|
||||
Exec '"$SYSDIR\regsvr32.exe" /s "$INSTDIR\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll"'
|
||||
${if} ${RunningX64}
|
||||
Exec '"$SYSDIR\regsvr32.exe" /s "$INSTDIR\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll"'
|
||||
${endif}
|
||||
|
||||
# ---------------------------------------
|
||||
|
||||
ClearErrors
|
||||
|
@ -420,6 +428,12 @@ Section "un.obs-studio Program Files" UninstallSection1
|
|||
SetShellVarContext current
|
||||
ClearErrors
|
||||
|
||||
; Unregister virtual camera dlls
|
||||
Exec '"$SYSDIR\regsvr32.exe" /u /s "$INSTDIR\data\obs-plugins\win-dshow\obs-virtualcam-module32.dll"'
|
||||
${if} ${RunningX64}
|
||||
Exec '"$SYSDIR\regsvr32.exe" /u /s "$INSTDIR\data\obs-plugins\win-dshow\obs-virtualcam-module64.dll"'
|
||||
${endif}
|
||||
|
||||
; Remove from registry...
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
|
||||
DeleteRegKey HKLM "SOFTWARE\${APPNAME}"
|
||||
|
|
|
@ -75,6 +75,7 @@ bool opt_start_streaming = false;
|
|||
bool opt_start_recording = false;
|
||||
bool opt_studio_mode = false;
|
||||
bool opt_start_replaybuffer = false;
|
||||
bool opt_start_virtualcam = false;
|
||||
bool opt_minimize_tray = false;
|
||||
bool opt_allow_opengl = false;
|
||||
bool opt_always_on_top = false;
|
||||
|
@ -2425,6 +2426,9 @@ int main(int argc, char *argv[])
|
|||
} else if (arg_is(argv[i], "--startreplaybuffer", nullptr)) {
|
||||
opt_start_replaybuffer = true;
|
||||
|
||||
} else if (arg_is(argv[i], "--startvirtualcam", nullptr)) {
|
||||
opt_start_virtualcam = true;
|
||||
|
||||
} else if (arg_is(argv[i], "--collection", nullptr)) {
|
||||
if (++i < argc)
|
||||
opt_starting_collection = argv[i];
|
||||
|
@ -2451,7 +2455,8 @@ int main(int argc, char *argv[])
|
|||
<< "--help, -h: Get list of available commands.\n\n"
|
||||
<< "--startstreaming: Automatically start streaming.\n"
|
||||
<< "--startrecording: Automatically start recording.\n"
|
||||
<< "--startreplaybuffer: Start replay buffer.\n\n"
|
||||
<< "--startreplaybuffer: Start replay buffer.\n"
|
||||
<< "--startvirtualcam: Start virtual camera (if available).\n\n"
|
||||
<< "--collection <string>: Use specific scene collection."
|
||||
<< "\n"
|
||||
<< "--profile <string>: Use specific profile.\n"
|
||||
|
|
|
@ -225,6 +225,7 @@ extern std::string remuxFilename;
|
|||
extern bool opt_start_streaming;
|
||||
extern bool opt_start_recording;
|
||||
extern bool opt_start_replaybuffer;
|
||||
extern bool opt_start_virtualcam;
|
||||
extern bool opt_minimize_tray;
|
||||
extern bool opt_studio_mode;
|
||||
extern bool opt_allow_opengl;
|
||||
|
|
|
@ -1424,6 +1424,40 @@ static bool Update(wchar_t *cmdLine)
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------- *
|
||||
* Install virtual camera */
|
||||
|
||||
if (!bIsPortable) {
|
||||
wchar_t regsvr[MAX_PATH];
|
||||
wchar_t src[MAX_PATH];
|
||||
wchar_t tmp[MAX_PATH];
|
||||
wchar_t tmp2[MAX_PATH];
|
||||
|
||||
SHGetFolderPathW(nullptr, CSIDL_SYSTEM, nullptr,
|
||||
SHGFP_TYPE_CURRENT, regsvr);
|
||||
StringCbCat(regsvr, sizeof(regsvr), L"\\regsvr32.exe");
|
||||
|
||||
GetCurrentDirectoryW(_countof(src), src);
|
||||
StringCbCat(src, sizeof(src),
|
||||
L"\\data\\obs-plugins\\win-dshow\\");
|
||||
|
||||
StringCbCopy(tmp, sizeof(tmp), L"\"\"");
|
||||
StringCbCat(tmp, sizeof(tmp), regsvr);
|
||||
StringCbCat(tmp, sizeof(tmp), L"\" /s \"");
|
||||
StringCbCat(tmp, sizeof(tmp), src);
|
||||
StringCbCat(tmp, sizeof(tmp), L"obs-virtualcam-module");
|
||||
|
||||
StringCbCopy(tmp2, sizeof(tmp2), tmp);
|
||||
StringCbCat(tmp2, sizeof(tmp2), L"32.dll\"\"");
|
||||
_wsystem(tmp2);
|
||||
|
||||
if (is_64bit_windows()) {
|
||||
StringCbCopy(tmp2, sizeof(tmp2), tmp);
|
||||
StringCbCat(tmp2, sizeof(tmp2), L"64.dll\"\"");
|
||||
_wsystem(tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------- *
|
||||
* Update hook files and vulkan registry */
|
||||
|
||||
|
|
|
@ -990,7 +990,7 @@ void AutoConfigTestPage::FinalizeResults()
|
|||
return new QLabel(QTStr(str), this);
|
||||
};
|
||||
|
||||
if (wiz->type != AutoConfig::Type::Recording) {
|
||||
if (wiz->type == AutoConfig::Type::Streaming) {
|
||||
const char *serverType = wiz->customServer ? "rtmp_custom"
|
||||
: "rtmp_common";
|
||||
|
||||
|
@ -1093,7 +1093,7 @@ void AutoConfigTestPage::NextStage()
|
|||
started = true;
|
||||
}
|
||||
|
||||
if (wiz->type == AutoConfig::Type::Recording) {
|
||||
if (wiz->type != AutoConfig::Type::Streaming) {
|
||||
stage = Stage::StreamEncoder;
|
||||
} else if (!wiz->bandwidthTest) {
|
||||
stage = Stage::BandwidthTest;
|
||||
|
@ -1163,8 +1163,17 @@ AutoConfigTestPage::~AutoConfigTestPage()
|
|||
|
||||
void AutoConfigTestPage::initializePage()
|
||||
{
|
||||
if (wiz->type == AutoConfig::Type::VirtualCam) {
|
||||
wiz->idealResolutionCX = wiz->baseResolutionCX;
|
||||
wiz->idealResolutionCY = wiz->baseResolutionCY;
|
||||
wiz->idealFPSNum = 30;
|
||||
wiz->idealFPSDen = 1;
|
||||
stage = Stage::Finished;
|
||||
} else {
|
||||
stage = Stage::Starting;
|
||||
}
|
||||
|
||||
setSubTitle(QTStr(SUBTITLE_TESTING));
|
||||
stage = Stage::Starting;
|
||||
softwareTested = false;
|
||||
cancel = false;
|
||||
DeleteLayout(results);
|
||||
|
|
|
@ -69,6 +69,18 @@ AutoConfigStartPage::AutoConfigStartPage(QWidget *parent)
|
|||
ui->setupUi(this);
|
||||
setTitle(QTStr("Basic.AutoConfig.StartPage"));
|
||||
setSubTitle(QTStr("Basic.AutoConfig.StartPage.SubTitle"));
|
||||
|
||||
OBSBasic *main = OBSBasic::Get();
|
||||
if (main->VCamEnabled()) {
|
||||
QRadioButton *prioritizeVCam = new QRadioButton(
|
||||
QTStr("Basic.AutoConfig.StartPage.PrioritizeVirtualCam"),
|
||||
this);
|
||||
QBoxLayout *box = reinterpret_cast<QBoxLayout *>(layout());
|
||||
box->insertWidget(2, prioritizeVCam);
|
||||
|
||||
connect(prioritizeVCam, &QPushButton::clicked, this,
|
||||
&AutoConfigStartPage::PrioritizeVCam);
|
||||
}
|
||||
}
|
||||
|
||||
AutoConfigStartPage::~AutoConfigStartPage()
|
||||
|
@ -78,7 +90,9 @@ AutoConfigStartPage::~AutoConfigStartPage()
|
|||
|
||||
int AutoConfigStartPage::nextId() const
|
||||
{
|
||||
return AutoConfig::VideoPage;
|
||||
return wiz->type == AutoConfig::Type::VirtualCam
|
||||
? AutoConfig::TestPage
|
||||
: AutoConfig::VideoPage;
|
||||
}
|
||||
|
||||
void AutoConfigStartPage::on_prioritizeStreaming_clicked()
|
||||
|
@ -91,6 +105,11 @@ void AutoConfigStartPage::on_prioritizeRecording_clicked()
|
|||
wiz->type = AutoConfig::Type::Recording;
|
||||
}
|
||||
|
||||
void AutoConfigStartPage::PrioritizeVCam()
|
||||
{
|
||||
wiz->type = AutoConfig::Type::VirtualCam;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x
|
||||
|
|
|
@ -33,6 +33,7 @@ class AutoConfig : public QWizard {
|
|||
Invalid,
|
||||
Streaming,
|
||||
Recording,
|
||||
VirtualCam,
|
||||
};
|
||||
|
||||
enum class Service {
|
||||
|
@ -139,6 +140,7 @@ public:
|
|||
public slots:
|
||||
void on_prioritizeStreaming_clicked();
|
||||
void on_prioritizeRecording_clicked();
|
||||
void PrioritizeVCam();
|
||||
};
|
||||
|
||||
class AutoConfigVideoPage : public QWizardPage {
|
||||
|
|
|
@ -14,6 +14,7 @@ volatile bool streaming_active = false;
|
|||
volatile bool recording_active = false;
|
||||
volatile bool recording_paused = false;
|
||||
volatile bool replaybuf_active = false;
|
||||
volatile bool virtualcam_active = false;
|
||||
|
||||
#define RTMP_PROTOCOL "rtmp"
|
||||
|
||||
|
@ -139,6 +140,30 @@ static void OBSReplayBufferStopping(void *data, calldata_t *params)
|
|||
UNUSED_PARAMETER(params);
|
||||
}
|
||||
|
||||
static void OBSStartVirtualCam(void *data, calldata_t *params)
|
||||
{
|
||||
BasicOutputHandler *output = static_cast<BasicOutputHandler *>(data);
|
||||
|
||||
output->virtualCamActive = true;
|
||||
os_atomic_set_bool(&virtualcam_active, true);
|
||||
QMetaObject::invokeMethod(output->main, "OnVirtualCamStart");
|
||||
|
||||
UNUSED_PARAMETER(params);
|
||||
}
|
||||
|
||||
static void OBSStopVirtualCam(void *data, calldata_t *params)
|
||||
{
|
||||
BasicOutputHandler *output = static_cast<BasicOutputHandler *>(data);
|
||||
int code = (int)calldata_int(params, "code");
|
||||
|
||||
output->virtualCamActive = false;
|
||||
os_atomic_set_bool(&virtualcam_active, false);
|
||||
QMetaObject::invokeMethod(output->main, "OnVirtualCamStop",
|
||||
Q_ARG(int, code));
|
||||
|
||||
UNUSED_PARAMETER(params);
|
||||
}
|
||||
|
||||
static void FindBestFilename(string &strPath, bool noSpace)
|
||||
{
|
||||
int num = 2;
|
||||
|
@ -197,6 +222,49 @@ static bool CreateAACEncoder(OBSEncoder &res, string &id, int bitrate,
|
|||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
inline BasicOutputHandler::BasicOutputHandler(OBSBasic *main_) : main(main_)
|
||||
{
|
||||
if (main->vcamEnabled) {
|
||||
virtualCam = obs_output_create("virtualcam_output",
|
||||
"virtualcam_output", nullptr,
|
||||
nullptr);
|
||||
obs_output_release(virtualCam);
|
||||
|
||||
signal_handler_t *signal =
|
||||
obs_output_get_signal_handler(virtualCam);
|
||||
startVirtualCam.Connect(signal, "start", OBSStartVirtualCam,
|
||||
this);
|
||||
stopVirtualCam.Connect(signal, "stop", OBSStopVirtualCam, this);
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicOutputHandler::StartVirtualCam()
|
||||
{
|
||||
if (main->vcamEnabled) {
|
||||
obs_output_set_media(virtualCam, obs_get_video(),
|
||||
obs_get_audio());
|
||||
return obs_output_start(virtualCam);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BasicOutputHandler::StopVirtualCam()
|
||||
{
|
||||
if (main->vcamEnabled) {
|
||||
obs_output_stop(virtualCam);
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicOutputHandler::VirtualCamActive() const
|
||||
{
|
||||
if (main->vcamEnabled) {
|
||||
return obs_output_active(virtualCam);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
struct SimpleOutput : BasicOutputHandler {
|
||||
OBSEncoder aacStreaming;
|
||||
OBSEncoder h264Streaming;
|
||||
|
|
|
@ -8,10 +8,12 @@ struct BasicOutputHandler {
|
|||
OBSOutput fileOutput;
|
||||
OBSOutput streamOutput;
|
||||
OBSOutput replayBuffer;
|
||||
OBSOutput virtualCam;
|
||||
bool streamingActive = false;
|
||||
bool recordingActive = false;
|
||||
bool delayActive = false;
|
||||
bool replayBufferActive = false;
|
||||
bool virtualCamActive = false;
|
||||
OBSBasic *main;
|
||||
|
||||
std::string outputType;
|
||||
|
@ -23,31 +25,36 @@ struct BasicOutputHandler {
|
|||
OBSSignal stopReplayBuffer;
|
||||
OBSSignal startStreaming;
|
||||
OBSSignal stopStreaming;
|
||||
OBSSignal startVirtualCam;
|
||||
OBSSignal stopVirtualCam;
|
||||
OBSSignal streamDelayStarting;
|
||||
OBSSignal streamStopping;
|
||||
OBSSignal recordStopping;
|
||||
OBSSignal replayBufferStopping;
|
||||
|
||||
inline BasicOutputHandler(OBSBasic *main_) : main(main_) {}
|
||||
inline BasicOutputHandler(OBSBasic *main_);
|
||||
|
||||
virtual ~BasicOutputHandler(){};
|
||||
|
||||
virtual bool StartStreaming(obs_service_t *service) = 0;
|
||||
virtual bool StartRecording() = 0;
|
||||
virtual bool StartReplayBuffer() { return false; }
|
||||
virtual bool StartVirtualCam();
|
||||
virtual void StopStreaming(bool force = false) = 0;
|
||||
virtual void StopRecording(bool force = false) = 0;
|
||||
virtual void StopReplayBuffer(bool force = false) { (void)force; }
|
||||
virtual void StopVirtualCam();
|
||||
virtual bool StreamingActive() const = 0;
|
||||
virtual bool RecordingActive() const = 0;
|
||||
virtual bool ReplayBufferActive() const { return false; }
|
||||
virtual bool VirtualCamActive() const;
|
||||
|
||||
virtual void Update() = 0;
|
||||
|
||||
inline bool Active() const
|
||||
{
|
||||
return streamingActive || recordingActive || delayActive ||
|
||||
replayBufferActive;
|
||||
replayBufferActive || virtualCamActive;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1080,6 +1080,12 @@ retryScene:
|
|||
opt_start_replaybuffer = false;
|
||||
}
|
||||
|
||||
if (opt_start_virtualcam) {
|
||||
QMetaObject::invokeMethod(this, "StartVirtualCam",
|
||||
Qt::QueuedConnection);
|
||||
opt_start_virtualcam = false;
|
||||
}
|
||||
|
||||
copyStrings.clear();
|
||||
copyFiltersString = nullptr;
|
||||
|
||||
|
@ -1518,6 +1524,18 @@ void OBSBasic::ReplayBufferClicked()
|
|||
StartReplayBuffer();
|
||||
};
|
||||
|
||||
void OBSBasic::AddVCamButton()
|
||||
{
|
||||
vcamButton = new ReplayBufferButton(QTStr("Basic.Main.StartVirtualCam"),
|
||||
this);
|
||||
vcamButton->setCheckable(true);
|
||||
connect(vcamButton.data(), &QPushButton::clicked, this,
|
||||
&OBSBasic::VCamButtonClicked);
|
||||
|
||||
vcamButton->setProperty("themeID", "vcamButton");
|
||||
ui->buttonsVLayout->insertWidget(2, vcamButton);
|
||||
}
|
||||
|
||||
void OBSBasic::ResetOutputs()
|
||||
{
|
||||
ProfileScope("OBSBasic::ResetOutputs");
|
||||
|
@ -1645,6 +1663,13 @@ void OBSBasic::OBSInit()
|
|||
cef = obs_browser_init_panel();
|
||||
#endif
|
||||
|
||||
obs_data_t *obsData = obs_get_private_data();
|
||||
vcamEnabled = obs_data_get_bool(obsData, "vcamEnabled");
|
||||
if (vcamEnabled) {
|
||||
AddVCamButton();
|
||||
}
|
||||
obs_data_release(obsData);
|
||||
|
||||
InitBasicConfigDefaults2();
|
||||
|
||||
CheckForSimpleModeX264Fallback();
|
||||
|
@ -2248,6 +2273,23 @@ void OBSBasic::CreateHotkeys()
|
|||
LoadHotkeyPair(replayBufHotkeys, "OBSBasic.StartReplayBuffer",
|
||||
"OBSBasic.StopReplayBuffer");
|
||||
|
||||
if (vcamEnabled) {
|
||||
vcamHotkeys = obs_hotkey_pair_register_frontend(
|
||||
"OBSBasic.StartVirtualCam",
|
||||
Str("Basic.Main.StartVirtualCam"),
|
||||
"OBSBasic.StopVirtualCam",
|
||||
Str("Basic.Main.StopVirtualCam"),
|
||||
MAKE_CALLBACK(!basic.outputHandler->VirtualCamActive(),
|
||||
basic.StartVirtualCam,
|
||||
"Starting virtual camera"),
|
||||
MAKE_CALLBACK(basic.outputHandler->VirtualCamActive(),
|
||||
basic.StopVirtualCam,
|
||||
"Stopping virtual camera"),
|
||||
this, this);
|
||||
LoadHotkeyPair(vcamHotkeys, "OBSBasic.StartVirtualCam",
|
||||
"OBSBasic.StopVirtualCam");
|
||||
}
|
||||
|
||||
togglePreviewHotkeys = obs_hotkey_pair_register_frontend(
|
||||
"OBSBasic.EnablePreview",
|
||||
Str("Basic.Main.PreviewConextMenu.Enable"),
|
||||
|
@ -5247,6 +5289,10 @@ void OBSBasic::OpenSceneFilters()
|
|||
"==== Streaming Start ==============================================="
|
||||
#define STREAMING_STOP \
|
||||
"==== Streaming Stop ================================================"
|
||||
#define VIRTUAL_CAM_START \
|
||||
"==== Virtual Camera Start =========================================="
|
||||
#define VIRTUAL_CAM_STOP \
|
||||
"==== Virtual Camera Stop ==========================================="
|
||||
|
||||
void OBSBasic::StartStreaming()
|
||||
{
|
||||
|
@ -5967,6 +6013,61 @@ void OBSBasic::ReplayBufferStop(int code)
|
|||
UpdateReplayBuffer(false);
|
||||
}
|
||||
|
||||
void OBSBasic::StartVirtualCam()
|
||||
{
|
||||
if (!outputHandler || !outputHandler->virtualCam)
|
||||
return;
|
||||
if (outputHandler->VirtualCamActive())
|
||||
return;
|
||||
if (disableOutputsRef)
|
||||
return;
|
||||
|
||||
SaveProject();
|
||||
|
||||
if (!outputHandler->StartVirtualCam()) {
|
||||
vcamButton->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasic::StopVirtualCam()
|
||||
{
|
||||
if (!outputHandler || !outputHandler->virtualCam)
|
||||
return;
|
||||
|
||||
SaveProject();
|
||||
|
||||
if (outputHandler->VirtualCamActive())
|
||||
outputHandler->StopVirtualCam();
|
||||
|
||||
OnDeactivate();
|
||||
}
|
||||
|
||||
void OBSBasic::OnVirtualCamStart()
|
||||
{
|
||||
if (!outputHandler || !outputHandler->virtualCam)
|
||||
return;
|
||||
|
||||
vcamButton->setText(QTStr("Basic.Main.StopVirtualCam"));
|
||||
vcamButton->setChecked(true);
|
||||
|
||||
OnActivate();
|
||||
|
||||
blog(LOG_INFO, VIRTUAL_CAM_START);
|
||||
}
|
||||
|
||||
void OBSBasic::OnVirtualCamStop(int)
|
||||
{
|
||||
if (!outputHandler || !outputHandler->virtualCam)
|
||||
return;
|
||||
|
||||
vcamButton->setText(QTStr("Basic.Main.StartVirtualCam"));
|
||||
vcamButton->setChecked(false);
|
||||
|
||||
blog(LOG_INFO, VIRTUAL_CAM_STOP);
|
||||
|
||||
OnDeactivate();
|
||||
}
|
||||
|
||||
void OBSBasic::on_streamButton_clicked()
|
||||
{
|
||||
if (outputHandler->StreamingActive()) {
|
||||
|
@ -6073,6 +6174,20 @@ void OBSBasic::on_recordButton_clicked()
|
|||
}
|
||||
}
|
||||
|
||||
void OBSBasic::VCamButtonClicked()
|
||||
{
|
||||
if (outputHandler->VirtualCamActive()) {
|
||||
StopVirtualCam();
|
||||
} else {
|
||||
if (!UIValidation::NoSourcesConfirmation(this)) {
|
||||
vcamButton->setChecked(false);
|
||||
return;
|
||||
}
|
||||
|
||||
StartVirtualCam();
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasic::on_settingsButton_clicked()
|
||||
{
|
||||
on_action_Settings_triggered();
|
||||
|
|
|
@ -166,6 +166,7 @@ class OBSBasic : public OBSMainWindow {
|
|||
friend class ReplayBufferButton;
|
||||
friend class ExtraBrowsersModel;
|
||||
friend class ExtraBrowsersDelegate;
|
||||
friend struct BasicOutputHandler;
|
||||
friend struct OBSStudioAPI;
|
||||
|
||||
enum class MoveDir { Up, Down, Left, Right };
|
||||
|
@ -256,6 +257,9 @@ private:
|
|||
QScopedPointer<QPushButton> pause;
|
||||
QScopedPointer<QPushButton> replay;
|
||||
|
||||
QPointer<QPushButton> vcamButton;
|
||||
bool vcamEnabled = false;
|
||||
|
||||
QScopedPointer<QSystemTrayIcon> trayIcon;
|
||||
QPointer<QAction> sysTrayStream;
|
||||
QPointer<QAction> sysTrayRecord;
|
||||
|
@ -382,7 +386,7 @@ private:
|
|||
QModelIndexList GetAllSelectedSourceItems();
|
||||
|
||||
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, pauseHotkeys,
|
||||
replayBufHotkeys, togglePreviewHotkeys;
|
||||
replayBufHotkeys, vcamHotkeys, togglePreviewHotkeys;
|
||||
obs_hotkey_id forceStreamingStopHotkey;
|
||||
|
||||
void InitDefaultTransitions();
|
||||
|
@ -561,6 +565,12 @@ public slots:
|
|||
void ReplayBufferStopping();
|
||||
void ReplayBufferStop(int code);
|
||||
|
||||
void StartVirtualCam();
|
||||
void StopVirtualCam();
|
||||
|
||||
void OnVirtualCamStart();
|
||||
void OnVirtualCamStop(int code);
|
||||
|
||||
void SaveProjectDeferred();
|
||||
void SaveProject();
|
||||
|
||||
|
@ -740,6 +750,8 @@ public:
|
|||
return os_atomic_load_bool(&previewProgramMode);
|
||||
}
|
||||
|
||||
inline bool VCamEnabled() const { return vcamEnabled; }
|
||||
|
||||
bool StreamingActive() const;
|
||||
bool Active() const;
|
||||
|
||||
|
@ -747,6 +759,7 @@ public:
|
|||
int ResetVideo();
|
||||
bool ResetAudio();
|
||||
|
||||
void AddVCamButton();
|
||||
void ResetOutputs();
|
||||
|
||||
void ResetAudioDevice(const char *sourceId, const char *deviceId,
|
||||
|
@ -887,6 +900,7 @@ private slots:
|
|||
|
||||
void on_streamButton_clicked();
|
||||
void on_recordButton_clicked();
|
||||
void VCamButtonClicked();
|
||||
void on_settingsButton_clicked();
|
||||
|
||||
void on_actionHelpPortal_triggered();
|
||||
|
|
Loading…
Reference in New Issue