|
|
@ -8,7 +8,10 @@ |
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
static void obs_render(void *param, uint32_t cx, uint32_t cy) |
|
|
|
//
|
|
|
|
// Static Functions
|
|
|
|
//
|
|
|
|
static void OBSRender(void *param, uint32_t cx, uint32_t cy) |
|
|
|
{ |
|
|
|
obs_render_main_texture(); |
|
|
|
} |
|
|
@ -16,21 +19,26 @@ static void obs_render(void *param, uint32_t cx, uint32_t cy) |
|
|
|
static void OBSStartRecording(void *data, calldata_t *params) |
|
|
|
{ |
|
|
|
OBSManager *o = static_cast<OBSManager*>(data); |
|
|
|
o->startRecording.emit(); |
|
|
|
o->sigStartRecording.emit(); |
|
|
|
} |
|
|
|
|
|
|
|
static void OBSStopRecording(void *data, calldata_t *params) |
|
|
|
{ |
|
|
|
OBSManager *o = static_cast<OBSManager*>(data); |
|
|
|
o->stopRecording.emit(); |
|
|
|
o->sigStopRecording.emit(); |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
// OBSManager
|
|
|
|
//
|
|
|
|
OBSManager::OBSManager() |
|
|
|
{ |
|
|
|
mPlugins = { |
|
|
|
"obs-ffmpeg.so", |
|
|
|
"obs-outputs.so", |
|
|
|
"obs-x264.so", |
|
|
|
"linux-alsa.so", |
|
|
|
"linux-pulseaudio.so", |
|
|
|
"linux-v4l2.so", |
|
|
|
"linux-capture.so", |
|
|
|
}; |
|
|
@ -46,11 +54,25 @@ string OBSManager::GetVersion() |
|
|
|
return string(obs_get_version_string()); |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::Initialize() |
|
|
|
void OBSManager::LoadSettings(SettingsManager *settings) |
|
|
|
{ |
|
|
|
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); |
|
|
|
mAudioDeviceID = settings->Get(SETTINGS_KEY_AUDIO_DEVICE_ID); |
|
|
|
mScreenEnabled = settings->GetBool(SETTINGS_KEY_SCREEN_ENABLED); |
|
|
|
mWebcamEnabled = settings->GetBool(SETTINGS_KEY_WEBCAM_ENABLED); |
|
|
|
mAudioEnabled = settings->GetBool(SETTINGS_KEY_AUDIO_ENABLED); |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::Initialize(Gdk::Rectangle rect) |
|
|
|
{ |
|
|
|
if (isInitialized) |
|
|
|
return; |
|
|
|
|
|
|
|
mScreenWidth = rect.get_width(); |
|
|
|
mScreenHeight = rect.get_height(); |
|
|
|
|
|
|
|
mSources = list<OBSSource>(); |
|
|
|
auto settings = new SettingsManager(); |
|
|
|
LoadSettings(settings); |
|
|
@ -64,10 +86,10 @@ void OBSManager::Initialize() |
|
|
|
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.base_width = mScreenWidth; |
|
|
|
v.base_height = mScreenHeight; |
|
|
|
v.output_width = mScreenWidth; |
|
|
|
v.output_height = mScreenHeight; |
|
|
|
v.output_format = VIDEO_FORMAT_NV12; |
|
|
|
v.adapter = 0; |
|
|
|
v.gpu_conversion = true; |
|
|
@ -83,15 +105,14 @@ void OBSManager::Initialize() |
|
|
|
obs_reset_audio(&a); |
|
|
|
|
|
|
|
isInitialized = true; |
|
|
|
//printTypes();
|
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) |
|
|
|
void OBSManager::StartPreview(XID wid, Display *wdisplay) |
|
|
|
{ |
|
|
|
auto settings = new SettingsManager(); |
|
|
|
|
|
|
|
gs_init_data init = {}; |
|
|
|
init.cx = PreviewWidth; |
|
|
|
init.cy = PreviewHeight; |
|
|
|
init.cx = mScreenWidth; |
|
|
|
init.cy = mScreenHeight; |
|
|
|
init.format = GS_BGRA; |
|
|
|
init.zsformat = GS_ZS_NONE; |
|
|
|
init.window.id = wid; |
|
|
@ -101,20 +122,21 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) |
|
|
|
if (mDisplay == nullptr) |
|
|
|
throw runtime_error("Failed to create display"); |
|
|
|
|
|
|
|
obs_display_add_draw_callback(mDisplay, obs_render, nullptr); |
|
|
|
obs_display_resize(mDisplay, PreviewWidth, PreviewHeight); |
|
|
|
obs_display_add_draw_callback(mDisplay, OBSRender, nullptr); |
|
|
|
|
|
|
|
OBSScene scene = obs_scene_create("scene1"); |
|
|
|
if (scene == NULL) |
|
|
|
throw runtime_error("Couldn't create scene\n"); |
|
|
|
|
|
|
|
if (settings->GetBool(SETTINGS_KEY_SCREEN_ENABLED)) |
|
|
|
if (mScreenEnabled) |
|
|
|
{ |
|
|
|
auto source = CreateScreenSource(); |
|
|
|
obs_scene_add(scene, source); |
|
|
|
mSources.push_back(source); |
|
|
|
} |
|
|
|
|
|
|
|
if (settings->GetBool(SETTINGS_KEY_WEBCAM_ENABLED)) |
|
|
|
if (mWebcamEnabled) |
|
|
|
{ |
|
|
|
vec2 scale; |
|
|
|
vec2_set(&scale, 0.5f, 0.5f); |
|
|
@ -125,7 +147,7 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) |
|
|
|
mSources.push_back(source); |
|
|
|
} |
|
|
|
|
|
|
|
if (settings->GetBool(SETTINGS_KEY_AUDIO_ENABLED)) |
|
|
|
if (mAudioEnabled) |
|
|
|
{ |
|
|
|
auto source = CreateAudioSource(); |
|
|
|
obs_scene_add(scene, source); |
|
|
@ -133,6 +155,20 @@ void OBSManager::SetPreviewWindow(XID wid, Display *wdisplay) |
|
|
|
} |
|
|
|
|
|
|
|
obs_set_output_source(0, obs_scene_get_source(scene)); |
|
|
|
sigStartPreview.emit(); |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::StopPreview() |
|
|
|
{ |
|
|
|
for (auto source : mSources) |
|
|
|
{ |
|
|
|
obs_source_remove(source); |
|
|
|
} |
|
|
|
|
|
|
|
if (mDisplay != nullptr) |
|
|
|
obs_display_destroy(mDisplay); |
|
|
|
|
|
|
|
sigStopPreview.emit(); |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::StartRecording() |
|
|
@ -158,7 +194,7 @@ void OBSManager::StartRecording() |
|
|
|
obs_data_set_string(settings, "directory", path.c_str()); |
|
|
|
obs_data_set_string(settings, "url", fileName.c_str()); |
|
|
|
|
|
|
|
mOutput = obs_output_create("ffmpeg_output", "ffmpeg_output", nullptr, nullptr); |
|
|
|
mOutput = obs_output_create("ffmpeg_output", "output", nullptr, nullptr); |
|
|
|
obs_output_set_video_encoder(mOutput, venc); |
|
|
|
obs_output_set_audio_encoder(mOutput, aenc, 0); |
|
|
|
obs_output_update(mOutput, settings); |
|
|
@ -182,6 +218,28 @@ void OBSManager::StopRecording() |
|
|
|
isRecording = false; |
|
|
|
} |
|
|
|
|
|
|
|
bool OBSManager::IsRecording() |
|
|
|
{ |
|
|
|
return isRecording; |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::Cleanup() |
|
|
|
{ |
|
|
|
if (!isInitialized) |
|
|
|
return; |
|
|
|
|
|
|
|
StopRecording(); |
|
|
|
StopPreview(); |
|
|
|
|
|
|
|
obs_shutdown(); |
|
|
|
isInitialized = false; |
|
|
|
|
|
|
|
sigCleanup.emit(); |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
// Sources
|
|
|
|
//
|
|
|
|
OBSSource OBSManager::CreateScreenSource() |
|
|
|
{ |
|
|
|
obs_data_t *settings = obs_data_create(); |
|
|
@ -209,7 +267,9 @@ OBSSource OBSManager::CreateWebcamSource() |
|
|
|
OBSSource OBSManager::CreateAudioSource() |
|
|
|
{ |
|
|
|
obs_data_t *settings = obs_data_create(); |
|
|
|
OBSSource source = obs_source_create("audio_line", "Audio Source", settings, NULL); |
|
|
|
obs_data_set_string(settings, "device_id", mAudioDeviceID.c_str()); |
|
|
|
|
|
|
|
OBSSource source = obs_source_create("pulse_input_capture", "Audio Source", settings, NULL); |
|
|
|
if (source == NULL) |
|
|
|
throw runtime_error("Couldn't create screen source"); |
|
|
|
|
|
|
@ -217,37 +277,9 @@ OBSSource OBSManager::CreateAudioSource() |
|
|
|
return source; |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::Cleanup() |
|
|
|
{ |
|
|
|
if (!isInitialized) |
|
|
|
return; |
|
|
|
|
|
|
|
StopRecording(); |
|
|
|
|
|
|
|
for (auto source : mSources) |
|
|
|
{ |
|
|
|
obs_source_remove(source); |
|
|
|
} |
|
|
|
|
|
|
|
if (mDisplay != nullptr) |
|
|
|
obs_display_destroy(mDisplay); |
|
|
|
|
|
|
|
obs_shutdown(); |
|
|
|
isInitialized = false; |
|
|
|
} |
|
|
|
|
|
|
|
void OBSManager::LoadSettings(SettingsManager *settings) |
|
|
|
{ |
|
|
|
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); |
|
|
|
} |
|
|
|
|
|
|
|
bool OBSManager::IsRecording() |
|
|
|
{ |
|
|
|
return isRecording; |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
// Private (Helpers)
|
|
|
|
//
|
|
|
|
void OBSManager::loadPlugin(string name) |
|
|
|
{ |
|
|
|
obs_module_t *module; |
|
|
|