-
Notifications
You must be signed in to change notification settings - Fork 0
/
obsc.cpp
157 lines (129 loc) · 5.75 KB
/
obsc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <functional>
#include <queue>
#include <mutex>
#include "stored.h"
#include "socket_helper.h"
#include "osc_message.h"
OBS_DECLARE_MODULE()
typedef std::function<void(void)> task_t;
std::queue<task_t> tasks;
std::mutex tasks_mutex;
socket_helper* sockets;
stored stored_data;
void update_osc()
{
// Are we recording?
osc_message* currentMessage = new osc_bool_message((char*)"/avatar/parameters/OBSRecordToggle", stored_data.get_recording_active());
sockets->send(currentMessage->message, currentMessage->writerIndex);
// Are we streaming?
currentMessage = new osc_bool_message((char*)"/avatar/parameters/OBSStreamToggle", stored_data.get_streaming_active());
sockets->send(currentMessage->message, currentMessage->writerIndex);
// Is replay buffer currently recording?
currentMessage = new osc_bool_message((char*)"/avatar/parameters/OBSReplayBufferToggle", stored_data.get_replay_buffer_active());
sockets->send(currentMessage->message, currentMessage->writerIndex);
// How many times has the replay buffer been saved?
currentMessage = new osc_int_message((char*)"/avatar/parameters/OBSReplayBufferSaveCount", stored_data.get_replay_buffer_save_count());
sockets->send(currentMessage->message, currentMessage->writerIndex);
// What index is the scene currently at?
float sceneIndex = stored_data.get_scene_index() / 100.0f;
currentMessage = new osc_float_message((char*)"/avatar/parameters/OBSSceneSwitchSelector", sceneIndex);
sockets->send(currentMessage->message, currentMessage->writerIndex);
}
void handle_scene_switch(int newSceneIndex) {
if (stored_data.get_scene_index() == newSceneIndex)
return;
if (stored_data.sceneList.sources.array != nullptr && stored_data.sceneList.sources.num > newSceneIndex) {
obs_source_t *source = stored_data.sceneList.sources.array[newSceneIndex];
if (source != nullptr)
obs_frontend_set_current_scene(source);
}
else { // We're out of range, relay this info back to the client
float sceneIndex = stored_data.get_scene_index() / 100.0f;
osc_message* currentMessage = new osc_float_message((char*)"/avatar/parameters/OBSSceneSwitchSelector", sceneIndex);
sockets->send(currentMessage->message, currentMessage->writerIndex);
}
}
void frontend_cb(enum obs_frontend_event event, void *priv_data)
{
blog(LOG_INFO, "frontend_cb: %d", event);
switch (event)
{
case OBS_FRONTEND_EVENT_RECORDING_STARTED:
case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
case OBS_FRONTEND_EVENT_STREAMING_STARTED:
case OBS_FRONTEND_EVENT_STREAMING_STOPPED:
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED:
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED:
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
update_osc();
break;
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED:
stored_data.increment_save_count();
update_osc();
break;
case OBS_FRONTEND_EVENT_EXIT:
delete sockets;
break;
}
}
void on_update_recv(osc_message message) {
blog(LOG_INFO, "Received update message for address %s", message.address);
if (strcmp(message.address, "/avatar/change") == 0)
update_osc();
if (strcmp(message.address, "/avatar/parameters/OBSRecordToggle") == 0) {
if (message.type == 'T' && !stored_data.get_recording_active()) {
obs_frontend_recording_start();
blog(LOG_INFO, "Recording started");
} else if (message.type == 'F' && stored_data.get_recording_active()) {
obs_frontend_recording_stop();
blog(LOG_INFO, "Recording stopped");
}
}
if (strcmp(message.address, "/avatar/parameters/OBSStreamToggle") == 0) {
if (message.type == 'T' && !stored_data.get_streaming_active())
obs_frontend_streaming_start();
else if (message.type == 'F' && stored_data.get_streaming_active())
obs_frontend_streaming_stop();
}
if (strcmp(message.address, "/avatar/parameters/OBSReplayBufferToggle") == 0) {
if (message.type == 'T' && !stored_data.get_replay_buffer_active())
obs_frontend_replay_buffer_start();
else if (message.type == 'F' && stored_data.get_replay_buffer_active())
obs_frontend_replay_buffer_stop();
}
if (strcmp(message.address, "/avatar/parameters/OBSReplayBufferCapture") == 0 && message.type == 'T')
obs_frontend_replay_buffer_save();
if (strcmp(message.address, "/avatar/parameters/OBSScreenshotCapture") == 0 && message.type == 'T')
obs_frontend_take_screenshot();
if (strcmp(message.address, "/avatar/parameters/OBSSceneSwitchSelector") == 0 && message.type == 'f') {
// We'll have to read the value from the message
osc_float_message* intMessage = (osc_float_message*)&message;
int newSceneIndex = intMessage->parse()*100;
blog(LOG_INFO, "Switching to scene %d", newSceneIndex);
std::unique_lock<std::mutex> lock(tasks_mutex);
task_t task = [newSceneIndex]() {
handle_scene_switch(newSceneIndex);
};
tasks.push(task);
}
}
void update_loop(void* data, float seconds) {
while(!tasks.empty()) {
auto task = tasks.front();
tasks.pop();
task();
}
}
bool obs_module_load()
{
obs_frontend_source_list sceneList = {};
obs_frontend_get_scenes(&sceneList);
// Log how many scenes we have
blog(LOG_INFO, "There are %d scenes", sceneList.sources.num);
sockets = new socket_helper("127.0.0.1", 9001, 9000, on_update_recv);
obs_add_tick_callback(update_loop, &stored_data);
obs_frontend_add_event_callback(frontend_cb, nullptr);
return true;
}