Skip to content

Commit

Permalink
Add recording pause functions
Browse files Browse the repository at this point in the history
  • Loading branch information
billyct committed Aug 22, 2022
1 parent 9062c0d commit e8c8339
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 0 deletions.
41 changes: 41 additions & 0 deletions obs-studio-client/source/nodeobs_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,38 @@ Napi::Value service::OBS_service_stopReplayBuffer(const Napi::CallbackInfo& info
return info.Env().Undefined();
}

Napi::Value service::OBS_service_canPauseRecording(const Napi::CallbackInfo& info)
{
auto conn = GetConnection(info);
if (!conn)
return info.Env().Undefined();

std::vector<ipc::value> response = conn->call_synchronous_helper("NodeOBS_Service", "OBS_service_canPauseRecording", {});
return Napi::Boolean::New(info.Env(), (bool)response[1].value_union.i32);
}

Napi::Value service::OBS_service_pauseRecording(const Napi::CallbackInfo& info)
{
bool shouldPause = info[0].ToBoolean().Value();

auto conn = GetConnection(info);
if (!conn)
return info.Env().Undefined();

std::vector<ipc::value> response = conn->call_synchronous_helper("NodeOBS_Service", "OBS_service_pauseRecording", {ipc::value(shouldPause)});
return Napi::Boolean::New(info.Env(), (bool)response[1].value_union.i32);
}

Napi::Value service::OBS_service_isPausedRecording(const Napi::CallbackInfo& info)
{
auto conn = GetConnection(info);
if (!conn)
return info.Env().Undefined();

std::vector<ipc::value> response = conn->call_synchronous_helper("NodeOBS_Service", "OBS_service_isPausedRecording", {});
return Napi::Boolean::New(info.Env(), (bool)response[1].value_union.i32);
}

static v8::Persistent<v8::Object> serviceCallbackObject;

Napi::Value service::OBS_service_connectOutputSignals(const Napi::CallbackInfo& info)
Expand Down Expand Up @@ -464,6 +496,15 @@ void service::Init(Napi::Env env, Napi::Object exports)
exports.Set(
Napi::String::New(env, "OBS_service_stopReplayBuffer"),
Napi::Function::New(env, service::OBS_service_stopReplayBuffer));
exports.Set(
Napi::String::New(env, "OBS_service_canPauseRecording"),
Napi::Function::New(env, service::OBS_service_canPauseRecording));
exports.Set(
Napi::String::New(env, "OBS_service_pauseRecording"),
Napi::Function::New(env, service::OBS_service_pauseRecording));
exports.Set(
Napi::String::New(env, "OBS_service_isPausedRecording"),
Napi::Function::New(env, service::OBS_service_isPausedRecording));
exports.Set(
Napi::String::New(env, "OBS_service_connectOutputSignals"),
Napi::Function::New(env, service::OBS_service_connectOutputSignals));
Expand Down
4 changes: 4 additions & 0 deletions obs-studio-client/source/nodeobs_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ namespace service
Napi::Value OBS_service_stopRecording(const Napi::CallbackInfo& info);
Napi::Value OBS_service_stopReplayBuffer(const Napi::CallbackInfo& info);

Napi::Value OBS_service_canPauseRecording(const Napi::CallbackInfo& info);
Napi::Value OBS_service_pauseRecording(const Napi::CallbackInfo& info);
Napi::Value OBS_service_isPausedRecording(const Napi::CallbackInfo& info);

Napi::Value OBS_service_connectOutputSignals(const Napi::CallbackInfo& info);
Napi::Value OBS_service_removeCallback(const Napi::CallbackInfo& info);
Napi::Value OBS_service_processReplayBufferHotkey(const Napi::CallbackInfo& info);
Expand Down
56 changes: 56 additions & 0 deletions obs-studio-server/source/nodeobs_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ void OBS_service::Register(ipc::server& srv)
"OBS_service_stopRecording", std::vector<ipc::type>{}, OBS_service_stopRecording));
cls->register_function(std::make_shared<ipc::function>(
"OBS_service_stopReplayBuffer", std::vector<ipc::type>{ipc::type::Int32}, OBS_service_stopReplayBuffer));
cls->register_function(std::make_shared<ipc::function>("OBS_service_canPauseRecording", std::vector<ipc::type>{}, OBS_service_canPauseRecording));
cls->register_function(std::make_shared<ipc::function>("OBS_service_pauseRecording", std::vector<ipc::type>{ipc::type::Int32}, OBS_service_pauseRecording));
cls->register_function(std::make_shared<ipc::function>("OBS_service_isPausedRecording", std::vector<ipc::type>{}, OBS_service_isPausedRecording));
cls->register_function(std::make_shared<ipc::function>(
"OBS_service_connectOutputSignals", std::vector<ipc::type>{}, OBS_service_connectOutputSignals));
cls->register_function(std::make_shared<ipc::function>("Query", std::vector<ipc::type>{}, Query));
Expand Down Expand Up @@ -244,6 +247,42 @@ void OBS_service::OBS_service_stopReplayBuffer(
AUTO_DEBUG;
}

void OBS_service::OBS_service_canPauseRecording(
void* data,
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval)
{
bool result = canPauseRecording();
rval.push_back(ipc::value((uint64_t)ErrorCode::Ok));
rval.push_back(ipc::value(result));
AUTO_DEBUG;
}

void OBS_service::OBS_service_pauseRecording(
void* data,
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval)
{
bool result = pauseRecording((bool)args[0].value_union.i32);
rval.push_back(ipc::value((uint64_t)ErrorCode::Ok));
rval.push_back(ipc::value(result));
AUTO_DEBUG;
}

