Skip to content

Instantly share code, notes, and snippets.

@HarukaMa
Created July 20, 2017 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarukaMa/4bca558db27724a486825dd35972573b to your computer and use it in GitHub Desktop.
Save HarukaMa/4bca558db27724a486825dd35972573b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Test.OBS;
namespace Test {
public static class OBSManager {
public static TextBox logbox;
static IntPtr display;
static IntPtr default_scene;
static IntPtr capture_source;
delegate void log_callback(string log);
static void log(string log) {
if (logbox == null)
return;
if (logbox.InvokeRequired) {
log_callback d = OBSManager.log;
logbox.Invoke(d, log);
return;
}
logbox.AppendText($"[{DateTime.Now:G}] {log}\r\n");
}
public static void init(Control preview, Control load_parent = null) {
uint a = libobs.obs_get_version();
log("Initializing obs");
uint major = (a & 0xFF000000) >> 24;
uint minor = (a & 0x00FF0000) >> 16;
uint rev = a & 0x0000FFFF;
// MessageBox.Show($@"v{major}.{minor}.{rev}");
log($@"obs version v{major}.{minor}.{rev}");
bool r = libobs.obs_startup();
log("obs startup finished");
// MessageBox.Show(r.ToString());
libobs.obs_video_info info = new libobs.obs_video_info {
graphics_module = "libobs-opengl",
fps_num = 30,
fps_den = 1,
base_width = 1280,
base_height = 720,
output_width = 1280,
output_height = 720,
output_format = libobs.video_format.VIDEO_FORMAT_I420
};
int res = libobs.obs_reset_video(ref info);
// MessageBox.Show(res.ToString());
log("Loading obs modules");
libobs.obs_find_modules(load_module, IntPtr.Zero);
bool go;
int idx = 0;
log("Enumerating input source types:");
while (true) {
IntPtr[] id = new IntPtr[1];
go = libobs.obs_enum_input_types(idx, id);
if (!go)
break;
IntPtr name = libobs.obs_source_get_display_name(id[0]);
log(_3rdparty.StringFromNativeUtf8(name) + " " + _3rdparty.StringFromNativeUtf8(id[0]));
idx += 1;
}
idx = 0;
log("Enumerating output types:");
while (true) {
IntPtr[] id = new IntPtr[1];
go = libobs.obs_enum_output_types(idx, id);
if (!go)
break;
log(_3rdparty.StringFromNativeUtf8(id[0]));
idx += 1;
}
idx = 0;
log("Enumerating encoder types:");
while (true) {
IntPtr[] id = new IntPtr[1];
go = libobs.obs_enum_encoder_types(idx, id);
if (!go)
break;
log(_3rdparty.StringFromNativeUtf8(id[0]));
idx += 1;
}
idx = 0;
log("Enumerating service types:");
while (true) {
IntPtr[] id = new IntPtr[1];
go = libobs.obs_enum_service_types(idx, id);
if (!go)
break;
log(_3rdparty.StringFromNativeUtf8(id[0]));
idx += 1;
}
idx = 0;
log("Source types:");
while (true) {
IntPtr[] id = new IntPtr[1];
go = libobs.obs_enum_source_types(idx, id);
if (!go)
break;
log(_3rdparty.StringFromNativeUtf8(id[0]));
idx += 1;
}
init_display(preview);
init_scene();
}
static void load_module(IntPtr param, ref libobs.obs_module_info info) {
Debug.Print("Load module: {0}", _3rdparty.StringFromNativeUtf8(info.bin_path));
log($"Loading module {_3rdparty.StringFromNativeUtf8(info.bin_path)?.Split('/').Last()}");
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(libobs.obs_module)));
int r = libobs.obs_open_module(
ptr,
info.bin_path,
info.data_path);
if (r != 0) {
MessageBox.Show($@"Error on loading {_3rdparty.StringFromNativeUtf8(info.bin_path)}");
log($"Error on loading module {_3rdparty.StringFromNativeUtf8(info.bin_path)?.Split('/').Last()}");
}
libobs.obs_module module =
(libobs.obs_module) Marshal.PtrToStructure((IntPtr) Marshal.PtrToStructure(ptr, typeof(IntPtr)),
typeof(libobs.obs_module));
log($"Initing module {_3rdparty.StringFromNativeUtf8(info.bin_path)?.Split('/').Last()}");
bool res = libobs.obs_init_module(ref module);
if (!res) {
MessageBox.Show($@"Error on initing {_3rdparty.StringFromNativeUtf8(info.bin_path)}");
log($"Error on initing module {_3rdparty.StringFromNativeUtf8(info.bin_path)?.Split('/').Last()}");
}
Marshal.FreeHGlobal(ptr);
}
public static void init_scene() {
default_scene = libobs.obs_scene_create("Default");
libobs.obs_scene scene = (libobs.obs_scene) Marshal.PtrToStructure(default_scene, typeof(libobs.obs_scene));
IntPtr default_source = libobs.obs_scene_get_source(default_scene);
libobs.obs_set_output_source(0, default_source);
// libobs.obs_scene_enum_items(ref scene, scene_enum_items, IntPtr.Zero);
capture_source = libobs.obs_source_create("dshow_input", "Capture", libobs.obs_get_source_defaults("dshow_input"), IntPtr.Zero);
IntPtr dataptr = libobs.obs_source_get_settings(capture_source);
libobs.obs_data data = (libobs.obs_data) Marshal.PtrToStructure(dataptr, typeof(libobs.obs_data));
string a = _3rdparty.StringFromNativeUtf8(libobs.obs_data_get_json(dataptr));
IntPtr itemptr = data.first_item;
libobs.obs_data_item item = (libobs.obs_data_item) Marshal.PtrToStructure(itemptr, typeof(libobs.obs_data_item));
log("Data items:");
log(_3rdparty.StringFromNativeUtf8(libobs.obs_data_item_get_name(itemptr)));
while (item.next != IntPtr.Zero) {
itemptr = item.next;
item = (libobs.obs_data_item) Marshal.PtrToStructure(itemptr, typeof(libobs.obs_data_item));
log(_3rdparty.StringFromNativeUtf8(libobs.obs_data_item_get_name(itemptr)));
}
IntPtr sceneitem = libobs.obs_scene_add(default_scene, capture_source);
libobs.vec2 vec = new libobs.vec2 {x = 1280, y = 720};
libobs.obs_sceneitem_set_bounds(sceneitem, ref vec);
libobs.obs_sceneitem_get_bounds(sceneitem, ref vec);
MessageBox.Show(vec.x.ToString() + vec.y.ToString());
IntPtr proptr = libobs.obs_source_properties(capture_source);
libobs.obs_properties pro =
(libobs.obs_properties) Marshal.PtrToStructure(proptr, typeof(libobs.obs_properties));
itemptr = pro.first_property;
libobs.obs_property p = (libobs.obs_property) Marshal.PtrToStructure(itemptr, typeof(libobs.obs_property));
log("Property items:");
log($"{_3rdparty.StringFromNativeUtf8(p.name)}: {_3rdparty.StringFromNativeUtf8(p.desc)} - {_3rdparty.StringFromNativeUtf8(p.long_desc)} - {p.type}");
if (p.type == libobs.obs_property_type.OBS_PROPERTY_LIST) {
int c = libobs.obs_property_list_item_count(itemptr);
for (int i = 0; i < c; i++) {
log($" - {_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_name(itemptr, i))} / {_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_string(itemptr, i))} / {libobs.obs_property_list_item_int(itemptr, i)} / {libobs.obs_property_list_item_float(itemptr, i)}");
}
}
while (p.next != IntPtr.Zero) {
itemptr = p.next;
p = (libobs.obs_property) Marshal.PtrToStructure(itemptr, typeof(libobs.obs_property));
log($"{_3rdparty.StringFromNativeUtf8(p.name)}: {_3rdparty.StringFromNativeUtf8(p.desc)} - {_3rdparty.StringFromNativeUtf8(p.long_desc)} - {p.type}");
if (p.type == libobs.obs_property_type.OBS_PROPERTY_LIST) {
int c = libobs.obs_property_list_item_count(itemptr);
for (int i = 0; i < c; i++) {
log($" - {_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_name(itemptr, i))} / {_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_string(itemptr, i))} / {libobs.obs_property_list_item_int(itemptr, i)} / {libobs.obs_property_list_item_float(itemptr, i)}");
}
}
}
}
delegate void init_display_callback(Control preview);
static void init_display(Control preview) {
if (preview.InvokeRequired) {
init_display_callback d = init_display;
preview.Invoke(d, preview);
return;
}
libobs.gs_init_data gsinit = new libobs.gs_init_data {
cx = (uint) preview.Width,
cy = (uint) preview.Height,
window = {hwnd = preview.Handle},
format = libobs.gs_color_format.GS_RGBA,
zsformat = libobs.gs_zstencil_format.GS_ZS_NONE
};
display = libobs.obs_display_create(ref gsinit);
libobs.obs_display_add_draw_callback(display, draw, IntPtr.Zero);
}
static void draw(IntPtr intPtr, uint cx, uint cy) {
libobs.obs_render_main_view();
}
static bool scene_enum_items(ref libobs.obs_scene scene, ref libobs.obs_scene_item scene_item, IntPtr param) {
return true;
}
public static void get_capture_device_list(ref List<string> name, ref List<string> str) {
IntPtr proptr = libobs.obs_source_properties(capture_source);
libobs.obs_properties pro =
(libobs.obs_properties) Marshal.PtrToStructure(proptr, typeof(libobs.obs_properties));
IntPtr itemptr = pro.first_property;
libobs.obs_property p = (libobs.obs_property) Marshal.PtrToStructure(itemptr, typeof(libobs.obs_property));
if (_3rdparty.StringFromNativeUtf8(p.name) == "video_device_id" && p.type == libobs.obs_property_type.OBS_PROPERTY_LIST) {
int c = libobs.obs_property_list_item_count(itemptr);
for (int i = 0; i < c; i++) {
name.Add(_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_name(itemptr, i)));
str.Add(_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_string(itemptr, i)));
}
return;
}
while (p.next != IntPtr.Zero) {
itemptr = p.next;
p = (libobs.obs_property) Marshal.PtrToStructure(itemptr, typeof(libobs.obs_property));
if (_3rdparty.StringFromNativeUtf8(p.name) == "video_device_id" && p.type == libobs.obs_property_type.OBS_PROPERTY_LIST) {
int c = libobs.obs_property_list_item_count(itemptr);
for (int i = 0; i < c; i++) {
name.Add(_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_name(itemptr, i)));
str.Add(_3rdparty.StringFromNativeUtf8(libobs.obs_property_list_item_string(itemptr, i)));
}
return;
}
}
}
public static void set_capture_device(string str) {
IntPtr data = libobs.obs_data_create();
libobs.obs_data_set_string(data, "video_device_id", str);
libobs.obs_properties_apply_settings(libobs.obs_source_properties(capture_source), data);
libobs.obs_source_update(capture_source, data);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment