diff --git a/main-window.cpp b/main-window.cpp index 4ec51c8..b5eb070 100644 --- a/main-window.cpp +++ b/main-window.cpp @@ -9,6 +9,7 @@ using namespace std; MainWindow::MainWindow(OBSManager *obs) : mBoxMain(Gtk::Orientation::ORIENTATION_VERTICAL, 2), + mButtonPreview("Start Preview"), mButtonStart("Start Recording"), mButtonSettings("Settings"), mButtonExit("Exit"), @@ -21,7 +22,11 @@ MainWindow::MainWindow(OBSManager *obs) set_border_width(10); mOBS = obs; + mOBS->startRecording.connect(sigc::mem_fun(*this, &MainWindow::recordingStarted)); + mOBS->stopRecording.connect(sigc::mem_fun(*this, &MainWindow::recordingStopped)); + mButtonPreview.signal_clicked().connect( + sigc::mem_fun(*this, &MainWindow::onPreviewClicked)); mButtonStart.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::onStartClicked)); mButtonSettings.signal_clicked().connect( @@ -29,6 +34,7 @@ MainWindow::MainWindow(OBSManager *obs) mButtonExit.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::onExitClicked)); + mBoxMain.add(mButtonPreview); mBoxMain.add(mButtonStart); mBoxMain.add(mButtonSettings); mBoxMain.add(mButtonExit); @@ -50,11 +56,19 @@ MainWindow::~MainWindow() mOBS->Cleanup(); } -void MainWindow::onStartClicked() +void MainWindow::onPreviewClicked() { mPreviewWindow.show(); } +void MainWindow::onStartClicked() +{ + if (mOBS->IsRecording()) + mOBS->StopRecording(); + else + mOBS->StartRecording(); +} + void MainWindow::onSettingsClicked() { mSettingsWindow.set_transient_for(*this); @@ -67,5 +81,15 @@ void MainWindow::onExitClicked() Gtk::Main::quit(); } +void MainWindow::recordingStarted() +{ + mButtonStart.set_label("Stop Recording"); +} + +void MainWindow::recordingStopped() +{ + mButtonStart.set_label("Start Recording"); +} + diff --git a/main-window.hpp b/main-window.hpp index 6df5941..57cb5a5 100644 --- a/main-window.hpp +++ b/main-window.hpp @@ -14,16 +14,22 @@ public: virtual ~MainWindow(); private: OBSManager *mOBS; + void onPreviewClicked(); void onStartClicked(); void onSettingsClicked(); void onExitClicked(); Gtk::Box mBoxMain; + Gtk::Button mButtonPreview; Gtk::Button mButtonStart; Gtk::Button mButtonSettings; Gtk::Button mButtonExit; Gtk::Label mLabelVersion; SettingsWindow mSettingsWindow; PreviewWindow mPreviewWindow; + + // Signals + void recordingStarted(); + void recordingStopped(); }; #endif diff --git a/obs-manager.cpp b/obs-manager.cpp index d0dd3e2..871175d 100644 --- a/obs-manager.cpp +++ b/obs-manager.cpp @@ -1,24 +1,30 @@ #include "obs-manager.hpp" #include "settings-manager.hpp" -#include -#include -#include -#include -#include #include #include #include #include using namespace std; -using namespace Glib; static void obs_render(void *param, uint32_t cx, uint32_t cy) { obs_render_main_texture(); } +static void OBSStartRecording(void *data, calldata_t *params) +{ + OBSManager *o = static_cast(data); + o->startRecording.emit(); +} + +static void OBSStopRecording(void *data, calldata_t *params) +{ + OBSManager *o = static_cast(data); + o->stopRecording.emit(); +} + OBSManager::OBSManager() { mPlugins = { @@ -35,9 +41,9 @@ OBSManager::~OBSManager() Cleanup(); } -ustring OBSManager::GetVersion() +string OBSManager::GetVersion() { - return ustring(obs_get_version_string()); + return string(obs_get_version_string()); } void OBSManager::Initialize() @@ -45,7 +51,7 @@ void OBSManager::Initialize() if (isInitialized) return; - sources = list(); + mSources = list(); auto settings = new SettingsManager(); LoadSettings(settings); @@ -53,7 +59,6 @@ void OBSManager::Initialize() throw runtime_error("Failed to initialize OBS"); loadPlugins(); - printTypes(); obs_video_info v = {}; v.graphics_module = "libobs-opengl.so.0"; @@ -92,13 +97,13 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) init.window.id = wid; init.window.display = (void*)wdisplay; - display = obs_display_create(&init, 0); - if (display == nullptr) + mDisplay = obs_display_create(&init, 0); + if (mDisplay == nullptr) throw runtime_error("Failed to create display"); - obs_display_add_draw_callback(display, obs_render, nullptr); + obs_display_add_draw_callback(mDisplay, obs_render, nullptr); - obs_scene_t *scene = obs_scene_create("scene1"); + OBSScene scene = obs_scene_create("scene1"); if (scene == NULL) throw runtime_error("Couldn't create scene\n"); @@ -106,7 +111,7 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) { auto source = CreateScreenSource(); obs_scene_add(scene, source); - sources.push_back(source); + mSources.push_back(source); } if (settings->GetBool(SETTINGS_KEY_WEBCAM_ENABLED)) @@ -117,14 +122,14 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) auto source = CreateWebcamSource(); auto item = obs_scene_add(scene, source); obs_sceneitem_set_scale(item, &scale); - sources.push_back(source); + mSources.push_back(source); } if (settings->GetBool(SETTINGS_KEY_AUDIO_ENABLED)) { auto source = CreateAudioSource(); obs_scene_add(scene, source); - sources.push_back(source); + mSources.push_back(source); } obs_set_output_source(0, obs_scene_get_source(scene)); @@ -153,31 +158,34 @@ void OBSManager::StartRecording() obs_data_set_string(settings, "directory", path.c_str()); obs_data_set_string(settings, "url", fileName.c_str()); - output = obs_output_create("ffmpeg_output", "ffmpeg_output", nullptr, nullptr); - obs_output_set_video_encoder(output, venc); - obs_output_set_audio_encoder(output, aenc, 0); - obs_output_update(output, settings); - obs_output_set_media(output, obs_get_video(), obs_get_audio()); + mOutput = obs_output_create("ffmpeg_output", "ffmpeg_output", nullptr, nullptr); + obs_output_set_video_encoder(mOutput, venc); + obs_output_set_audio_encoder(mOutput, aenc, 0); + obs_output_update(mOutput, settings); + obs_output_set_media(mOutput, obs_get_video(), obs_get_audio()); obs_data_release(settings); - if (!obs_output_start(output)) + if (!obs_output_start(mOutput)) throw runtime_error("Failed to start recording"); + obsStartRecording.Connect(obs_output_get_signal_handler(mOutput), "start", OBSStartRecording, this); + obsStopRecording.Connect(obs_output_get_signal_handler(mOutput), "stop", OBSStopRecording, this); + isRecording = true; } void OBSManager::StopRecording() { - if (isRecording && output != nullptr) - obs_output_stop(output); + if (isRecording && mOutput != nullptr) + obs_output_stop(mOutput); isRecording = false; } -obs_source_t *OBSManager::CreateScreenSource() +OBSSource OBSManager::CreateScreenSource() { obs_data_t *settings = obs_data_create(); - obs_source_t *source = obs_source_create("xshm_input", "Screen Source", settings, NULL); + OBSSource source = obs_source_create("xshm_input", "Screen Source", settings, NULL); if (source == NULL) throw runtime_error("Couldn't create screen source"); @@ -185,12 +193,12 @@ obs_source_t *OBSManager::CreateScreenSource() return source; } -obs_source_t *OBSManager::CreateWebcamSource() +OBSSource OBSManager::CreateWebcamSource() { obs_data_t *settings = obs_data_create(); obs_data_set_string(settings, "device_id", mWebcamDeviceID.c_str()); - obs_source_t *source = obs_source_create("v4l2_input", "Webcam Source", settings, NULL); + OBSSource source = obs_source_create("v4l2_input", "Webcam Source", settings, NULL); if (source == NULL) throw runtime_error("Couldn't create webcam source"); @@ -198,10 +206,10 @@ obs_source_t *OBSManager::CreateWebcamSource() return source; } -obs_source_t *OBSManager::CreateAudioSource() +OBSSource OBSManager::CreateAudioSource() { obs_data_t *settings = obs_data_create(); - obs_source_t *source = obs_source_create("audio_line", "Audio Source", settings, NULL); + OBSSource source = obs_source_create("audio_line", "Audio Source", settings, NULL); if (source == NULL) throw runtime_error("Couldn't create screen source"); @@ -216,13 +224,13 @@ void OBSManager::Cleanup() StopRecording(); - for (auto source : sources) + for (auto source : mSources) { obs_source_remove(source); } - if (display != nullptr) - obs_display_destroy(display); + if (mDisplay != nullptr) + obs_display_destroy(mDisplay); obs_shutdown(); isInitialized = false; @@ -235,11 +243,16 @@ void OBSManager::LoadSettings(SettingsManager *settings) mWebcamDeviceID = settings->Get(SETTINGS_KEY_VIDEO_DEVICE_ID); } -void OBSManager::loadPlugin(ustring name) +bool OBSManager::IsRecording() +{ + return isRecording; +} + +void OBSManager::loadPlugin(string name) { obs_module_t *module; - ustring path; + string path; path.append(mPluginDir); path.append(name); @@ -253,7 +266,7 @@ void OBSManager::loadPlugin(ustring name) void OBSManager::loadPlugins() { - for (ustring plugin : mPlugins) + for (string plugin : mPlugins) { loadPlugin(plugin); } diff --git a/obs-manager.hpp b/obs-manager.hpp index 75581a1..72dae6f 100644 --- a/obs-manager.hpp +++ b/obs-manager.hpp @@ -1,15 +1,14 @@ #ifndef SCREEN_RECORDER_OBS_MANAGER_HPP #define SCREEN_RECORDER_OBS_MANAGER_HPP +#include "settings-manager.hpp" + #include #include -#include #include #include -#include -#include "settings-manager.hpp" +#include -using namespace Glib; using namespace std; class OBSManager @@ -17,34 +16,42 @@ class OBSManager public: OBSManager(); virtual ~OBSManager(); - ustring GetVersion(); + string GetVersion(); void Initialize(); void SetPreviewWindow(XID wid, Display *wdisplay); void StartRecording(); void StopRecording(); - obs_source_t *CreateScreenSource(); - obs_source_t *CreateWebcamSource(); - obs_source_t *CreateAudioSource(); + OBSSource CreateScreenSource(); + OBSSource CreateWebcamSource(); + OBSSource CreateAudioSource(); void Cleanup(); void LoadSettings(SettingsManager *settings); + bool IsRecording(); int PreviewWidth = 1280; int PreviewHeight = 720; + // Signals + sigc::signal startRecording; + sigc::signal stopRecording; + private: + void printTypes(); + bool isInitialized = false; bool isRecording = false; - obs_display_t *display; - obs_output_t *output; - list sources; - ustring mPluginDir; - ustring mOutputDir; - ustring mWebcamDeviceID; - void printTypes(); + OBSDisplay mDisplay; + OBSOutput mOutput; + OBSSignal obsStartRecording; + OBSSignal obsStopRecording; + list mSources; + string mPluginDir; + string mOutputDir; + string mWebcamDeviceID; // Plugins - list mPlugins; - void loadPlugin(ustring name); + void loadPlugin(string name); void loadPlugins(); + list mPlugins; }; #endif diff --git a/preview-window.cpp b/preview-window.cpp index 29cbc75..22f8c18 100644 --- a/preview-window.cpp +++ b/preview-window.cpp @@ -11,7 +11,6 @@ PreviewWindow::PreviewWindow(OBSManager *obs) PreviewWindow::~PreviewWindow() { - std::cout << "PreviewWindow::~PreviewWindow" << std::endl; } void PreviewWindow::on_realize() @@ -28,11 +27,9 @@ void PreviewWindow::on_realize() void PreviewWindow::on_show() { Gtk::Widget::on_show(); - mOBS->StartRecording(); } void PreviewWindow::on_hide() { Gtk::Widget::on_hide(); - mOBS->StopRecording(); } diff --git a/settings-manager.cpp b/settings-manager.cpp index 5845780..d9750fa 100644 --- a/settings-manager.cpp +++ b/settings-manager.cpp @@ -102,7 +102,7 @@ void SettingsManager::readAll() while (getline(fin, line)) { - if (line.find("=") != -1) + if (line.find("=") != std::string::npos) { settings.push_back(new SettingsEntry{ .key = line.substr(0, line.find("=")), diff --git a/settings-window.cpp b/settings-window.cpp index a69e06c..aec066b 100644 --- a/settings-window.cpp +++ b/settings-window.cpp @@ -33,8 +33,6 @@ SettingsWindow::SettingsWindow(OBSManager* obs) settings = new SettingsManager(); - populateVideoDevices(); - signal_key_press_event().connect( sigc::mem_fun(*this, &SettingsWindow::onKeyPressed)); @@ -104,6 +102,12 @@ SettingsWindow::~SettingsWindow() { } +void SettingsWindow::on_show() +{ + Gtk::Window::on_show(); + populateVideoDevices(); +} + bool SettingsWindow::onKeyPressed(GdkEventKey *event) { if (event->keyval == GDK_KEY_Escape) @@ -148,7 +152,7 @@ void SettingsWindow::populateVideoDevices() continue; auto name = string(dp->d_name); - if (name.find("video") == -1) + if (name.find("video") == string::npos) continue; auto device = "/dev/" + name; diff --git a/settings-window.hpp b/settings-window.hpp index 241dfd5..9cceb70 100644 --- a/settings-window.hpp +++ b/settings-window.hpp @@ -38,6 +38,7 @@ private: Gtk::Button mButtonClose; Gtk::Button mButtonSave; + void on_show(); void populateVideoDevices(); bool onKeyPressed(GdkEventKey* event); void onClosePressed();