Dwayne Harris 3 years ago
parent
commit
4d1f349039
  1. 12
      config.cfg
  2. 8
      main-window.cpp
  3. 3
      main-window.hpp
  4. 1
      main.cpp
  5. 146
      obs-manager.cpp
  6. 18
      obs-manager.hpp
  7. 13
      preview-window.cpp
  8. 4
      preview-window.hpp
  9. BIN
      screenrecorder
  10. 23
      settings-manager.cpp
  11. 11
      settings-manager.hpp
  12. 33
      settings-window.cpp
  13. 2
      settings-window.hpp

12
config.cfg

@ -1,6 +1,6 @@
outputdir=/home/parallels/Projects/Progrium/screen-recorder
pluginsdir=/usr/lib/x86_64-linux-gnu/obs-plugins/
desktopenabled=true
videoenabled=true
videodevice=/dev/video3
audioenabled=false
plugin_dir=/usr/lib/x86_64-linux-gnu/obs-plugins/
output_dir=/home/parallels/Projects/Progrium/screen-recorder
screen_enabled=true
webcam_enabled=true
video_device_id=/dev/video2
audio_enabled=true

8
main-window.cpp

@ -1,8 +1,8 @@
#include <iostream>
#include <string>
#include "main-window.hpp"
#include "obs-manager.hpp"
#include "settings-manager.hpp"
#include <iostream>
#include <string>
#include <gdk/gdkx.h>
using namespace std;
@ -42,8 +42,6 @@ MainWindow::MainWindow(OBSManager *obs)
version.append(obs->GetVersion());
mLabelVersion.set_text(version);
auto settings = new SettingsManager();
mOBS->LoadSettings(settings);
mOBS->Initialize();
}

3
main-window.hpp

