diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1c2145c0..520d4254 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,7 @@ set(obs-websocket_SOURCES
src/Utils.cpp
src/rpc/RpcRequest.cpp
src/rpc/RpcResponse.cpp
+ src/rpc/RpcEvent.cpp
src/protocol/OBSRemoteProtocol.cpp
src/forms/settings-dialog.cpp)
@@ -61,6 +62,7 @@ set(obs-websocket_HEADERS
src/Utils.h
src/rpc/RpcRequest.h
src/rpc/RpcResponse.h
+ src/rpc/RpcEvent.h
src/protocol/OBSRemoteProtocol.h
src/forms/settings-dialog.h)
@@ -180,8 +182,8 @@ if(UNIX AND NOT APPLE)
install(TARGETS obs-websocket
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/obs-plugins")
# Dirty fix for Ubuntu
- install(TARGETS obs-websocket
- LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/${UNAME_MACHINE}-linux-gnu/obs-plugins")
+ install(TARGETS obs-websocket
+ LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/${UNAME_MACHINE}-linux-gnu/obs-plugins")
install(FILES ${locale_files}
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/obs/obs-plugins/obs-websocket/locale")
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 243faf35..02b55e1d 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see
*/
+#include
#include
#include
#include
@@ -822,3 +823,17 @@ void Utils::PauseRecording(bool pause)
pauseRecording(pause);
}
+
+QString Utils::nsToTimestamp(uint64_t ns)
+{
+ uint64_t ms = ns / 1000000ULL;
+ uint64_t secs = ms / 1000ULL;
+ uint64_t minutes = secs / 60ULL;
+
+ uint64_t hoursPart = minutes / 60ULL;
+ uint64_t minutesPart = minutes % 60ULL;
+ uint64_t secsPart = secs % 60ULL;
+ uint64_t msPart = ms % 1000ULL;
+
+ return QString::asprintf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%03" PRIu64, hoursPart, minutesPart, secsPart, msPart);
+}
diff --git a/src/Utils.h b/src/Utils.h
index 89f01acc..bdd5da20 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -86,4 +86,6 @@ class Utils {
static bool RecordingPauseSupported();
static bool RecordingPaused();
static void PauseRecording(bool pause);
+
+ static QString nsToTimestamp(uint64_t ns);
};
diff --git a/src/WSEvents.cpp b/src/WSEvents.cpp
index 4e978cc4..143309e8 100644
--- a/src/WSEvents.cpp
+++ b/src/WSEvents.cpp
@@ -23,27 +23,15 @@
#include
-#include "Config.h"
-#include "Utils.h"
#include "WSEvents.h"
#include "obs-websocket.h"
+#include "Config.h"
+#include "Utils.h"
+#include "rpc/RpcEvent.h"
#define STATUS_INTERVAL 2000
-QString nsToTimestamp(uint64_t ns) {
- uint64_t ms = ns / 1000000ULL;
- uint64_t secs = ms / 1000ULL;
- uint64_t minutes = secs / 60ULL;
-
- uint64_t hoursPart = minutes / 60ULL;
- uint64_t minutesPart = minutes % 60ULL;
- uint64_t secsPart = secs % 60ULL;
- uint64_t msPart = ms % 1000ULL;
-
- return QString::asprintf("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 ".%03" PRIu64, hoursPart, minutesPart, secsPart, msPart);
-}
-
const char* sourceTypeToString(obs_source_type type) {
switch (type) {
case OBS_SOURCE_TYPE_INPUT:
@@ -252,28 +240,11 @@ void WSEvents::FrontendEventHandler(enum obs_frontend_event event, void* private
void WSEvents::broadcastUpdate(const char* updateType,
obs_data_t* additionalFields = nullptr)
{
- OBSDataAutoRelease update = obs_data_create();
- obs_data_set_string(update, "update-type", updateType);
+ uint64_t streamTime = getStreamingTime();
+ uint64_t recordingTime = getStreamingTime();
+ RpcEvent event(QString(updateType), streamTime, recordingTime, additionalFields);
- if (obs_frontend_streaming_active()) {
- QString streamingTimecode = getStreamingTimecode();
- obs_data_set_string(update, "stream-timecode", streamingTimecode.toUtf8().constData());
- }
-
- if (obs_frontend_recording_active()) {
- QString recordingTimecode = getRecordingTimecode();
- obs_data_set_string(update, "rec-timecode", recordingTimecode.toUtf8().constData());
- }
-
- if (additionalFields)
- obs_data_apply(update, additionalFields);
-
- QString json = obs_data_get_json(update);
- _srv->broadcast(json.toStdString());
-
- if (GetConfig()->DebugEnabled) {
- blog(LOG_INFO, "Update << '%s'", json.toUtf8().constData());
- }
+ _srv->broadcast(event);
}
void WSEvents::connectSourceSignals(obs_source_t* source) {
@@ -410,11 +381,11 @@ uint64_t WSEvents::getRecordingTime() {
}
QString WSEvents::getStreamingTimecode() {
- return nsToTimestamp(getStreamingTime());
+ return Utils::nsToTimestamp(getStreamingTime());
}
QString WSEvents::getRecordingTimecode() {
- return nsToTimestamp(getRecordingTime());
+ return Utils::nsToTimestamp(getRecordingTime());
}
/**
diff --git a/src/WSServer.cpp b/src/WSServer.cpp
index 69c25ec7..c9f09362 100644
--- a/src/WSServer.cpp
+++ b/src/WSServer.cpp
@@ -125,8 +125,15 @@ void WSServer::stop()
blog(LOG_INFO, "server stopped successfully");
}
-void WSServer::broadcast(std::string message)
+void WSServer::broadcast(const RpcEvent& event)
{
+ OBSRemoteProtocol protocol;
+ std::string message = protocol.encodeEvent(event);
+
+ if (GetConfig()->DebugEnabled) {
+ blog(LOG_INFO, "Update << '%s'", message.c_str());
+ }
+
QMutexLocker locker(&_clMutex);
for (connection_hdl hdl : _connections) {
if (GetConfig()->AuthRequired) {
diff --git a/src/WSServer.h b/src/WSServer.h
index 76e978e3..723f51af 100644
--- a/src/WSServer.h
+++ b/src/WSServer.h
@@ -30,8 +30,8 @@ with this program. If not, see
#include
#include "ConnectionProperties.h"
-
#include "WSRequestHandler.h"
+#include "rpc/RpcEvent.h"
using websocketpp::connection_hdl;
@@ -46,7 +46,7 @@ public:
virtual ~WSServer();
void start(quint16 port);
void stop();
- void broadcast(std::string message);
+ void broadcast(const RpcEvent& event);
QThreadPool* threadPool() {
return &_threadPool;
}
diff --git a/src/protocol/OBSRemoteProtocol.cpp b/src/protocol/OBSRemoteProtocol.cpp
index f0adb7c1..002f0f54 100644
--- a/src/protocol/OBSRemoteProtocol.cpp
+++ b/src/protocol/OBSRemoteProtocol.cpp
@@ -16,8 +16,12 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see
*/
+#include
+
#include "OBSRemoteProtocol.h"
#include "../WSRequestHandler.h"
+#include "../rpc/RpcEvent.h"
+#include "../Utils.h"
std::string OBSRemoteProtocol::processMessage(WSRequestHandler& requestHandler, std::string message)
{
@@ -56,7 +60,33 @@ std::string OBSRemoteProtocol::processMessage(WSRequestHandler& requestHandler,
return std::string();
}
-std::string OBSRemoteProtocol::buildResponse(QString messageId, QString status, obs_data_t* fields) {
+std::string OBSRemoteProtocol::encodeEvent(const RpcEvent& event)
+{
+ OBSDataAutoRelease eventData = obs_data_create();
+
+ OBSData additionalFields = event.fields();
+ if (additionalFields) {
+ obs_data_apply(eventData, additionalFields);
+ }
+
+ QString updateType = event.updateType();
+ obs_data_set_string(eventData, "update-type", updateType.toUtf8().constData());
+
+ if (obs_frontend_streaming_active()) {
+ QString streamingTimecode = Utils::nsToTimestamp(event.streamTime());
+ obs_data_set_string(eventData, "stream-timecode", streamingTimecode.toUtf8().constData());
+ }
+
+ if (obs_frontend_recording_active()) {
+ QString recordingTimecode = Utils::nsToTimestamp(event.recordingTime());
+ obs_data_set_string(eventData, "rec-timecode", recordingTimecode.toUtf8().constData());
+ }
+
+ return std::string(obs_data_get_json(eventData));
+}
+
+std::string OBSRemoteProtocol::buildResponse(QString messageId, QString status, obs_data_t* fields)
+{
OBSDataAutoRelease response = obs_data_create();
if (!messageId.isNull()) {
obs_data_set_string(response, "message-id", messageId.toUtf8().constData());
@@ -71,11 +101,13 @@ std::string OBSRemoteProtocol::buildResponse(QString messageId, QString status,
return responseString;
}
-std::string OBSRemoteProtocol::successResponse(QString messageId, obs_data_t* fields) {
+std::string OBSRemoteProtocol::successResponse(QString messageId, obs_data_t* fields)
+{
return buildResponse(messageId, "ok", fields);
}
-std::string OBSRemoteProtocol::errorResponse(QString messageId, QString errorMessage, obs_data_t* additionalFields) {
+std::string OBSRemoteProtocol::errorResponse(QString messageId, QString errorMessage, obs_data_t* additionalFields)
+{
OBSDataAutoRelease fields = obs_data_create();
if (additionalFields) {
obs_data_apply(fields, additionalFields);
diff --git a/src/protocol/OBSRemoteProtocol.h b/src/protocol/OBSRemoteProtocol.h
index 6df77fac..03d8aa7d 100644
--- a/src/protocol/OBSRemoteProtocol.h
+++ b/src/protocol/OBSRemoteProtocol.h
@@ -23,11 +23,13 @@ with this program. If not, see
#include
class WSRequestHandler;
+class RpcEvent;
class OBSRemoteProtocol
{
public:
std::string processMessage(WSRequestHandler& requestHandler, std::string message);
+ std::string encodeEvent(const RpcEvent& event);
private:
std::string buildResponse(QString messageId, QString status, obs_data_t* fields = nullptr);
diff --git a/src/rpc/RpcEvent.cpp b/src/rpc/RpcEvent.cpp
new file mode 100644
index 00000000..488aaaf2
--- /dev/null
+++ b/src/rpc/RpcEvent.cpp
@@ -0,0 +1,47 @@
+/*
+obs-websocket
+Copyright (C) 2016-2020 Stéphane Lepin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see
+*/
+
+#include "RpcEvent.h"
+
+RpcEvent::RpcEvent(const QString& updateType, uint64_t streamTime, uint64_t recordingTime, obs_data_t* fields) :
+ _updateType(updateType),
+ _streamTime(streamTime),
+ _recordingTime(recordingTime),
+ _fields(fields)
+{
+}
+
+const QString& RpcEvent::updateType() const
+{
+ return _updateType;
+}
+
+const uint64_t RpcEvent::streamTime() const
+{
+ return _streamTime;
+}
+
+const uint64_t RpcEvent::recordingTime() const
+{
+ return _recordingTime;
+}
+
+const OBSData RpcEvent::fields() const
+{
+ return OBSData(_fields);
+}
\ No newline at end of file
diff --git a/src/rpc/RpcEvent.h b/src/rpc/RpcEvent.h
new file mode 100644
index 00000000..b1deee67
--- /dev/null
+++ b/src/rpc/RpcEvent.h
@@ -0,0 +1,45 @@
+/*
+obs-websocket
+Copyright (C) 2016-2020 Stéphane Lepin
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program. If not, see
+*/
+
+#pragma once
+
+#include
+#include
+
+#include "../obs-websocket.h"
+
+class RpcEvent
+{
+public:
+ explicit RpcEvent(
+ const QString& updateType,
+ uint64_t streamTime, uint64_t recordingTime,
+ obs_data_t* fields = nullptr
+ );
+
+ const QString& updateType() const;
+ const uint64_t streamTime() const;
+ const uint64_t recordingTime() const;
+ const OBSData fields() const;
+
+private:
+ QString _updateType;
+ uint64_t _streamTime;
+ uint64_t _recordingTime;
+ OBSDataAutoRelease _fields;
+};