mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
So tired I can't write a decent commit message
This commit is contained in:
parent
c23eaed283
commit
f500f0f296
@ -18,6 +18,7 @@ set(obs-websocket_SOURCES
|
||||
Utils.cpp)
|
||||
|
||||
set(obs-websocket_HEADERS
|
||||
obs-websocket.h
|
||||
WSServer.h
|
||||
WSRequestHandler.h
|
||||
WSEvents.h
|
||||
|
63
Utils.cpp
63
Utils.cpp
@ -1,30 +1,63 @@
|
||||
#include "Utils.h"
|
||||
|
||||
obs_data_array_t* Utils::GetSceneItems(obs_source_t *source) {
|
||||
obs_data_array *items = obs_data_array_create();
|
||||
obs_scene *scene = obs_scene_from_source(source);
|
||||
bool enum_scene_items(obs_scene_t *scene, obs_sceneitem_t *currentItem, void *param) {
|
||||
obs_data_array_t *data = static_cast<obs_data_array *>(param);
|
||||
obs_data_array_push_back(data, Utils::GetSceneItemData(currentItem));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*obs_scene_item *currentItem = scene->first_item;
|
||||
while (currentItem != NULL) {
|
||||
obs_data_array_push_back(items, GetSceneItemData(currentItem));
|
||||
currentItem = currentItem->next;
|
||||
}*/
|
||||
obs_data_array_t* Utils::GetSceneItems(obs_source_t *source) {
|
||||
obs_data_array_t *items = obs_data_array_create();
|
||||
obs_scene_t *scene = obs_scene_from_source(source);
|
||||
|
||||
obs_scene_enum_items(scene, enum_scene_items, items);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
obs_data_t* Utils::GetSceneItemData(obs_scene_item *item) {
|
||||
obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t *item) {
|
||||
if (!item) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vec2 pos;
|
||||
obs_sceneitem_get_pos(item, &pos);
|
||||
|
||||
vec2 bounds;
|
||||
obs_sceneitem_get_bounds(item, &bounds);
|
||||
|
||||
obs_data_t *data = obs_data_create();
|
||||
/*obs_data_set_string(data, "name", obs_source_get_name(item->source));
|
||||
obs_data_set_double(data, "x", item->pos.x);
|
||||
obs_data_set_double(data, "y", item->pos.y);
|
||||
obs_data_set_double(data, "cx", item->bounds.x);
|
||||
obs_data_set_double(data, "cy", item->bounds.y);
|
||||
obs_data_set_bool(data, "render", item->visible);*/
|
||||
obs_data_set_string(data, "name", obs_source_get_name(obs_sceneitem_get_source(item)));
|
||||
obs_data_set_string(data, "type", obs_source_get_id(obs_sceneitem_get_source(item)));
|
||||
obs_data_set_double(data, "volume", obs_source_get_volume(obs_sceneitem_get_source(item)));
|
||||
obs_data_set_double(data, "x", pos.x);
|
||||
obs_data_set_double(data, "y", pos.y);
|
||||
obs_data_set_double(data, "cx", bounds.x);
|
||||
obs_data_set_double(data, "cy", bounds.y);
|
||||
obs_data_set_bool(data, "render", obs_sceneitem_visible(item));
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
obs_data_array_t* Utils::GetScenes() {
|
||||
obs_frontend_source_list sceneList = {};
|
||||
obs_frontend_get_scenes(&sceneList);
|
||||
|
||||
obs_data_array_t* scenes = obs_data_array_create();
|
||||
for (size_t i = 0; i < (&sceneList)->sources.num; i++) {
|
||||
obs_source_t* scene = (&sceneList)->sources.array[i];
|
||||
obs_data_array_push_back(scenes, GetSceneData(scene));
|
||||
}
|
||||
|
||||
obs_frontend_source_list_free(&sceneList);
|
||||
|
||||
return scenes;
|
||||
}
|
||||
|
||||
obs_data_t* Utils::GetSceneData(obs_source *source) {
|
||||
obs_data_t* sceneData = obs_data_create();
|
||||
obs_data_set_string(sceneData, "name", obs_source_get_name(source));
|
||||
obs_data_set_array(sceneData, "sources", GetSceneItems(source));
|
||||
|
||||
return sceneData;
|
||||
}
|
4
Utils.h
4
Utils.h
@ -2,12 +2,16 @@
|
||||
#define UTILS_H
|
||||
|
||||
#include <obs-module.h>
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
static obs_data_array_t* GetSceneItems(obs_source_t* source);
|
||||
static obs_data_t* GetSceneItemData(obs_scene_item *item);
|
||||
|
||||
static obs_data_array_t* GetScenes();
|
||||
static obs_data_t* GetSceneData(obs_source *source);
|
||||
};
|
||||
|
||||
#endif // UTILS_H
|
47
WSEvents.cpp
47
WSEvents.cpp
@ -5,7 +5,7 @@ WSEvents::WSEvents(WSServer *server) {
|
||||
obs_frontend_add_event_callback(WSEvents::FrontendEventHandler, this);
|
||||
|
||||
QTimer *statusTimer = new QTimer();
|
||||
connect(statusTimer, SIGNAL(timeout()), this, SLOT(StreamStatus));
|
||||
connect(statusTimer, SIGNAL(timeout()), this, SLOT(StreamStatus()));
|
||||
statusTimer->start(1000);
|
||||
}
|
||||
|
||||
@ -17,9 +17,14 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void *private
|
||||
{
|
||||
WSEvents *owner = static_cast<WSEvents *>(private_data);
|
||||
|
||||
// TODO : implement SourceChanged, SourceOrderChanged and RepopulateSources
|
||||
|
||||
if (event == OBS_FRONTEND_EVENT_SCENE_CHANGED) {
|
||||
owner->OnSceneChange();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED) {
|
||||
owner->OnSceneListChange();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTING) {
|
||||
owner->OnStreamStarting();
|
||||
}
|
||||
@ -44,6 +49,9 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void *private
|
||||
else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPED) {
|
||||
owner->OnRecordingStopped();
|
||||
}
|
||||
else if (event == OBS_FRONTEND_EVENT_EXIT) {
|
||||
owner->OnExit();
|
||||
}
|
||||
}
|
||||
|
||||
void WSEvents::broadcastUpdate(const char *updateType, obs_data_t *additionalFields = NULL) {
|
||||
@ -77,6 +85,10 @@ void WSEvents::OnSceneChange() {
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void WSEvents::OnSceneListChange() {
|
||||
broadcastUpdate("ScenesChanged");
|
||||
}
|
||||
|
||||
void WSEvents::OnStreamStarting() {
|
||||
// Implements an existing update type from bilhamil's OBS Remote
|
||||
obs_data_t *data = obs_data_create();
|
||||
@ -130,22 +142,21 @@ void WSEvents::OnRecordingStopped() {
|
||||
broadcastUpdate("RecordingStopped");
|
||||
}
|
||||
|
||||
// TODO : Add a timer to trigger StreamStatus
|
||||
void WSEvents::StreamStatus() {
|
||||
blog(LOG_INFO, "top StreamStatus");
|
||||
void WSEvents::OnExit() {
|
||||
// New update type specific to OBS Studio
|
||||
broadcastUpdate("Exiting");
|
||||
}
|
||||
|
||||
void WSEvents::StreamStatus() {
|
||||
bool streamingActive = obs_frontend_streaming_active();
|
||||
bool recordingActive = obs_frontend_recording_active();
|
||||
|
||||
obs_output_t *streamOutput = obs_frontend_get_streaming_output();
|
||||
|
||||
if (!streamOutput) {
|
||||
blog(LOG_INFO, "not this time. no stream output running.");
|
||||
if (!streamOutput || !streamingActive || !recordingActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t bytesPerSec = 0;
|
||||
|
||||
uint64_t bytesSent = obs_output_get_total_bytes(streamOutput);
|
||||
uint64_t bytesSentTime = os_gettime_ns();
|
||||
|
||||
@ -160,22 +171,22 @@ void WSEvents::StreamStatus() {
|
||||
double timePassed = double(bytesSentTime - _lastBytesSentTime) / 1000000000.0;
|
||||
|
||||
uint64_t bitsPerSec = bitsBetween / timePassed;
|
||||
bytesPerSec = bitsPerSec / 8;
|
||||
uint64_t bytesPerSec = bitsPerSec / 8;
|
||||
|
||||
uint64_t totalStreamTime = (os_gettime_ns() - _streamStartTime); // TODO : convert to seconds
|
||||
|
||||
uint64_t droppedFrames = obs_output_get_frames_dropped(streamOutput);
|
||||
uint64_t totalFrames = obs_output_get_total_frames(streamOutput);
|
||||
_lastBytesSent = bytesSent;
|
||||
_lastBytesSentTime = bytesSentTime;
|
||||
|
||||
uint64_t totalStreamTime = (os_gettime_ns() - _streamStartTime) / 1000000000;
|
||||
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_bool(data, "streaming", streamingActive);
|
||||
obs_data_set_bool(data, "recording", recordingActive); // New in OBS Studio
|
||||
obs_data_set_bool(data, "recording", recordingActive);
|
||||
obs_data_set_bool(data, "preview-only", false); // Retrocompat with OBSRemote
|
||||
obs_data_set_int(data, "bytes-per-sec", bytesPerSec);
|
||||
obs_data_set_double(data, "strain", 0.0); // TODO
|
||||
obs_data_set_int(data, "bytes-per-sec", bytesPerSec); // BUG : Computation seems buggy
|
||||
obs_data_set_double(data, "strain", 0.0); // dafuq is strain
|
||||
obs_data_set_int(data, "total-stream-time", totalStreamTime);
|
||||
obs_data_set_int(data, "num-total-frames", totalFrames);
|
||||
obs_data_set_int(data, "num-dropped-frames", droppedFrames);
|
||||
obs_data_set_int(data, "num-total-frames", obs_output_get_total_frames(streamOutput));
|
||||
obs_data_set_int(data, "num-dropped-frames", obs_output_get_frames_dropped(streamOutput));
|
||||
obs_data_set_double(data, "fps", obs_get_active_fps());
|
||||
|
||||
broadcastUpdate("StreamStatus", data);
|
||||
|
@ -27,6 +27,7 @@ class WSEvents : public QObject
|
||||
void broadcastUpdate(const char *updateType, obs_data_t *additionalFields);
|
||||
|
||||
void OnSceneChange();
|
||||
void OnSceneListChange();
|
||||
|
||||
void OnStreamStarting();
|
||||
void OnStreamStarted();
|
||||
@ -37,6 +38,8 @@ class WSEvents : public QObject
|
||||
void OnRecordingStarted();
|
||||
void OnRecordingStopping();
|
||||
void OnRecordingStopped();
|
||||
|
||||
void OnExit();
|
||||
};
|
||||
|
||||
#endif // WSEVENTS_H
|
@ -1,11 +1,17 @@
|
||||
#include "WSRequestHandler.h"
|
||||
#include "obs-websocket.h"
|
||||
#include "Utils.h"
|
||||
|
||||
WSRequestHandler::WSRequestHandler(QWebSocket *client) {
|
||||
_client = client;
|
||||
|
||||
messageMap["GetVersion"] = WSRequestHandler::HandleGetVersion;
|
||||
messageMap["GetAuthRequired"] = WSRequestHandler::HandleGetAuthRequired;
|
||||
messageMap["Authenticate"] = WSRequestHandler::HandleAuthenticate;
|
||||
|
||||
messageMap["SetCurrentScene"] = WSRequestHandler::HandleSetCurrentScene;
|
||||
messageMap["GetCurrentScene"] = WSRequestHandler::HandleGetCurrentScene;
|
||||
messageMap["GetSceneList"] = WSRequestHandler::ErrNotImplemented;
|
||||
messageMap["GetSceneList"] = WSRequestHandler::HandleGetSceneList;
|
||||
messageMap["SetSourceOrder"] = WSRequestHandler::ErrNotImplemented;
|
||||
messageMap["SetSourceRender"] = WSRequestHandler::ErrNotImplemented;
|
||||
messageMap["SetSceneItemPositionAndSize"] = WSRequestHandler::ErrNotImplemented;
|
||||
@ -69,6 +75,41 @@ void WSRequestHandler::SendErrorResponse(const char *errorMessage) {
|
||||
obs_data_release(response);
|
||||
}
|
||||
|
||||
void WSRequestHandler::HandleGetVersion(WSRequestHandler *owner) {
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_double(data, "version", OBS_WEBSOCKET_VERSION);
|
||||
|
||||
owner->SendOKResponse(data);
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void WSRequestHandler::HandleGetAuthRequired(WSRequestHandler *owner) {
|
||||
bool authRequired = false; // Auth isn't implemented yet
|
||||
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_bool(data, "authRequired", authRequired);
|
||||
if (authRequired) {
|
||||
// Just here for protocol doc
|
||||
obs_data_set_string(data, "challenge", "");
|
||||
obs_data_set_string(data, "salt", "");
|
||||
}
|
||||
|
||||
owner->SendOKResponse(data);
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void WSRequestHandler::HandleAuthenticate(WSRequestHandler *owner) {
|
||||
const char *auth = obs_data_get_string(owner->_requestData, "auth");
|
||||
if (!auth) {
|
||||
owner->SendErrorResponse("auth not specified!");
|
||||
return;
|
||||
}
|
||||
|
||||
owner->SendOKResponse();
|
||||
}
|
||||
|
||||
void WSRequestHandler::HandleSetCurrentScene(WSRequestHandler *owner) {
|
||||
const char *sceneName = obs_data_get_string(owner->_requestData, "scene-name");
|
||||
obs_source_t *source = obs_get_source_by_name(sceneName);
|
||||
@ -78,7 +119,6 @@ void WSRequestHandler::HandleSetCurrentScene(WSRequestHandler *owner) {
|
||||
owner->SendOKResponse();
|
||||
}
|
||||
else {
|
||||
blog(LOG_ERROR, "[obs-websockets] requested scene '%s' doesn't exist !", sceneName);
|
||||
owner->SendErrorResponse("requested scene does not exist");
|
||||
}
|
||||
|
||||
@ -98,6 +138,16 @@ void WSRequestHandler::HandleGetCurrentScene(WSRequestHandler *owner) {
|
||||
obs_source_release(source);
|
||||
}
|
||||
|
||||
void WSRequestHandler::HandleGetSceneList(WSRequestHandler *owner) {
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_string(data, "current-scene", obs_source_get_name(obs_frontend_get_current_scene()));
|
||||
obs_data_set_array(data, "scenes", Utils::GetScenes());
|
||||
|
||||
owner->SendOKResponse(data);
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
void WSRequestHandler::HandleGetStreamingStatus(WSRequestHandler *owner) {
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_bool(data, "streaming", obs_frontend_streaming_active());
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include <map>
|
||||
#include <QtWebSockets/QWebSocket>
|
||||
#include <obs-frontend-api.h>
|
||||
#include "Utils.h"
|
||||
#include "WSServer.h"
|
||||
|
||||
class WSRequestHandler
|
||||
{
|
||||
@ -24,10 +22,14 @@ class WSRequestHandler
|
||||
|
||||
void SendOKResponse(obs_data_t *additionalFields = NULL);
|
||||
void SendErrorResponse(const char *errorMessage);
|
||||
|
||||
static void ErrNotImplemented(WSRequestHandler *owner);
|
||||
|
||||
static void HandleGetVersion(WSRequestHandler *owner);
|
||||
static void HandleGetAuthRequired(WSRequestHandler *owner);
|
||||
static void HandleAuthenticate(WSRequestHandler *owner);
|
||||
static void HandleSetCurrentScene(WSRequestHandler *owner);
|
||||
static void HandleGetCurrentScene(WSRequestHandler *owner);
|
||||
static void HandleGetSceneList(WSRequestHandler *owner);
|
||||
static void HandleGetStreamingStatus(WSRequestHandler *owner);
|
||||
static void HandleStartStopStreaming(WSRequestHandler *owner);
|
||||
static void HandleStartStopRecording(WSRequestHandler *owner);
|
||||
|
Loading…
x
Reference in New Issue
Block a user