mirror of
https://github.com/Palakis/obs-websocket.git
synced 2024-08-30 18:12:16 +00:00
events: decouple events encoding from event emit
This commit is contained in:
@ -48,6 +48,7 @@ set(obs-websocket_SOURCES
|
|||||||
src/Utils.cpp
|
src/Utils.cpp
|
||||||
src/rpc/RpcRequest.cpp
|
src/rpc/RpcRequest.cpp
|
||||||
src/rpc/RpcResponse.cpp
|
src/rpc/RpcResponse.cpp
|
||||||
|
src/rpc/RpcEvent.cpp
|
||||||
src/protocol/OBSRemoteProtocol.cpp
|
src/protocol/OBSRemoteProtocol.cpp
|
||||||
src/forms/settings-dialog.cpp)
|
src/forms/settings-dialog.cpp)
|
||||||
|
|
||||||
@ -61,6 +62,7 @@ set(obs-websocket_HEADERS
|
|||||||
src/Utils.h
|
src/Utils.h
|
||||||
src/rpc/RpcRequest.h
|
src/rpc/RpcRequest.h
|
||||||
src/rpc/RpcResponse.h
|
src/rpc/RpcResponse.h
|
||||||
|
src/rpc/RpcEvent.h
|
||||||
src/protocol/OBSRemoteProtocol.h
|
src/protocol/OBSRemoteProtocol.h
|
||||||
src/forms/settings-dialog.h)
|
src/forms/settings-dialog.h)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along
|
|||||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
#include <QtWidgets/QMainWindow>
|
#include <QtWidgets/QMainWindow>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
@ -822,3 +823,17 @@ void Utils::PauseRecording(bool pause)
|
|||||||
|
|
||||||
pauseRecording(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);
|
||||||
|
}
|
||||||
|
@ -86,4 +86,6 @@ class Utils {
|
|||||||
static bool RecordingPauseSupported();
|
static bool RecordingPauseSupported();
|
||||||
static bool RecordingPaused();
|
static bool RecordingPaused();
|
||||||
static void PauseRecording(bool pause);
|
static void PauseRecording(bool pause);
|
||||||
|
|
||||||
|
static QString nsToTimestamp(uint64_t ns);
|
||||||
};
|
};
|
||||||
|
@ -23,27 +23,15 @@
|
|||||||
|
|
||||||
#include <QtWidgets/QPushButton>
|
#include <QtWidgets/QPushButton>
|
||||||
|
|
||||||
#include "Config.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
#include "WSEvents.h"
|
#include "WSEvents.h"
|
||||||
|
|
||||||
#include "obs-websocket.h"
|
#include "obs-websocket.h"
|
||||||
|
#include "Config.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
#include "rpc/RpcEvent.h"
|
||||||
|
|
||||||
#define STATUS_INTERVAL 2000
|
#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) {
|
const char* sourceTypeToString(obs_source_type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OBS_SOURCE_TYPE_INPUT:
|
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,
|
void WSEvents::broadcastUpdate(const char* updateType,
|
||||||
obs_data_t* additionalFields = nullptr)
|
obs_data_t* additionalFields = nullptr)
|
||||||
{
|
{
|
||||||
OBSDataAutoRelease update = obs_data_create();
|
uint64_t streamTime = getStreamingTime();
|
||||||
obs_data_set_string(update, "update-type", updateType);
|
uint64_t recordingTime = getStreamingTime();
|
||||||
|
RpcEvent event(QString(updateType), streamTime, recordingTime, additionalFields);
|
||||||
|
|
||||||
if (obs_frontend_streaming_active()) {
|
_srv->broadcast(event);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSEvents::connectSourceSignals(obs_source_t* source) {
|
void WSEvents::connectSourceSignals(obs_source_t* source) {
|
||||||
@ -410,11 +381,11 @@ uint64_t WSEvents::getRecordingTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString WSEvents::getStreamingTimecode() {
|
QString WSEvents::getStreamingTimecode() {
|
||||||
return nsToTimestamp(getStreamingTime());
|
return Utils::nsToTimestamp(getStreamingTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WSEvents::getRecordingTimecode() {
|
QString WSEvents::getRecordingTimecode() {
|
||||||
return nsToTimestamp(getRecordingTime());
|
return Utils::nsToTimestamp(getRecordingTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -125,8 +125,15 @@ void WSServer::stop()
|
|||||||
blog(LOG_INFO, "server stopped successfully");
|
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);
|
QMutexLocker locker(&_clMutex);
|
||||||
for (connection_hdl hdl : _connections) {
|
for (connection_hdl hdl : _connections) {
|
||||||
if (GetConfig()->AuthRequired) {
|
if (GetConfig()->AuthRequired) {
|
||||||
|
@ -30,8 +30,8 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
#include <websocketpp/server.hpp>
|
#include <websocketpp/server.hpp>
|
||||||
|
|
||||||
#include "ConnectionProperties.h"
|
#include "ConnectionProperties.h"
|
||||||
|
|
||||||
#include "WSRequestHandler.h"
|
#include "WSRequestHandler.h"
|
||||||
|
#include "rpc/RpcEvent.h"
|
||||||
|
|
||||||
using websocketpp::connection_hdl;
|
using websocketpp::connection_hdl;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ public:
|
|||||||
virtual ~WSServer();
|
virtual ~WSServer();
|
||||||
void start(quint16 port);
|
void start(quint16 port);
|
||||||
void stop();
|
void stop();
|
||||||
void broadcast(std::string message);
|
void broadcast(const RpcEvent& event);
|
||||||
QThreadPool* threadPool() {
|
QThreadPool* threadPool() {
|
||||||
return &_threadPool;
|
return &_threadPool;
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,12 @@ You should have received a copy of the GNU General Public License along
|
|||||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "OBSRemoteProtocol.h"
|
#include "OBSRemoteProtocol.h"
|
||||||
#include "../WSRequestHandler.h"
|
#include "../WSRequestHandler.h"
|
||||||
|
#include "../rpc/RpcEvent.h"
|
||||||
|
#include "../Utils.h"
|
||||||
|
|
||||||
std::string OBSRemoteProtocol::processMessage(WSRequestHandler& requestHandler, std::string message)
|
std::string OBSRemoteProtocol::processMessage(WSRequestHandler& requestHandler, std::string message)
|
||||||
{
|
{
|
||||||
@ -56,7 +60,33 @@ std::string OBSRemoteProtocol::processMessage(WSRequestHandler& requestHandler,
|
|||||||
return std::string();
|
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();
|
OBSDataAutoRelease response = obs_data_create();
|
||||||
if (!messageId.isNull()) {
|
if (!messageId.isNull()) {
|
||||||
obs_data_set_string(response, "message-id", messageId.toUtf8().constData());
|
obs_data_set_string(response, "message-id", messageId.toUtf8().constData());
|
||||||
@ -71,11 +101,13 @@ std::string OBSRemoteProtocol::buildResponse(QString messageId, QString status,
|
|||||||
return responseString;
|
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);
|
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();
|
OBSDataAutoRelease fields = obs_data_create();
|
||||||
if (additionalFields) {
|
if (additionalFields) {
|
||||||
obs_data_apply(fields, additionalFields);
|
obs_data_apply(fields, additionalFields);
|
||||||
|
@ -23,11 +23,13 @@ with this program. If not, see <https://www.gnu.org/licenses/>
|
|||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
class WSRequestHandler;
|
class WSRequestHandler;
|
||||||
|
class RpcEvent;
|
||||||
|
|
||||||
class OBSRemoteProtocol
|
class OBSRemoteProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string processMessage(WSRequestHandler& requestHandler, std::string message);
|
std::string processMessage(WSRequestHandler& requestHandler, std::string message);
|
||||||
|
std::string encodeEvent(const RpcEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string buildResponse(QString messageId, QString status, obs_data_t* fields = nullptr);
|
std::string buildResponse(QString messageId, QString status, obs_data_t* fields = nullptr);
|
||||||
|
47
src/rpc/RpcEvent.cpp
Normal file
47
src/rpc/RpcEvent.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
obs-websocket
|
||||||
|
Copyright (C) 2016-2020 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
45
src/rpc/RpcEvent.h
Normal file
45
src/rpc/RpcEvent.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
obs-websocket
|
||||||
|
Copyright (C) 2016-2020 Stéphane Lepin <stephane.lepin@gmail.com>
|
||||||
|
|
||||||
|
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 <https://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <obs-data.h>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
};
|
Reference in New Issue
Block a user