Skip to content

Commit d1127ba

Browse files
Meng LiMeng Li
authored andcommitted
add dsk
1 parent bc75dfb commit d1127ba

11 files changed

Lines changed: 179 additions & 17 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ SET(OBS_NODE_SOURCES
3232
src/cpp/scene.cpp
3333
src/cpp/display.h
3434
src/cpp/display.cpp
35+
src/cpp/dsk.h
36+
src/cpp/dsk.cpp
3537
src/cpp/platform/platform.h)
3638

3739
if (WIN32)

src/cpp/dsk.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "dsk.h"
2+
3+
Dsk::Dsk(std::string &id, std::string &position, std::string &url, int left, int top, int width, int height) :
4+
position(position),
5+
url(url),
6+
left(left),
7+
top(top),
8+
width(width),
9+
height(height) {
10+
obs_data_t *obs_data = obs_data_create();
11+
obs_data_set_string(obs_data, "file", url.c_str());
12+
obs_data_set_bool(obs_data, "unload", false);
13+
obs_source = obs_source_create("image_source", id.c_str(), obs_data, nullptr);
14+
obs_data_release(obs_data);
15+
}
16+
17+
Dsk::~Dsk() {
18+
if (obs_source) {
19+
obs_source_release(obs_source);
20+
}
21+
}

src/cpp/dsk.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
#include <string>
3+
#include <obs.h>
4+
5+
class Dsk {
6+
7+
public:
8+
Dsk(std::string &id, std::string &position, std::string &url, int left, int top, int width, int height);
9+
~Dsk();
10+
11+
std::string &getPosition() { return position; }
12+
13+
int getLeft() const { return left; }
14+
15+
int getTop() const { return top; }
16+
17+
int getWidth() const { return width; }
18+
19+
int getHeight() const { return height; }
20+
21+
obs_source_t *getObsSource() { return obs_source; }
22+
23+
private:
24+
obs_source_t *obs_source;
25+
std::string position;
26+
std::string url;
27+
int left;
28+
int top;
29+
int width;
30+
int height;
31+
};

src/cpp/main.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ Napi::Value updateSource(const Napi::CallbackInfo &info) {
6363
return info.Env().Undefined();
6464
}
6565

66+
Napi::Value addDSK(const Napi::CallbackInfo &info) {
67+
std::string id = info[0].As<Napi::String>();
68+
std::string position = info[1].As<Napi::String>();
69+
std::string url = info[2].As<Napi::String>();
70+
int left = info[3].As<Napi::Number>();
71+
int top = info[4].As<Napi::Number>();
72+
int width = info[5].As<Napi::Number>();
73+
int height = info[6].As<Napi::Number>();
74+
TRY_METHOD(studio->addDSK(id, position, url, left, top, width, height))
75+
return info.Env().Undefined();
76+
}
77+
6678
Napi::Value muteSource(const Napi::CallbackInfo &info) {
6779
std::string sceneId = info[0].As<Napi::String>();
6880
std::string sourceId = info[1].As<Napi::String>();
@@ -135,6 +147,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
135147
exports.Set(Napi::String::New(env, "createDisplay"), Napi::Function::New(env, createDisplay));
136148
exports.Set(Napi::String::New(env, "destroyDisplay"), Napi::Function::New(env, destroyDisplay));
137149
exports.Set(Napi::String::New(env, "moveDisplay"), Napi::Function::New(env, moveDisplay));
150+
exports.Set(Napi::String::New(env, "addDSK"), Napi::Function::New(env, addDSK));
138151
return exports;
139152
}
140153

src/cpp/scene.cpp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
#include "scene.h"
2+
#include "dsk.h"
3+
#include <map>
24