@ -1,11 +1,12 @@
#ifndef SCREEN_RECORDER_MAIN_WINDOW_HPP
#define SCREEN_RECORDER_MAIN_WINDOW_HPP
#include <gtkmm.h>
#include "obs-manager.hpp"
#include "settings-window.hpp"
#include "preview-window.hpp"
#include <gtkmm.h>
class MainWindow : public Gtk::Window
{
public:

1
main.cpp

@ -1,5 +1,6 @@
#include "main-window.hpp"
#include "obs-manager.hpp"
#include <gtkmm/application.h>
#include <GL/freeglut.h>

146
obs-manager.cpp

@ -1,13 +1,17 @@
#include "obs-manager.hpp"
#include "settings-manager.hpp"
#include <obs/obs.h>
#include <gdkmm/display.h>
#include <glibmm/ustring.h>
#include <gdk/gdkx.h>
#include <X11/X.h>
#include <ctime>
#include <list>
#include <filesystem>
#include <stdexcept>
#include "obs-manager.hpp"
#include "settings-manager.hpp"
using namespace std;
using namespace Glib;
static void obs_render(void *param, uint32_t cx, uint32_t cy)
@ -19,6 +23,8 @@ OBSManager::OBSManager()
{
mPlugins = {
"obs-ffmpeg.so",
"obs-outputs.so",
"obs-x264.so",
"linux-v4l2.so",
"linux-capture.so",
};
@ -26,8 +32,7 @@ OBSManager::OBSManager()
OBSManager::~OBSManager()
{
if (display != nullptr)
obs_display_destroy(display);
Cleanup();
}
ustring OBSManager::GetVersion()
@ -40,11 +45,15 @@ void OBSManager::Initialize()
if (isInitialized)
return;
sources = list<obs_source_t*>();
auto settings = new SettingsManager();
LoadSettings(settings);
if (!obs_startup("en-US", NULL, NULL))
throw std::runtime_error("Failed to initialize OBS");
throw runtime_error("Failed to initialize OBS");
loadPlugins();
printInputTypes();
printTypes();
obs_video_info v = {};
v.graphics_module = "libobs-opengl.so.0";
@ -85,42 +94,94 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay)
display = obs_display_create(&init, 0);
if (display == nullptr)
throw std::runtime_error("Failed to create display");
throw runtime_error("Failed to create display");
obs_display_add_draw_callback(display, obs_render, nullptr);
obs_scene_t *scene = obs_scene_create("scene1");
if (scene == NULL)
throw std::runtime_error("Couldn't create scene\n");
throw runtime_error("Couldn't create scene\n");
if (settings->GetBool("desktopenabled"))
if (settings->GetBool(SETTINGS_KEY_SCREEN_ENABLED))
{
auto source = CreateScreenSource();
obs_scene_add(scene, source);
sources.push_back(source);
}
if (settings->GetBool("videoenabled"))
if (settings->GetBool(SETTINGS_KEY_WEBCAM_ENABLED))
{
vec2 scale;
vec2_set(&scale, 0.5f, 0.5f);
auto source = CreateWebcamSource();
obs_scene_add(scene, source);
auto item = obs_scene_add(scene, source);
obs_sceneitem_set_scale(item, &scale);
sources.push_back(source);
}
if (settings->GetBool("audioenabled"))
if (settings->GetBool(SETTINGS_KEY_AUDIO_ENABLED))
{
auto source = CreateAudioSource();
obs_scene_add(scene, source);
sources.push_back(source);
}
obs_set_output_source(0, obs_scene_get_source(scene));
}
void OBSManager::StartRecording()
{
if (isRecording)
return;
auto s = new SettingsManager();
obs_encoder_t *venc = obs_video_encoder_create("obs_x264", "x264", nullptr, nullptr);
obs_encoder_t *aenc = obs_audio_encoder_create("ffmpeg_aac", "aac", nullptr, 0, nullptr);
obs_encoder_set_video(venc, obs_get_video());
obs_encoder_set_audio(aenc, obs_get_audio());
string path = s->GetWithDefault(SETTINGS_KEY_OUTPUT_DIR, filesystem::current_path());
if (path.back() != '/')
path += "/";
string fileName = path + "recording_" + to_string(time(0)) + ".mp4";
obs_data_t *settings = obs_data_create();
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());
obs_data_release(settings);
if (!obs_output_start(output))
throw runtime_error("Failed to start recording");
isRecording = true;
}
void OBSManager::StopRecording()
{
if (isRecording && output != nullptr)
obs_output_stop(output);
isRecording = false;
}
obs_source_t *OBSManager::CreateScreenSource()
{
obs_data_t *settings = obs_data_create();
obs_source_t *source = obs_source_create("xshm_input", "Screen Source", settings, NULL);
if (source == NULL)
throw std::runtime_error("Couldn't create screen source");
throw runtime_error("Couldn't create screen source");
obs_data_release(settings);
return source;
}
@ -128,12 +189,12 @@ obs_source_t *OBSManager::CreateWebcamSource()
{
obs_data_t *settings = obs_data_create();
obs_data_set_string(settings, "device_id", mWebcamDeviceID.c_str());
//obs_data_set_string(settings, "format", "NV12");
obs_source_t *source = obs_source_create("v4l2_input", "Webcam Source", settings, NULL);
if (source == NULL)
throw std::runtime_error("Couldn't create webcam source");
throw runtime_error("Couldn't create webcam source");
obs_data_release(settings);
return source;
}
@ -142,8 +203,9 @@ obs_source_t *OBSManager::CreateAudioSource()
obs_data_t *settings = obs_data_create();
obs_source_t *source = obs_source_create("audio_line", "Audio Source", settings, NULL);
if (source == NULL)
throw std::runtime_error("Couldn't create screen source");
throw runtime_error("Couldn't create screen source");
obs_data_release(settings);
return source;
}
@ -152,27 +214,25 @@ void OBSManager::Cleanup()
if (!isInitialized)
return;
StopRecording();
for (auto source : sources)
{
obs_source_remove(source);
}
if (display != nullptr)
obs_display_destroy(display);
obs_shutdown();
isInitialized = false;
}
void OBSManager::LoadSettings(SettingsManager *settings)
{
string pluginsDir = settings->Get("pluginsdir");
if (pluginsDir == "")
pluginsDir = "/usr/lib/x86_64-linux-gnu/obs-plugins/";
PluginsDir = pluginsDir;
string outputDir = settings->Get("outputdir");
if (outputDir == "")
outputDir = std::filesystem::current_path();
OutputDir = outputDir;
mWebcamDeviceID = settings->Get("webcamdeviceid");
mPluginDir = settings->GetWithDefault(SETTINGS_KEY_PLUGIN_DIR, SETTINGS_DEFAULT_PLUGIN_DIR);
mOutputDir = settings->GetWithDefault(SETTINGS_KEY_OUTPUT_DIR, std::filesystem::current_path());
mWebcamDeviceID = settings->Get(SETTINGS_KEY_VIDEO_DEVICE_ID);
}
void OBSManager::loadPlugin(ustring name)
@ -180,12 +240,12 @@ void OBSManager::loadPlugin(ustring name)
obs_module_t *module;
ustring path;
path.append(PluginsDir);
path.append(mPluginDir);
path.append(name);
int res = obs_open_module(&module, path.c_str(), nullptr);
if (res != MODULE_SUCCESS)
throw std::runtime_error("Failed to open plugin");
throw runtime_error("Failed to open plugin");
obs_init_module(module);
}
@ -201,12 +261,22 @@ void OBSManager::loadPlugins()
obs_post_load_modules();
}
void OBSManager::printInputTypes()
void OBSManager::printTypes()
{
const char *inputType;
for (int i = 0; obs_enum_input_types(i, &inputType); ++i)
const char *t;
for (int i = 0; obs_enum_input_types(i, &t); ++i)
{
cout << "input type: " << t << endl;
}
for (int i = 0; obs_enum_output_types(i, &t); ++i)
{
cout << "output type: " << t << endl;
}
for (int i = 0; obs_enum_encoder_types(i, &t); ++i)
{
std::cout << "input type: " << inputType << std::endl;
cout << "encoder type: " << t << endl;
}
}

