Skip to content

Commit

Permalink
Merge branch 'master' into feat/transition-data
Browse files Browse the repository at this point in the history
  • Loading branch information
duncte123 committed Aug 8, 2024
2 parents 4fd8e3f + faf0866 commit 2387dc2
Show file tree
Hide file tree
Showing 17 changed files with 230 additions and 33 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16...3.25)

legacy_check()

set(obs-websocket_VERSION 5.4.2)
set(obs-websocket_VERSION 5.5.2)
set(OBS_WEBSOCKET_RPC_VERSION 1)

include(cmake/obs-websocket-api.cmake)
Expand Down Expand Up @@ -138,12 +138,14 @@ target_compile_definitions(
target_compile_options(
obs-websocket
PRIVATE $<$<PLATFORM_ID:Windows>:/wd4267>
$<$<PLATFORM_ID:Windows>:/wd4996>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wall>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=float-conversion>
$<$<COMPILE_LANG_AND_ID:CXX,GNU,AppleClang,Clang>:-Wno-error=shadow>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=format-overflow>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=int-conversion>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=comment>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=deprecated-declarations>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=null-pointer-subtraction>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=deprecated-declarations>
$<$<COMPILE_LANG_AND_ID:CXX,AppleClang,Clang>:-Wno-error=implicit-int-conversion>
Expand Down
2 changes: 1 addition & 1 deletion cmake/legacy.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project(obs-websocket VERSION 5.4.2)
project(obs-websocket VERSION 5.5.2)
set(OBS_WEBSOCKET_RPC_VERSION 1)

option(ENABLE_WEBSOCKET "Enable building OBS with websocket plugin" ON)
Expand Down
4 changes: 2 additions & 2 deletions data/locale/be-BY.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ OBSWebSocket.Settings.ServerPort="Порт сервера"
OBSWebSocket.Settings.ShowConnectInfo="Паказаць звесткі пра злучэнне"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Увага: ідзе трансляцыя"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Выглядае, што ў бягучы момант ідзе вывад (стрым, запіс і г. д.)."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Вы ўпэўненыя, што хочаце паказаць вашы звесткі пра злучэнне?"
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Ці вы ўпэўненыя, што хочаце паказаць вашы звесткі пра злучэнне?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Увага: магчымая небяспека"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket захоўвае пароль сервера ў выглядзе звычайнага тэксту. Настойліва рэкамендуецца выкарыстоўваць пароль, які згенеруе obs-websocket."
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Вы ўпэўненыя, што хочаце карыстацца сваім паролем?"
OBSWebSocket.Settings.Save.UserPasswordWarningInfoText="Ці вы ўпэўненыя, што хочаце карыстацца сваім паролем?"
OBSWebSocket.Settings.Save.PasswordInvalidErrorTitle="Увага: памылковая канфігурацыя"
OBSWebSocket.Settings.Save.PasswordInvalidErrorMessage="Пароль павінен утрымліваць 6 або больш сімвалаў."
OBSWebSocket.SessionTable.Title="Злучаныя сеансы WebSocket"
Expand Down
2 changes: 1 addition & 1 deletion data/locale/ro-RO.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ OBSWebSocket.Settings.GeneratePassword="Generează parola"
OBSWebSocket.Settings.ServerPort="Portul serverului"
OBSWebSocket.Settings.ShowConnectInfo="Afișează informațiile conexiunii"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Avertisment: În prezent în direct"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Se pare că un output (transmisiune, înregistrare etc.) este activ în prezent."
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Se pare că un output (stream, înregistrare etc.) este activ în prezent."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Sigur vrei să afișezi informațiile de conectare?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Avertisment: Potențială problemă de securitate"
OBSWebSocket.Settings.Save.UserPasswordWarningMessage="obs-websocket stochează parola serverului ca text simplu. Este foarte recomandat să folosiți o parolă generată de obs-websocket."
Expand Down
2 changes: 1 addition & 1 deletion data/locale/ru-RU.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ OBSWebSocket.SessionTable.KickButtonColumnTitle="Выгнать?"
OBSWebSocket.SessionTable.KickButtonText="Выгнать"
OBSWebSocket.ConnectInfo.DialogTitle="Сведения о подключении WebSocket"
OBSWebSocket.ConnectInfo.CopyText="Копировать"
OBSWebSocket.ConnectInfo.ServerIp="IP сервера (лучшая догадка)"
OBSWebSocket.ConnectInfo.ServerIp="IP сервера (вероятный)"
OBSWebSocket.ConnectInfo.ServerPort="Порт сервера"
OBSWebSocket.ConnectInfo.ServerPassword="Пароль сервера"
OBSWebSocket.ConnectInfo.ServerPasswordPlaceholderText="[Вход отключён]"
Expand Down
4 changes: 2 additions & 2 deletions data/locale/sv-SE.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
OBSWebSocket.Plugin.Description="Fjärrkontroll av OBS Studio via WebSocket"
OBSWebSocket.Settings.DialogTitle="WebSocket-serverinställningar"
OBSWebSocket.Settings.PluginSettingsTitle="Insticksmodulsinställningar"
OBSWebSocket.Settings.PluginSettingsTitle="Insticksprogramsinställningar"
OBSWebSocket.Settings.ServerEnable="Aktivera WebSocket-server"
OBSWebSocket.Settings.AlertsEnable="Aktivera systemfältsmeddelanden"
OBSWebSocket.Settings.DebugEnable="Aktivera felsökningsloggning"
Expand All @@ -11,7 +11,7 @@ OBSWebSocket.Settings.Password="Serverlösenord"
OBSWebSocket.Settings.GeneratePassword="Generera lösenord"
OBSWebSocket.Settings.ServerPort="Serverport"
OBSWebSocket.Settings.ShowConnectInfo="Visa anslutningsinformation"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Varning: Sänder för närvarande"
OBSWebSocket.Settings.ShowConnectInfoWarningTitle="Varning: Direktsändning pågår"
OBSWebSocket.Settings.ShowConnectInfoWarningMessage="Det verkar som om en utmatning (ström, inspelning, etc.) är för närvarande aktiv."
OBSWebSocket.Settings.ShowConnectInfoWarningInfoText="Är du säker på att du vill visa din anslutningsinformation?"
OBSWebSocket.Settings.Save.UserPasswordWarningTitle="Varning: Potentiellt säkerhetsproblem"
Expand Down
9 changes: 9 additions & 0 deletions data/locale/tt-RU.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
OBSWebSocket.Settings.ServerSettingsTitle="Сервер көйләүләре"
OBSWebSocket.Settings.Password="Сервер серсүзе"
OBSWebSocket.Settings.GeneratePassword="Серсүзне ясау"
OBSWebSocket.Settings.ServerPort="Сервер порты"
OBSWebSocket.SessionTable.KickButtonColumnTitle="Чыгарыргамы?"
OBSWebSocket.SessionTable.KickButtonText="Чыгару"
OBSWebSocket.ConnectInfo.CopyText="Күчермә алу"
OBSWebSocket.ConnectInfo.ServerPort="Сервер порты"
OBSWebSocket.ConnectInfo.ServerPassword="Сервер серсүзе"
48 changes: 48 additions & 0 deletions docs/generated/protocol.json
Original file line number Diff line number Diff line change
Expand Up @@ -3472,6 +3472,37 @@
"requestFields": [],
"responseFields": []
},
{
"description": "Splits the current file being recorded into a new file.",
"requestType": "SplitRecordFile",
"complexity": 2,
"rpcVersion": "1",
"deprecated": false,
"initialVersion": "5.5.0",
"category": "record",
"requestFields": [],
"responseFields": []
},
{
"description": "Adds a new chapter marker to the file currently being recorded.\n\nNote: As of OBS 30.2.0, the only file format supporting this feature is Hybrid MP4.",
"requestType": "CreateRecordChapter",
"complexity": 2,
"rpcVersion": "1",
"deprecated": false,
"initialVersion": "5.5.0",
"category": "record",
"requestFields": [
{
"valueName": "chapterName",
"valueType": "String",
"valueDescription": "Name of the new chapter",
"valueRestrictions": null,
"valueOptional": true,
"valueOptionalBehavior": "Unknown"
}
],
"responseFields": []
},
{
"description": "Gets a list of all scene items in a scene.\n\nScenes only",
"requestType": "GetSceneItemList",
Expand Down Expand Up @@ -6046,6 +6077,23 @@
}
]
},
{
"description": "The record output has started writing to a new file. For example, when a file split happens.",
"eventType": "RecordFileChanged",
"eventSubscription": "Outputs",
"complexity": 2,
"rpcVersion": "1",
"deprecated": false,
"initialVersion": "5.5.0",
"category": "outputs",
"dataFields": [
{
"valueName": "newOutputPath",
"valueType": "String",
"valueDescription": "File name that the output has begun writing to"
}
]
},
{
"description": "The state of the replay buffer output has changed.",
"eventType": "ReplayBufferStateChanged",
Expand Down
47 changes: 47 additions & 0 deletions docs/generated/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,7 @@ The output has been resumed (unpaused).
- [Outputs Events](#outputs-events)
- [StreamStateChanged](#streamstatechanged)
- [RecordStateChanged](#recordstatechanged)
- [RecordFileChanged](#recordfilechanged)
- [ReplayBufferStateChanged](#replaybufferstatechanged)
- [VirtualcamStateChanged](#virtualcamstatechanged)
- [ReplayBufferSaved](#replaybuffersaved)
Expand Down Expand Up @@ -2433,6 +2434,22 @@ The state of the record output has changed.

---

### RecordFileChanged

The record output has started writing to a new file. For example, when a file split happens.

- Complexity Rating: `2/5`
- Latest Supported RPC Version: `1`
- Added in v5.5.0

**Data Fields:**

| Name | Type | Description |
| ---- | :---: | ----------- |
| newOutputPath | String | File name that the output has begun writing to |

---

### ReplayBufferStateChanged

The state of the replay buffer output has changed.
Expand Down Expand Up @@ -2712,6 +2729,8 @@ communication is desired.
- [ToggleRecordPause](#togglerecordpause)
- [PauseRecord](#pauserecord)
- [ResumeRecord](#resumerecord)
- [SplitRecordFile](#splitrecordfile)
- [CreateRecordChapter](#createrecordchapter)
- [Media Inputs Requests](#media-inputs-1-requests)
- [GetMediaInputStatus](#getmediainputstatus)
- [SetMediaInputCursor](#setmediainputcursor)
Expand Down Expand Up @@ -5265,6 +5284,34 @@ Resumes the record output.
- Latest Supported RPC Version: `1`
- Added in v5.0.0

---

### SplitRecordFile

Splits the current file being recorded into a new file.

- Complexity Rating: `2/5`
- Latest Supported RPC Version: `1`
- Added in v5.5.0

---

### CreateRecordChapter

Adds a new chapter marker to the file currently being recorded.

Note: As of OBS 30.2.0, the only file format supporting this feature is Hybrid MP4.

- Complexity Rating: `2/5`
- Latest Supported RPC Version: `1`
- Added in v5.5.0

**Request Fields:**

| Name | Type | Description | Value Restrictions | ?Default Behavior |
| ---- | :---: | ----------- | :----------------: | ----------------- |
| ?chapterName | String | Name of the new chapter | None | Unknown |

## Media Inputs Requests

### GetMediaInputStatus
Expand Down
17 changes: 12 additions & 5 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ void Config::Load(json config)
Save();
}

// If there are migrated settings, write them to disk before processing arguments.
if (!config.empty())
Save();

// Process `--websocket_port` override
QString portArgument = Utils::Platform::GetCommandLineArgument(CMDLINE_WEBSOCKET_PORT);
if (portArgument != "") {
Expand Down Expand Up @@ -141,7 +145,9 @@ void Config::Save()
config[PARAM_PASSWORD] = ServerPassword;
}

if (!Utils::Json::SetJsonFileContent(configFilePath, config))
if (Utils::Json::SetJsonFileContent(configFilePath, config))
blog(LOG_DEBUG, "[Config::Save] Saved config.");
else
blog(LOG_ERROR, "[Config::Save] Failed to write config file!");
}

Expand Down Expand Up @@ -193,7 +199,7 @@ bool MigratePersistentData()
std::error_code ec;

// Ensure module config directory exists
std::string moduleConfigDirectory = Utils::Obs::StringHelper::GetModuleConfigPath("");
auto moduleConfigDirectory = std::filesystem::u8path(Utils::Obs::StringHelper::GetModuleConfigPath(""));
if (!std::filesystem::exists(moduleConfigDirectory, ec))
std::filesystem::create_directories(moduleConfigDirectory, ec);
if (ec) {
Expand All @@ -203,10 +209,11 @@ bool MigratePersistentData()
}

// Move any existing persistent data to module config directory, then delete old file
std::string oldPersistentDataPath =
Utils::Obs::StringHelper::GetCurrentProfilePath() + "/../../../obsWebSocketPersistentData.json";
auto oldPersistentDataPath = std::filesystem::u8path(Utils::Obs::StringHelper::GetCurrentProfilePath() +
"/../../../obsWebSocketPersistentData.json");
if (std::filesystem::exists(oldPersistentDataPath, ec)) {
std::string persistentDataPath = Utils::Obs::StringHelper::GetModuleConfigPath("persistent_data.json");
auto persistentDataPath =
std::filesystem::u8path(Utils::Obs::StringHelper::GetModuleConfigPath("persistent_data.json"));
std::filesystem::copy_file(oldPersistentDataPath, persistentDataPath, ec);
std::filesystem::remove(oldPersistentDataPath, ec);
blog(LOG_INFO, "[MigratePersistentData] Persistent data migrated to new path");
Expand Down
30 changes: 15 additions & 15 deletions src/eventhandler/EventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ EventHandler::EventHandler()

signal_handler_t *coreSignalHandler = obs_get_signal_handler();
if (coreSignalHandler) {
signal_handler_connect(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this);
signal_handler_connect(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this);
coreSignals.emplace_back(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this);
coreSignals.emplace_back(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this);
coreSignals.emplace_back(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this);
coreSignals.emplace_back(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this);
coreSignals.emplace_back(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this);
} else {
blog(LOG_ERROR, "[EventHandler::EventHandler] Unable to get libobs signal handler!");
}
Expand All @@ -45,16 +45,7 @@ EventHandler::~EventHandler()

obs_frontend_remove_event_callback(OnFrontendEvent, this);

signal_handler_t *coreSignalHandler = obs_get_signal_handler();
if (coreSignalHandler) {
signal_handler_disconnect(coreSignalHandler, "source_create", SourceCreatedMultiHandler, this);
signal_handler_disconnect(coreSignalHandler, "source_destroy", SourceDestroyedMultiHandler, this);
signal_handler_disconnect(coreSignalHandler, "source_remove", SourceRemovedMultiHandler, this);
signal_handler_disconnect(coreSignalHandler, "source_rename", SourceRenamedMultiHandler, this);
signal_handler_disconnect(coreSignalHandler, "source_update", SourceUpdatedMultiHandler, this);
} else {
blog(LOG_ERROR, "[EventHandler::~EventHandler] Unable to get libobs signal handler!");
}
coreSignals.clear();

// Revoke callbacks of all inputs and scenes, in case some still have our callbacks attached
auto enumInputs = [](void *param, obs_source_t *source) {
Expand Down Expand Up @@ -378,12 +369,21 @@ void EventHandler::OnFrontendEvent(enum obs_frontend_event event, void *private_
break;
case OBS_FRONTEND_EVENT_RECORDING_STARTED:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STARTED);
{
OBSOutputAutoRelease recordOutput = obs_frontend_get_recording_output();
if (recordOutput) {
signal_handler_t *sh = obs_output_get_signal_handler(recordOutput);
eventHandler->recordFileChangedSignal.Connect(sh, "file_changed", HandleRecordFileChanged,
private_data);
}
}
break;
case OBS_FRONTEND_EVENT_RECORDING_STOPPING:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPING);
break;
case OBS_FRONTEND_EVENT_RECORDING_STOPPED:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_STOPPED);
eventHandler->recordFileChangedSignal.Disconnect();
break;
case OBS_FRONTEND_EVENT_RECORDING_PAUSED:
eventHandler->HandleRecordStateChanged(OBS_WEBSOCKET_OUTPUT_PAUSED);
Expand Down
4 changes: 4 additions & 0 deletions src/eventhandler/EventHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class EventHandler {

std::atomic<bool> _obsReady = false;

std::vector<OBSSignal> coreSignals;
OBSSignal recordFileChangedSignal;

std::unique_ptr<Utils::Obs::VolumeMeter::Handler> _inputVolumeMetersHandler;
std::atomic<uint64_t> _inputVolumeMetersRef = 0;
std::atomic<uint64_t> _inputActiveStateChangedRef = 0;
Expand Down Expand Up @@ -155,6 +158,7 @@ class EventHandler {
// Outputs
void HandleStreamStateChanged(ObsOutputState state);
void HandleRecordStateChanged(ObsOutputState state);
static void HandleRecordFileChanged(void *param, calldata_t *data); // Direct callback
void HandleReplayBufferStateChanged(ObsOutputState state);
void HandleVirtualcamStateChanged(ObsOutputState state);
void HandleReplayBufferSaved();
Expand Down
22 changes: 22 additions & 0 deletions src/eventhandler/EventHandler_Outputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ void EventHandler::HandleRecordStateChanged(ObsOutputState state)
BroadcastEvent(EventSubscription::Outputs, "RecordStateChanged", eventData);
}

/**
* The record output has started writing to a new file. For example, when a file split happens.
*
* @dataField newOutputPath | String | File name that the output has begun writing to
*
* @eventType RecordFileChanged
* @eventSubscription Outputs
* @complexity 2
* @rpcVersion -1
* @initialVersion 5.5.0
* @api events
* @category outputs
*/
void EventHandler::HandleRecordFileChanged(void *param, calldata_t *data)
{
auto eventHandler = static_cast<EventHandler *>(param);

json eventData;
eventData["newOutputPath"] = calldata_string(data, "next_file");
eventHandler->BroadcastEvent(EventSubscription::Outputs, "RecordFileChanged", eventData);
}

/**
* The state of the replay buffer output has changed.
*
Expand Down
2 changes: 2 additions & 0 deletions src/requesthandler/RequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ const std::unordered_map<std::string, RequestMethodHandler> RequestHandler::_han
{"ToggleRecordPause", &RequestHandler::ToggleRecordPause},
{"PauseRecord", &RequestHandler::PauseRecord},
{"ResumeRecord", &RequestHandler::ResumeRecord},
{"SplitRecordFile", &RequestHandler::SplitRecordFile},
{"CreateRecordChapter", &RequestHandler::CreateRecordChapter},

// Media Inputs
{"GetMediaInputStatus", &RequestHandler::GetMediaInputStatus},
Expand Down
2 changes: 2 additions & 0 deletions src/requesthandler/RequestHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ class RequestHandler {
RequestResult ToggleRecordPause(const Request &);
RequestResult PauseRecord(const Request &);
RequestResult ResumeRecord(const Request &);
RequestResult SplitRecordFile(const Request &);
RequestResult CreateRecordChapter(const Request &);

// Media Inputs
RequestResult GetMediaInputStatus(const Request &);
Expand Down
Loading

0 comments on commit 2387dc2

Please sign in to comment.