void OBS_service::OBS_service_isPausedRecording(
void* data,
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval)
{
bool result = isPausedRecording();
rval.push_back(ipc::value((uint64_t)ErrorCode::Ok));
rval.push_back(ipc::value(result));
AUTO_DEBUG;
}

bool OBS_service::resetAudioContext(bool reload)
{
struct obs_audio_info ai;
Expand Down Expand Up @@ -1363,6 +1402,21 @@ void OBS_service::stopRecording(void)
isRecording = false;
}

bool OBS_service::canPauseRecording(void)
{
return obs_output_can_pause(recordingOutput);
}

bool OBS_service::pauseRecording(bool shouldPause)
{
return obs_output_pause(recordingOutput, shouldPause);
}

bool OBS_service::isPausedRecording(void)
{
return obs_output_paused(recordingOutput);
}

void OBS_service::updateReplayBufferOutput(bool isSimpleMode, bool useStreamEncoder)
{
const char* path;
Expand Down Expand Up @@ -2317,6 +2371,8 @@ void OBS_service::OBS_service_connectOutputSignals(
recordingSignals.push_back(SignalInfo("recording", "stop"));
recordingSignals.push_back(SignalInfo("recording", "stopping"));
recordingSignals.push_back(SignalInfo("recording", "wrote"));
recordingSignals.push_back(SignalInfo("recording", "pause"));
recordingSignals.push_back(SignalInfo("recording", "unpause"));

replayBufferSignals.push_back(SignalInfo("replay-buffer", "start"));
replayBufferSignals.push_back(SignalInfo("replay-buffer", "stop"));
Expand Down
19 changes: 19 additions & 0 deletions obs-studio-server/source/nodeobs_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,21 @@ class OBS_service
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval);
static void OBS_service_canPauseRecording(
void* data,
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval);
static void OBS_service_pauseRecording(
void* data,
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval);
static void OBS_service_isPausedRecording(
void* data,
const int64_t id,
const std::vector<ipc::value>& args,
std::vector<ipc::value>& rval);
static void OBS_service_connectOutputSignals(
void* data,
const int64_t id,
Expand Down Expand Up @@ -212,6 +227,10 @@ class OBS_service
static void stopReplayBuffer(bool forceStop);
static void stopRecording(void);

static bool canPauseRecording(void);
static bool pauseRecording(bool shouldPause);
static bool isPausedRecording(void);

static void releaseStreamingOutput(void);

static void LoadRecordingPreset_h264(const char* encoder);
Expand Down
39 changes: 39 additions & 0 deletions tests/osn-tests/src/test_nodeobs_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,45 @@ describe(testName, function() {
expect(signalInfo.signal).to.equal(EOBSOutputSignal.Wrote, GetErrorMessage(ETestErrorMsg.RecordingOutput));
});

it('Simple mode - Pause recording and resume', async function() {
// Preparing environment
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
obs.setSetting(EOBSSettingsCategories.Output, 'StreamEncoder', obs.os === 'win32' ? 'x264' : 'obs_x264');
obs.setSetting(EOBSSettingsCategories.Output, 'FilePath', path.join(path.normalize(__dirname), '..', 'osnData'));

let signalInfo: IOBSOutputSignalInfo;

osn.NodeObs.OBS_service_startRecording();

signalInfo = await obs.getNextSignalInfo(EOBSOutputType.Recording, EOBSOutputSignal.Start);

if (signalInfo.signal == EOBSOutputSignal.Stop) {
throw Error(GetErrorMessage(ETestErrorMsg.RecordOutputDidNotStart, signalInfo.code.toString(), signalInfo.error));
}

expect(signalInfo.type).to.equal(EOBSOutputType.Recording, GetErrorMessage(ETestErrorMsg.RecordingOutput));
expect(signalInfo.signal).to.equal(EOBSOutputSignal.Start, GetErrorMessage(ETestErrorMsg.RecordingOutput));

await sleep(500);

expect(osn.NodeObs.OBS_service_canPauseRecording()).to.equal(true)
expect(osn.NodeObs.OBS_service_isPausedRecording()).to.equal(false)

expect(osn.NodeObs.OBS_service_pauseRecording(true)).to.equal(true);
signalInfo = await obs.getNextSignalInfo(EOBSOutputType.Recording, EOBSOutputSignal.Pause);

expect(signalInfo.signal).to.equal(EOBSOutputSignal.Pause, GetErrorMessage(ETestErrorMsg.RecordingOutput));
expect(osn.NodeObs.OBS_service_isPausedRecording()).to.equal(true);

expect(osn.NodeObs.OBS_service_pauseRecording(false)).to.equal(true)
signalInfo = await obs.getNextSignalInfo(EOBSOutputType.Recording, EOBSOutputSignal.Unpause);

expect(signalInfo.signal).to.equal(EOBSOutputSignal.Unpause, GetErrorMessage(ETestErrorMsg.RecordingOutput));
expect(osn.NodeObs.OBS_service_isPausedRecording()).to.equal(false)

osn.NodeObs.OBS_service_stopRecording();
});

it('Simple mode - Start replay buffer, save replay and stop', async function() {
// Preparing environment
obs.setSetting(EOBSSettingsCategories.Output, 'Mode', 'Simple');
Expand Down
2 changes: 2 additions & 0 deletions tests/osn-tests/util/obs_enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export const enum EOBSOutputSignal {
Writing = 'writing',
Wrote = 'wrote',
WriteError = 'writing_error',
Pause = 'pause',
Unpause = 'unpause',
}

export const enum EOBSInputTypes {
Expand Down

0 comments on commit e8c8339

Please sign in to comment.