You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
4.9 KiB
216 lines
4.9 KiB
#include <obs/obs.h>
|
|
#include <gdkmm/display.h>
|
|
#include <glibmm/ustring.h>
|
|
#include <gdk/gdkx.h>
|
|
#include <X11/X.h>
|
|
#include <filesystem>
|
|
#include <stdexcept>
|
|
#include "obs-manager.hpp"
|
|
#include "settings-manager.hpp"
|
|
|
|
using namespace Glib;
|
|
|
|
static void obs_render(void *param, uint32_t cx, uint32_t cy)
|
|
{
|
|
obs_render_main_texture();
|
|
}
|
|
|
|
OBSManager::OBSManager()
|
|
{
|
|
mPlugins = {
|
|
"obs-ffmpeg.so",
|
|
"linux-v4l2.so",
|
|
"linux-capture.so",
|
|
};
|
|
}
|
|
|
|
OBSManager::~OBSManager()
|
|
{
|
|
if (display != nullptr)
|
|
obs_display_destroy(display);
|
|
}
|
|
|
|
ustring OBSManager::GetVersion()
|
|
{
|
|
return ustring(obs_get_version_string());
|
|
}
|
|
|
|
void OBSManager::Initialize()
|
|
{
|
|
if (isInitialized)
|
|
return;
|
|
|
|
if (!obs_startup("en-US", NULL, NULL))
|
|
throw std::runtime_error("Failed to initialize OBS");
|
|
|
|
loadPlugins();
|
|
printInputTypes();
|
|
|
|
obs_video_info v = {};
|
|
v.graphics_module = "libobs-opengl.so.0";
|
|
v.fps_num = 30000;
|
|
v.fps_den = 1001;
|
|
v.base_width = PreviewWidth;
|
|
v.base_height = PreviewHeight;
|
|
v.output_width = PreviewWidth;
|
|
v.output_height = PreviewHeight;
|
|
v.output_format = VIDEO_FORMAT_NV12;
|
|
v.adapter = 0;
|
|
v.gpu_conversion = true;
|
|
v.colorspace = VIDEO_CS_601;
|
|
v.range = VIDEO_RANGE_PARTIAL;
|
|
v.scale_type = OBS_SCALE_BICUBIC;
|
|
|
|
obs_audio_info a = {};
|
|
a.samples_per_sec = 44100;
|
|
a.speakers = SPEAKERS_STEREO;
|
|
|
|
obs_reset_video(&v);
|
|
obs_reset_audio(&a);
|
|
|
|
isInitialized = true;
|
|
}
|
|
|
|
void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay)
|
|
{
|
|
auto settings = new SettingsManager();
|
|
|
|
gs_init_data init = {};
|
|
init.cx = PreviewWidth;
|
|
init.cy = PreviewHeight;
|
|
init.format = GS_BGRA;
|
|
init.zsformat = GS_ZS_NONE;
|
|
init.window.id = wid;
|
|
init.window.display = (void*)wdisplay;
|
|
|
|
display = obs_display_create(&init, 0);
|
|
if (display == nullptr)
|
|
throw std::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");
|
|
|
|
if (settings->GetBool("desktopenabled"))
|
|
{
|
|
auto source = CreateScreenSource();
|
|
obs_scene_add(scene, source);
|
|
}
|
|
|
|
if (settings->GetBool("videoenabled"))
|
|
{
|
|
auto source = CreateWebcamSource();
|
|
obs_scene_add(scene, source);
|
|
}
|
|
|
|
if (settings->GetBool("audioenabled"))
|
|
{
|
|
auto source = CreateAudioSource();
|
|
obs_scene_add(scene, source);
|
|
}
|
|
|
|
obs_set_output_source(0, obs_scene_get_source(scene));
|
|
}
|
|
|
|
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");
|
|
|
|
return source;
|
|
}
|
|
|
|
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");
|
|
|
|
return source;
|
|
}
|
|
|
|
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");
|
|
|
|
return source;
|
|
}
|
|
|
|
void OBSManager::Cleanup()
|
|
{
|
|
if (!isInitialized)
|
|
return;
|
|
|
|
if (display != nullptr)
|
|
obs_display_destroy(display);
|
|
|
|
obs_shutdown();
|
|
}
|
|
|
|
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");
|
|
}
|
|
|
|
void OBSManager::loadPlugin(ustring name)
|
|
{
|
|
obs_module_t *module;
|
|
|
|
ustring path;
|
|
path.append(PluginsDir);
|
|
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");
|
|
|
|
obs_init_module(module);
|
|
}
|
|
|
|
|
|
void OBSManager::loadPlugins()
|
|
{
|
|
for (ustring plugin : mPlugins)
|
|
{
|
|
loadPlugin(plugin);
|
|
}
|
|
|
|
obs_post_load_modules();
|
|
}
|
|
|
|
void OBSManager::printInputTypes()
|
|
{
|
|
const char *inputType;
|
|
for (int i = 0; obs_enum_input_types(i, &inputType); ++i)
|
|
{
|
|
std::cout << "input type: " << inputType << std::endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|