Closed ShayBox closed 8 months ago
I figured out how to do it using some projects I found
https://github.com/P1n3appl3/obs-livesplit/blob/main/src/lib.rs https://github.com/P1n3appl3/obs-gamepad/blob/main/src/lib.rs https://github.com/agrif/ds1054z-source/blob/master/src/source.rs https://github.com/chengyuhui/obs-subtitle/blob/master/src/lib.rs
But, It appears NvFBC was deprecated for Windows 10, though it still works it is outdated, and the nvfbc rust bindgen library only targets Linux which is still supported. Feel free to use this on Linux.
use nvfbc::{system::CaptureMethod, BufferFormat, SystemCapturer};
use obs_wrapper::{
graphics::{GraphicsColorFormat, GraphicsTexture},
obs_register_module,
obs_string,
prelude::*,
source::{
GetNameSource,
SourceContext,
SourceType,
Sourceable,
VideoRenderSource,
VideoTickSource,
},
};
struct NvidiaFrameBufferCaptureSource {
source: SourceContext,
texture: GraphicsTexture,
capturer: SystemCapturer,
}
struct NvidiaFrameBufferCaptureModule {
context: ModuleContext,
}
impl Sourceable for NvidiaFrameBufferCaptureSource {
fn get_id() -> ObsString {
obs_string!("nvfbc")
}
fn get_type() -> SourceType {
SourceType::INPUT
}
fn create(_create: &mut CreatableSourceContext<Self>, source: SourceContext) -> Self {
let mut capturer = SystemCapturer::new().expect("Failed to create SystemCapturer");
capturer
.start(BufferFormat::Rgb, 30)
.expect("Failed to start SystemCapturer");
let frame_info = capturer
.next_frame(CaptureMethod::Blocking)
.expect("Failed to get SystemFrameInfo");
let texture = GraphicsTexture::new(
frame_info.width,
frame_info.height,
GraphicsColorFormat::RGBA,
);
Self {
source,
texture,
capturer,
}
}
}
impl GetNameSource for NvidiaFrameBufferCaptureSource {
fn get_name() -> ObsString {
obs_string!("NvFBC")
}
}
impl VideoRenderSource for NvidiaFrameBufferCaptureSource {
fn video_render(&mut self, _context: &mut GlobalContext, _render: &mut VideoRenderContext) {
let frame_info = self
.capturer
.next_frame(CaptureMethod::Blocking)
.expect("Failed to get SystemFrameInfo");
self.texture
.set_image(frame_info.buffer, frame_info.width * 4, false);
self.texture.draw(0, 0, 2560, 1440, false);
}
}
impl Module for NvidiaFrameBufferCaptureModule {
fn new(context: ModuleContext) -> Self {
Self { context }
}
fn get_ctx(&self) -> &ModuleContext {
&self.context
}
fn load(&mut self, load_context: &mut LoadContext) -> bool {
let source = load_context
.create_source_builder::<NvidiaFrameBufferCaptureSource>()
.enable_get_name()
.enable_video_render()
.build();
load_context.register_source(source);
true
}
fn description() -> ObsString {
obs_string!(env!("CARGO_PKG_DESCRIPTION"))
}
fn name() -> ObsString {
obs_string!(env!("CARGO_PKG_NAME"))
}
fn author() -> ObsString {
obs_string!(env!("CARGO_PKG_AUTHORS"))
}
}
obs_register_module!(NvidiaFrameBufferCaptureModule);
Thanks @ShayBox!
I'm trying to write a plugin to render frames with nvfbc, but I can't figure out how to render frames with obs-wrapper.
I found
VideoRenderSource
andVideoTickSource
, but I can't figure out how to actually render frames,GlobalContext
andVideoRenderContext
don't appear to have any fields or methods.