18
obs-manager.hpp

@ -10,6 +10,7 @@
#include "settings-manager.hpp"
using namespace Glib;
using namespace std;
class OBSManager
{
@ -19,24 +20,29 @@ public:
ustring 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();
void Cleanup();
void LoadSettings(SettingsManager *settings);
std::string PluginsDir;
std::string OutputDir;
int PreviewWidth = 1280;
int PreviewHeight = 720;
private:
bool isInitialized = false;
obs_display_t *display = nullptr;
std::string mWebcamDeviceID;
void printInputTypes();
bool isRecording = false;
obs_display_t *display;
obs_output_t *output;
list<obs_source_t*> sources;
ustring mPluginDir;
ustring mOutputDir;
ustring mWebcamDeviceID;
void printTypes();
// Plugins
std::list<ustring> mPlugins;
list<ustring> mPlugins;
void loadPlugin(ustring name);
void loadPlugins();
};

13
preview-window.cpp

@ -11,6 +11,7 @@ PreviewWindow::PreviewWindow(OBSManager *obs)
PreviewWindow::~PreviewWindow()
{
std::cout << "PreviewWindow::~PreviewWindow" << std::endl;
}
void PreviewWindow::on_realize()
@ -23,3 +24,15 @@ void PreviewWindow::on_realize()
GDK_WINDOW_XDISPLAY(get_window()->gobj())
);
}
void PreviewWindow::on_show()
{
Gtk::Widget::on_show();
mOBS->StartRecording();
}
void PreviewWindow::on_hide()
{
Gtk::Widget::on_hide();
mOBS->StopRecording();
}

4
preview-window.hpp

@ -1,8 +1,8 @@
#ifndef SCREEN_RECORDER_PREVIEW_WINDOW_HPP
#define SCREEN_RECORDER_PREVIEW_WINDOW_HPP
#include <gtkmm.h>
#include "obs-manager.hpp"
#include <gtkmm.h>
class PreviewWindow : public Gtk::Window
{
@ -11,6 +11,8 @@ public:
virtual ~PreviewWindow();
private:
void on_realize();
void on_show();
void on_hide();
OBSManager *mOBS;
};