35
Scene::Scene(std::string &id, Settings *settings) :
46
id(id),
57
settings(settings),
6-
obs_scene(createObsScene(id)) {
8+
obs_scene(createObsScene(id)),
9+
obs_output_scene(nullptr) {
10+
}
11+
12+
Scene::~Scene() {
13+
if (obs_scene) {
14+
obs_scene_release(obs_scene);
15+
}
16+
if (obs_output_scene) {
17+
obs_scene_release(obs_scene);
18+
}
719
}
820

921
void Scene::addSource(std::string &sourceId, SourceType sourceType, std::string &sourceUrl) {
@@ -47,6 +59,65 @@ obs_scene_t *Scene::createObsScene(std::string &sceneId) {
4759
return scene;
4860
}
4961

62+
obs_scene_t *Scene::getObsOutputScene(std::map<std::string, Dsk*> &dsks) {
63+
if (obs_output_scene) {
64+
obs_scene_release(obs_output_scene);
65+
obs_output_scene = nullptr;
66+
}
67+
68+
// create duplicate scene
69+
obs_output_scene = obs_scene_duplicate(obs_scene, (id + "_output").c_str(), OBS_SCENE_DUP_REFS);
70+
71+
// add dsks
72+
for (auto &dsk : dsks) {
73+
// Add the source to the scene
74+
obs_scene_item *obs_scene_item = obs_scene_add(obs_output_scene, dsk.second->getObsSource());
75+
if (!obs_scene_item) {
76+
throw std::runtime_error("Failed to add scene item.");
77+
}
78+
79+
// set position
80+
struct vec2 pos = {};
81+
pos.x = (float)dsk.second->getLeft();
82+
pos.y = (float)dsk.second->getTop();
83+
obs_sceneitem_set_pos(obs_scene_item, &pos);
84+
85+
// set align
86+
std::string position = dsk.second->getPosition();
87+
uint32_t align = 0;
88+
if (position == "top") {
89+
align = OBS_ALIGN_TOP;
90+
} else if (position == "top-right") {
91+
align = OBS_ALIGN_TOP + OBS_ALIGN_RIGHT;
92+
} else if (position == "right") {
93+
align = OBS_ALIGN_RIGHT;
94+
} else if (position == "bottom-right") {
95+
align = OBS_ALIGN_BOTTOM + OBS_ALIGN_RIGHT;
96+
} else if (position == "bottom") {
97+
align = OBS_ALIGN_BOTTOM;
98+
} else if (position == "bottom-left") {
99+
align = OBS_ALIGN_BOTTOM + OBS_ALIGN_LEFT;
100+
} else if (position == "left") {
101+
align = OBS_ALIGN_LEFT;
102+
} else if (position == "top-left") {
103+
align = OBS_ALIGN_TOP + OBS_ALIGN_LEFT;
104+
}
105+
obs_sceneitem_set_bounds_alignment(obs_scene_item, align);
106+
107+
// set size
108+
struct vec2 bounds = {};
109+
bounds.x = (float)dsk.second->getWidth();
110+
bounds.y = (float)dsk.second->getHeight();
111+
obs_sceneitem_set_bounds_type(obs_scene_item, OBS_BOUNDS_SCALE_INNER);
112+
obs_sceneitem_set_bounds(obs_scene_item, &bounds);
113+
114+
// set top most
115+
obs_sceneitem_set_order(obs_scene_item, OBS_ORDER_MOVE_TOP);
116+
}
117+
118+
return obs_output_scene;
119+
}
120+
50121
Napi::Object Scene::getNapiScene(const Napi::Env &env) {
51122
auto napiScene = Napi::Object::New(env);
52123
auto napiSources = Napi::Array::New(env, sources.size());

src/cpp/scene.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22

33
#include "settings.h"
44
#include "source.h"
5+
#include "dsk.h"
56
#include <string>
67
#include <map>
78
#include <obs.h>
89

910
class Scene {
1011
public:
1112
Scene(std::string &id, Settings *settings);
13+
~Scene();
1214

1315
std::string getId() { return id; }
1416

1517
obs_scene_t *getObsScene() { return obs_scene; }
1618

17-
const std::map<std::string, Source *> &getSources() { return sources; }
18-
1919
void addSource(std::string &sourceId, SourceType sourceType, std::string &sourceUrl);
2020

2121
void updateSource(std::string &sourceId, std::string &sourceUrl);
@@ -24,6 +24,8 @@ class Scene {
2424

2525
void restartSource(std::string &sourceId);
2626

27+
obs_scene_t *getObsOutputScene(std::map<std::string, Dsk*> &dsks);
28+
2729
Napi::Object getNapiScene(const Napi::Env &env);
2830

2931
private:
@@ -32,5 +34,6 @@ class Scene {
3234
std::string id;
3335
Settings *settings;
3436
obs_scene_t *obs_scene;
37+
obs_scene_t *obs_output_scene;
3538
std::map<std::string, Source *> sources;
3639
};

src/cpp/source.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ void Source::start() {
4545
if (settings->videoDecoder) {
4646
obs_data_set_bool(obs_data, "hw_decode", settings->videoDecoder->hardwareEnable);
4747
}
48-
obs_data_set_bool(obs_data, "close_when_inactive", false);
49-
obs_data_set_bool(obs_data, "restart_on_activate", false);
48+
obs_data_set_bool(obs_data, "close_when_inactive", false); // make source always read
49+
obs_data_set_bool(obs_data, "restart_on_activate", false); // make source always read
5050
obs_source = obs_source_create("ffmpeg_source", this->id.c_str(), obs_data, nullptr);
5151
}
5252

src/cpp/studio.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,15 @@ void Studio::restartSource(std::string &sceneId, std::string &sourceId) {
262262
scene->restartSource(sourceId);
263263
}
264264

265+
void Studio::addDSK(std::string &id, std::string &position, std::string &url, int left, int top, int width, int height) {
266+
auto found = dsks.find(id);
267+
if (found != dsks.end()) {
268+
throw std::logic_error("Dsk " + id + " already existed");
269+
}
270+
auto *dsk = new Dsk(id, position, url, left, top, width, height);
271+
dsks[id] = dsk;
272+
}
273+
265274
void Studio::switchToScene(std::string &sceneId, std::string &transitionType, int transitionMs) {
266275
Scene *next = findScene(sceneId);
267276
if (next == nullptr) {
@@ -284,7 +293,7 @@ void Studio::switchToScene(std::string &sceneId, std::string &transitionType, in
284293

285294
obs_source_t *transition = transitions[transitionType];
286295
if (currentScene) {
287-
obs_transition_set(transition, obs_scene_get_source(currentScene->getObsScene()));
296+
obs_transition_set(transition, obs_scene_get_source(currentScene->getObsOutputScene(dsks)));
288297
}
289298

290299
obs_set_output_source(0, transition);
@@ -293,7 +302,7 @@ void Studio::switchToScene(std::string &sceneId, std::string &transitionType, in
293302
transition,
294303
OBS_TRANSITION_MODE_AUTO,
295304
transitionMs,
296-
obs_scene_get_source(next->getObsScene())
305+
obs_scene_get_source(next->getObsOutputScene(dsks))
297306
);
298307

299308
if (!ret) {

src/cpp/studio.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Studio {
1717
void updateSource(std::string &sceneId, std::string &sourceId, std::string &sourceUrl);
1818
void muteSource(std::string &sceneId, std::string &sourceId, bool mute);
1919
void restartSource(std::string &sceneId, std::string &sourceId);
20+
void addDSK(std::string &id, std::string &position, std::string &url, int left, int top, int width, int height);
2021
void switchToScene(std::string &sceneId, std::string &transitionType, int transitionMs);
2122
const std::map<std::string, Scene*>& getScenes();
2223
void createDisplay(std::string &displayName, void *parentHandle, int scaleFactor, std::string &sourceId);
@@ -35,6 +36,7 @@ class Studio {
3536
std::map<std::string, Scene*> scenes;
3637
std::map<std::string, obs_source_t*> transitions;
3738
std::map<std::string, Display*> displays;
39+
std::map<std::string, Dsk*> dsks;
3840
Scene *currentScene;
3941
obs_encoder_t *video_encoder;
4042
obs_encoder_t *audio_encoder;

src/index.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ obs.setObsPath(obsPath);
2222

2323
declare namespace obs {
2424

25-
export type RateControl = 'CBR';
25+
export type RateControl = 'CBR' | 'VBR';
2626

2727
export type SourceType = 'Image' | 'MediaSource';
2828

29+
export type Position = 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left' | 'top-left' | 'center';
30+
2931
export type TransitionType = 'cut_transition' | 'fade_transition' | 'swipe_transition' | 'slide_transition';
3032

3133
export interface Scene {
@@ -87,13 +89,6 @@ declare namespace obs {
8789
output?: OutputSettings;
8890
}
8991

90-
export interface Bounds {
91-
x: number;
92-
y: number;
93-
width: number;
94-
height: number;
95-
}
96-
9792
export interface ObsNode {
9893
setObsPath(obsPath: string): void
9994
startup(settings: Settings): void;
@@ -108,6 +103,7 @@ declare namespace obs {
108103
createDisplay(name: string, parentWindow: Buffer, scaleFactor: number, sourceId: string);
109104
destroyDisplay(name: string);
110105
moveDisplay(name: string, x: number, y: number, width: number, height: number);
106+
addDSK(id: string, position: Position, url: string, left: number, top: number, width: number, height: number): void;
111107
}
112108
}
113109

0 commit comments

Comments
 (0)