diff --git a/PROTOCOL.md b/PROTOCOL.md index 3257b5af..41dea2fd 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -95,6 +95,8 @@ The protocol in general is based on the OBS Remote protocol created by Bill Hami - ["SetMute"](#setmute) - ["GetMute"](#getmute) - ["ToggleMute"](#togglemute) + - ["SetSyncOffset"](#setsyncoffset) + - ["GetSyncOffset"](#getsyncoffset) - **Scene Items** - ["SetSceneItemRender"](#setsourcerender) (a.k.a `SetSourceRender`) - ["SetSceneItemPosition"](#setsceneitemposition) @@ -691,6 +693,29 @@ __Response__ : OK if specified source exists, error otherwise. --- +#### "SetSyncOffset" +Set the sync offset of a specific source. + +__Request fields__ : +- **"source"** (string) : the name of the source +- **"offset"** (integer) : the desired sync offset in nanoseconds + +__Response__ : OK if specified source exists, error otherwise. + +--- + +#### "GetSyncOffset" +Get the sync offset of a specific source. + +__Request fields__ : +- **"source"** (string) : the name of the source + +__Response__ : OK if source exists, with these additional fields : +- **"name"** (string) : source name +- **"offset"** (integer) : source sync offset, in nanoseconds + +--- + #### "GetSpecialSources" Get configured special sources like Desktop Audio and Mic/Aux sources. diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index ef4df5e8..48df3a45 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -77,6 +77,8 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) : messageMap["ToggleMute"] = WSRequestHandler::HandleToggleMute; messageMap["SetMute"] = WSRequestHandler::HandleSetMute; messageMap["GetMute"] = WSRequestHandler::HandleGetMute; + messageMap["SetSyncOffset"] = WSRequestHandler::HandleSetSyncOffset; + messageMap["GetSyncOffset"] = WSRequestHandler::HandleGetSyncOffset; messageMap["GetSpecialSources"] = WSRequestHandler::HandleGetSpecialSources; messageMap["SetCurrentSceneCollection"] = WSRequestHandler::HandleSetCurrentSceneCollection; @@ -710,6 +712,58 @@ void WSRequestHandler::HandleGetMute(WSRequestHandler* req) { obs_data_release(response); } +void WSRequestHandler::HandleSetSyncOffset(WSRequestHandler* req) { + if (!req->hasField("source") || + !req->hasField("offset")) { + req->SendErrorResponse("missing request parameters"); + return; + } + + const char* source_name = obs_data_get_string(req->data, "source"); + int64_t source_sync_offset = (int64_t)obs_data_get_int(req->data, "offset"); + + if (!source_name || strlen(source_name) < 1 || + source_sync_offset < 0) { + req->SendErrorResponse("invalid request parameters"); + return; + } + + obs_source_t* source = obs_get_source_by_name(source_name); + if (!source) { + req->SendErrorResponse("specified source doesn't exist"); + return; + } + + obs_source_set_sync_offset(source, source_sync_offset); + req->SendOKResponse(); + + obs_source_release(source); +} + +void WSRequestHandler::HandleGetSyncOffset(WSRequestHandler* req) { + if (!req->hasField("source")) { + req->SendErrorResponse("missing request parameters"); + return; + } + + const char* source_name = obs_data_get_string(req->data, "source"); + if (str_valid(source_name)) { + obs_source_t* source = obs_get_source_by_name(source_name); + + obs_data_t* response = obs_data_create(); + obs_data_set_string(response, "name", source_name); + obs_data_set_int(response, "offset", obs_source_get_sync_offset(source)); + + req->SendOKResponse(response); + + obs_data_release(response); + obs_source_release(source); + } + else { + req->SendErrorResponse("invalid request parameters"); + } +} + void WSRequestHandler::HandleSetSceneItemPosition(WSRequestHandler* req) { if (!req->hasField("item") || !req->hasField("x") || !req->hasField("y")) { diff --git a/WSRequestHandler.h b/WSRequestHandler.h index d51bbb74..7e86f788 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -83,6 +83,8 @@ class WSRequestHandler : public QObject { static void HandleToggleMute(WSRequestHandler* req); static void HandleSetMute(WSRequestHandler* req); static void HandleGetMute(WSRequestHandler* req); + static void HandleSetSyncOffset(WSRequestHandler* req); + static void HandleGetSyncOffset(WSRequestHandler* req); static void HandleGetSpecialSources(WSRequestHandler* req); static void HandleSetCurrentSceneCollection(WSRequestHandler* req);