BIN
screenrecorder

23
settings-manager.cpp

@ -1,5 +1,4 @@
#include "settings-manager.hpp"
#include <iostream>
#include <fstream>
using namespace std;
@ -63,6 +62,15 @@ string SettingsManager::Get(string key)
return "";
}
string SettingsManager::GetWithDefault(string key, string defaultValue)
{
auto value = Get(key);
if (value == "")
return defaultValue;
return value;
}
bool SettingsManager::GetBool(string key)
{
if (Get(key) == "true")
@ -71,6 +79,19 @@ bool SettingsManager::GetBool(string key)
return false;
}
bool SettingsManager::GetBoolWithDefault(string key, bool defaultValue)
{
auto value = Get(key);
if (value == "true")
return true;
if (value == "false")
return false;
return defaultValue;
}
void SettingsManager::readAll()
{
settings.clear();

11
settings-manager.hpp

@ -1,6 +1,15 @@
#ifndef SCREEN_RECORDER_SETTINGS_MANAGER_HPP
#define SCREEN_RECORDER_SETTINGS_MANAGER_HPP
#define SETTINGS_KEY_PLUGIN_DIR "plugin_dir"
#define SETTINGS_KEY_OUTPUT_DIR "output_dir"
#define SETTINGS_KEY_SCREEN_ENABLED "screen_enabled"
#define SETTINGS_KEY_WEBCAM_ENABLED "webcam_enabled"
#define SETTINGS_KEY_VIDEO_DEVICE_ID "video_device_id"
#define SETTINGS_KEY_AUDIO_ENABLED "audio_enabled"
#define SETTINGS_DEFAULT_PLUGIN_DIR "/usr/lib/x86_64-linux-gnu/obs-plugins/"
#include <iostream>
#include <list>
@ -23,7 +32,9 @@ public:
void Save(string key, string value);
void SaveAll();
string Get(string key);
string GetWithDefault(string key, string defaultValue);
bool GetBool(string key);
bool GetBoolWithDefault(string key, bool defaultValue);
private:
list<SettingsEntry*> settings;
void readAll();

33
settings-window.cpp

@ -1,7 +1,9 @@
#include "settings-window.hpp"
#include "settings-manager.hpp"
#include <linux/videodev2.h>
#include <iostream>
#include <filesystem>
#include <stdexcept>
#include <fcntl.h>
#include <libv4l2.h>
@ -30,7 +32,6 @@ SettingsWindow::SettingsWindow(OBSManager* obs)
set_type_hint(Gdk::WindowTypeHint::WINDOW_TYPE_HINT_DIALOG);
settings = new SettingsManager();
obs->LoadSettings(settings);
populateVideoDevices();
@ -45,14 +46,14 @@ SettingsWindow::SettingsWindow(OBSManager* obs)
mBoxSettings.set_border_width(10);
mEntryPluginDir.set_hexpand(true);
mEntryPluginDir.set_text(obs->PluginsDir.c_str());
mEntryPluginDir.set_text(settings->GetWithDefault(SETTINGS_KEY_PLUGIN_DIR, SETTINGS_DEFAULT_PLUGIN_DIR));
mBoxPluginDir.set_border_width(10);
mBoxPluginDir.add(mLabelPluginDir);
mBoxPluginDir.add(mEntryPluginDir);
mEntryOutputDir.set_hexpand(true);
mEntryOutputDir.set_text(obs->OutputDir.c_str());
mEntryOutputDir.set_text(settings->GetWithDefault(SETTINGS_KEY_OUTPUT_DIR, std::filesystem::current_path()));
mBoxOutputDir.set_border_width(10);
mBoxOutputDir.add(mLabelOutputDir);
@ -61,14 +62,14 @@ SettingsWindow::SettingsWindow(OBSManager* obs)
mFrameDesktop.set_label("Desktop");
mFrameDesktop.set_border_width(10);
mCheckButtonDesktop.set_border_width(10);
mCheckButtonDesktop.set_active(settings->GetBool("desktopenabled"));
mCheckButtonDesktop.set_active(settings->GetBoolWithDefault(SETTINGS_KEY_SCREEN_ENABLED, true));
mFrameDesktop.add(mCheckButtonDesktop);
mComboBoxVideoDevice.set_border_width(10);
mFrameWebcam.set_label("Webcam");
mFrameWebcam.set_border_width(10);
mBoxWebcam.set_border_width(10);
mCheckButtonWebcam.set_active(settings->GetBool("videoenabled"));
mCheckButtonWebcam.set_active(settings->GetBoolWithDefault(SETTINGS_KEY_WEBCAM_ENABLED, true));
mBoxWebcam.add(mCheckButtonWebcam);
mBoxWebcam.add(mComboBoxVideoDevice);
mFrameWebcam.add(mBoxWebcam);
@ -76,7 +77,7 @@ SettingsWindow::SettingsWindow(OBSManager* obs)
mFrameAudio.set_label("Microphone");
mFrameAudio.set_border_width(10);
mCheckButtonAudio.set_border_width(10);
mCheckButtonAudio.set_active(settings->GetBool("audioenabled"));
mCheckButtonAudio.set_active(settings->GetBoolWithDefault(SETTINGS_KEY_AUDIO_ENABLED, true));
mFrameAudio.add(mCheckButtonAudio);
mBoxSettings.add(mBoxPluginDir);
@ -121,20 +122,20 @@ void SettingsWindow::onClosePressed()
void SettingsWindow::onSavePressed()
{
settings->Update("pluginsdir", mEntryPluginDir.get_text());
settings->Update("outputdir", mEntryOutputDir.get_text());
settings->UpdateBool("desktopenabled", mCheckButtonDesktop.get_active());
settings->UpdateBool("videoenabled", mCheckButtonWebcam.get_active());
settings->Update("videodevice", mComboBoxVideoDevice.get_active_id());
settings->UpdateBool("audioenabled", mCheckButtonAudio.get_active());
settings->Update(SETTINGS_KEY_PLUGIN_DIR, mEntryPluginDir.get_text());
settings->Update(SETTINGS_KEY_OUTPUT_DIR, mEntryOutputDir.get_text());
settings->UpdateBool(SETTINGS_KEY_SCREEN_ENABLED, mCheckButtonDesktop.get_active());
settings->UpdateBool(SETTINGS_KEY_WEBCAM_ENABLED, mCheckButtonWebcam.get_active());
settings->Update(SETTINGS_KEY_VIDEO_DEVICE_ID, mComboBoxVideoDevice.get_active_id());
settings->UpdateBool(SETTINGS_KEY_AUDIO_ENABLED, mCheckButtonAudio.get_active());
settings->SaveAll();
close();
}
void SettingsWindow::populateVideoDevices()
{
auto settings = new SettingsManager();
struct v4l2_capability cap;
struct dirent *dp;
v4l2_capability cap;
dirent *dp;
auto dirp = opendir("/sys/class/video4linux");
if (!dirp)
@ -169,7 +170,7 @@ void SettingsWindow::populateVideoDevices()
n += " (" + device + ")";
mComboBoxVideoDevice.append(device, n);
if (settings->Get("videodevice") == device)
if (settings->Get(SETTINGS_KEY_VIDEO_DEVICE_ID) == device)
mComboBoxVideoDevice.set_active_id(device);
v4l2_close(fd);

2
settings-window.hpp

@ -1,9 +1,9 @@
#ifndef SCREEN_RECORDER_SETTINGS_WINDOW_HPP
#define SCREEN_RECORDER_SETTINGS_WINDOW_HPP
#include <gtkmm.h>
#include "obs-manager.hpp"
#include "settings-manager.hpp"
#include <gtkmm.h>
class SettingsWindow : public Gtk::Window
{

Loading…
Cancel
Save