parent
e8784e00c9
commit
b3817488b4
|
@ -123,6 +123,10 @@ bool OBSGetRecording() {return API->GetRecording();}
|
|||
|
||||
bool OBSGetKeepRecording() {return API->GetKeepRecording();}
|
||||
|
||||
void OBSStartStopRecordingReplayBuffer() {API->StartStopRecordingReplayBuffer();}
|
||||
bool OBSGetRecordingReplayBuffer() {return API->GetRecordingReplayBuffer();}
|
||||
void OBSSaveReplayBuffer() {API->SaveReplayBuffer();}
|
||||
|
||||
void OBSSetSourceOrder(StringList &sourceNames) {API->SetSourceOrder(sourceNames);}
|
||||
void OBSSetSourceRender(CTSTR lpSource, bool render) {API->SetSourceRender(lpSource, render);}
|
||||
|
||||
|
@ -151,6 +155,6 @@ void OBSGetCurMicVolumeStats(float *rms, float *max, float *peak) {API->Ge
|
|||
void OBSAddSettingsPane(SettingsPane *pane) {API->AddSettingsPane(pane);}
|
||||
void OBSRemoveSettingsPane(SettingsPane *pane) {API->RemoveSettingsPane(pane);}
|
||||
|
||||
UINT OBSGetAPIVersion() {return 0x0102;}
|
||||
UINT OBSGetAPIVersion() {return 0x0103;}
|
||||
|
||||
UINT OBSGetSampleRateHz() {return API->GetSampleRateHz();}
|
||||
|
|
|
@ -189,6 +189,10 @@ public:
|
|||
virtual UINT GetBytesPerSec() const=0;
|
||||
|
||||
virtual void SetCanOptimizeSettings(bool canOptimize) = 0;
|
||||
|
||||
virtual void StartStopRecordingReplayBuffer() = 0;
|
||||
virtual bool GetRecordingReplayBuffer() const=0;
|
||||
virtual void SaveReplayBuffer() = 0;
|
||||
};
|
||||
|
||||
BASE_EXPORT extern APIInterface *API;
|
||||
|
@ -266,6 +270,10 @@ BASE_EXPORT bool OBSGetRecording();
|
|||
|
||||
BASE_EXPORT bool OBSGetKeepRecording();
|
||||
|
||||
BASE_EXPORT void OBSStartStopRecordingReplayBuffer();
|
||||
BASE_EXPORT bool OBSGetRecordingReplayBuffer();
|
||||
BASE_EXPORT void OBSSaveReplayBuffer();
|
||||
|
||||
BASE_EXPORT void OBSSetSourceOrder(StringList &sourceNames);
|
||||
BASE_EXPORT void OBSSetSourceRender(CTSTR lpSource, bool render);
|
||||
|
||||
|
|
|
@ -440,6 +440,16 @@ public:
|
|||
PostMessage(hwndMain, WM_COMMAND, MAKEWPARAM(ID_TOGGLERECORDING, 0), 0);
|
||||
}
|
||||
|
||||
virtual void StartStopRecordingReplayBuffer() override
|
||||
{
|
||||
PostMessage(hwndMain, WM_COMMAND, MAKEWPARAM(ID_TOGGLERECORDINGREPLAYBUFFER, 0), 0);
|
||||
}
|
||||
|
||||
virtual void SaveReplayBuffer() override
|
||||
{
|
||||
::SaveReplayBuffer(App->replayBuffer, (DWORD)(App->GetVideoTime() - App->firstFrameTimestamp));
|
||||
}
|
||||
|
||||
virtual bool GetStreaming()
|
||||
{
|
||||
return App->bRunning;
|
||||
|
@ -455,6 +465,11 @@ public:
|
|||
return App->bRecording;
|
||||
}
|
||||
|
||||
virtual bool GetRecordingReplayBuffer() const override
|
||||
{
|
||||
return App->bRecordingReplayBuffer;
|
||||
}
|
||||
|
||||
virtual bool GetKeepRecording() const override
|
||||
{
|
||||
return App->bKeepRecording;
|
||||
|
|
|
@ -735,22 +735,25 @@ OBS::OBS()
|
|||
pluginInfo->strFile = ofd.fileName;
|
||||
|
||||
/* get event callbacks for the plugin */
|
||||
pluginInfo->startStreamCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartStream");
|
||||
pluginInfo->stopStreamCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopStream");
|
||||
pluginInfo->startStreamingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartStreaming");
|
||||
pluginInfo->stopStreamingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopStreaming");
|
||||
pluginInfo->startRecordingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartRecording");
|
||||
pluginInfo->stopRecordingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopRecording");
|
||||
pluginInfo->statusCallback = (OBS_STATUS_CALLBACK)GetProcAddress(hPlugin, "OnOBSStatus");
|
||||
pluginInfo->streamStatusCallback = (OBS_STREAM_STATUS_CALLBACK)GetProcAddress(hPlugin, "OnStreamStatus");
|
||||
pluginInfo->sceneSwitchCallback = (OBS_SCENE_SWITCH_CALLBACK)GetProcAddress(hPlugin, "OnSceneSwitch");
|
||||
pluginInfo->scenesChangedCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnScenesChanged");
|
||||
pluginInfo->sourceOrderChangedCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnSourceOrderChanged");
|
||||
pluginInfo->sourceChangedCallback = (OBS_SOURCE_CHANGED_CALLBACK)GetProcAddress(hPlugin, "OnSourceChanged");
|
||||
pluginInfo->sourcesAddedOrRemovedCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnSourcesAddedOrRemoved");
|
||||
pluginInfo->micVolumeChangeCallback = (OBS_VOLUME_CHANGED_CALLBACK)GetProcAddress(hPlugin, "OnMicVolumeChanged");
|
||||
pluginInfo->desktopVolumeChangeCallback = (OBS_VOLUME_CHANGED_CALLBACK)GetProcAddress(hPlugin, "OnDesktopVolumeChanged");
|
||||
pluginInfo->logUpdateCallback = (OBS_LOG_UPDATE_CALLBACK)GetProcAddress(hPlugin, "OnLogUpdate");
|
||||
pluginInfo->startStreamCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartStream");
|
||||
pluginInfo->stopStreamCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopStream");
|
||||
pluginInfo->startStreamingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartStreaming");
|
||||
pluginInfo->stopStreamingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopStreaming");
|
||||
pluginInfo->startRecordingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartRecording");
|
||||
pluginInfo->stopRecordingCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopRecording");
|
||||
pluginInfo->statusCallback = (OBS_STATUS_CALLBACK)GetProcAddress(hPlugin, "OnOBSStatus");
|
||||
pluginInfo->streamStatusCallback = (OBS_STREAM_STATUS_CALLBACK)GetProcAddress(hPlugin, "OnStreamStatus");
|
||||
pluginInfo->sceneSwitchCallback = (OBS_SCENE_SWITCH_CALLBACK)GetProcAddress(hPlugin, "OnSceneSwitch");
|
||||
pluginInfo->scenesChangedCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnScenesChanged");
|
||||
pluginInfo->sourceOrderChangedCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnSourceOrderChanged");
|
||||
pluginInfo->sourceChangedCallback = (OBS_SOURCE_CHANGED_CALLBACK)GetProcAddress(hPlugin, "OnSourceChanged");
|
||||
pluginInfo->sourcesAddedOrRemovedCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnSourcesAddedOrRemoved");
|
||||
pluginInfo->micVolumeChangeCallback = (OBS_VOLUME_CHANGED_CALLBACK)GetProcAddress(hPlugin, "OnMicVolumeChanged");
|
||||
pluginInfo->desktopVolumeChangeCallback = (OBS_VOLUME_CHANGED_CALLBACK)GetProcAddress(hPlugin, "OnDesktopVolumeChanged");
|
||||
pluginInfo->logUpdateCallback = (OBS_LOG_UPDATE_CALLBACK)GetProcAddress(hPlugin, "OnLogUpdate");
|
||||
pluginInfo->startRecordingReplayBufferCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStartRecordingReplayBuffer");
|
||||
pluginInfo->stopRecordingReplayBufferCallback = (OBS_CALLBACK)GetProcAddress(hPlugin, "OnStopRecordingReplayBuffer");
|
||||
pluginInfo->replayBufferSavedCallback = (OBS_REPLAY_BUFFER_SAVED_CALLBACK)GetProcAddress(hPlugin, "OnReplayBufferSaved");
|
||||
|
||||
//GETPLUGINNAMEPROC getName = (GETPLUGINNAMEPROC)GetProcAddress(hPlugin, "GetPluginName");
|
||||
|
||||
|
|
15
Source/OBS.h
15
Source/OBS.h
|
@ -283,6 +283,7 @@ struct ClassInfo
|
|||
|
||||
/* Event callback signiture definitions */
|
||||
typedef void (*OBS_CALLBACK)();
|
||||
typedef void (*OBS_REPLAY_BUFFER_SAVED_CALLBACK)(CTSTR filename, UINT recordingLengthMS);
|
||||
typedef void (*OBS_STATUS_CALLBACK)(bool /*running*/, bool /*streaming*/, bool /*recording*/,
|
||||
bool /*previewing*/, bool /*reconnecting*/);
|
||||
typedef void (*OBS_STREAM_STATUS_CALLBACK)(bool /*streaming*/, bool /*previewOnly*/,
|
||||
|
@ -319,6 +320,15 @@ struct PluginInfo
|
|||
/* called when recording (to file) stops */
|
||||
OBS_CALLBACK stopRecordingCallback;
|
||||
|
||||
/* called when recording (to replay buffer) starts */
|
||||
OBS_CALLBACK startRecordingReplayBufferCallback;
|
||||
|
||||
/* called when recording (to replay buffer) stops */
|
||||
OBS_CALLBACK stopRecordingReplayBufferCallback;
|
||||
|
||||
/* called when replay buffer has been written to a file */
|
||||
OBS_REPLAY_BUFFER_SAVED_CALLBACK replayBufferSavedCallback;
|
||||
|
||||
/* called when status bar is updated, even without network */
|
||||
OBS_STATUS_CALLBACK statusCallback;
|
||||
|
||||
|
@ -364,6 +374,7 @@ struct GlobalSourceInfo
|
|||
enum
|
||||
{
|
||||
ID_SETTINGS=5000,
|
||||
ID_TOGGLERECORDINGREPLAYBUFFER,
|
||||
ID_TOGGLERECORDING,
|
||||
ID_STARTSTOP,
|
||||
ID_EXIT,
|
||||
|
@ -561,6 +572,7 @@ enum class SceneCollectionAction {
|
|||
};
|
||||
|
||||
struct ReplayBuffer;
|
||||
void SaveReplayBuffer(ReplayBuffer *out, DWORD timestamp);
|
||||
|
||||
//todo: this class has become way too big, it's horrible, and I should be ashamed of myself
|
||||
class OBS
|
||||
|
@ -1200,6 +1212,9 @@ public:
|
|||
virtual void ReportStopStreamingTrigger();
|
||||
virtual void ReportStartRecordingTrigger();
|
||||
virtual void ReportStopRecordingTrigger();
|
||||
virtual void ReportStartRecordingReplayBufferTrigger();
|
||||
virtual void ReportStopRecordingReplayBufferTrigger();
|
||||
virtual void ReportReplayBufferSavedTrigger(String filename, UINT recordingLengthMS);
|
||||
virtual void ReportOBSStatus(bool running, bool streaming, bool recording,
|
||||
bool previewing, bool reconnecting);
|
||||
virtual void ReportStreamStatus(bool streaming, bool previewOnly = false,
|
||||
|
|
|
@ -104,6 +104,7 @@ void OBS::StartReplayBuffer()
|
|||
Log(L"Using ReplayBuffer with a length of %d seconds", length);
|
||||
|
||||
bRecordingReplayBuffer = true;
|
||||
ReportStartRecordingReplayBufferTrigger();
|
||||
|
||||
ConfigureStreamButtons();
|
||||
}
|
||||
|
@ -111,7 +112,9 @@ void OBS::StartReplayBuffer()
|
|||
void OBS::StopReplayBuffer()
|
||||
{
|
||||
if (!replayBufferStream) return;
|
||||
|
||||
bRecordingReplayBuffer = false;
|
||||
ReportStopRecordingReplayBufferTrigger();
|
||||
|
||||
if (!bStreaming && !bRecording && bRunning) Stop(true);
|
||||
|
||||
|
|
|
@ -100,6 +100,46 @@ void OBS::ReportStopRecordingTrigger()
|
|||
}
|
||||
}
|
||||
|
||||
void OBS::ReportStartRecordingReplayBufferTrigger()
|
||||
{
|
||||
if (bShuttingDown)
|
||||
return;
|
||||
|
||||
for (UINT i = 0; i<plugins.Num(); i++)
|
||||
{
|
||||
OBS_CALLBACK callback = plugins[i].startRecordingReplayBufferCallback;
|
||||
|
||||
if (callback)
|
||||
(*callback)();
|
||||
}
|
||||
}
|
||||
void OBS::ReportStopRecordingReplayBufferTrigger()
|
||||
{
|
||||
if (bShuttingDown)
|
||||
return;
|
||||
|
||||
for (UINT i = 0; i<plugins.Num(); i++)
|
||||
{
|
||||
OBS_CALLBACK callback = plugins[i].stopRecordingReplayBufferCallback;
|
||||
|
||||
if (callback)
|
||||
(*callback)();
|
||||
}
|
||||
}
|
||||
void OBS::ReportReplayBufferSavedTrigger(String filename, UINT recordingLengthMS)
|
||||
{
|
||||
if (bShuttingDown)
|
||||
return;
|
||||
|
||||
for (UINT i = 0; i<plugins.Num(); i++)
|
||||
{
|
||||
OBS_REPLAY_BUFFER_SAVED_CALLBACK callback = plugins[i].replayBufferSavedCallback;
|
||||
|
||||
if (callback)
|
||||
(*callback)(filename, recordingLengthMS);
|
||||
}
|
||||
}
|
||||
|
||||
void OBS::ReportOBSStatus(bool running, bool streaming, bool recording, bool previewing, bool reconnecting)
|
||||
{
|
||||
if (bShuttingDown)
|
||||
|
|
|
@ -111,8 +111,6 @@ void STDCALL OBS::StopReplayBufferHotkey(DWORD hotkey, UPARAM param, bool bDown)
|
|||
}
|
||||
}
|
||||
|
||||
void SaveReplayBuffer(ReplayBuffer *out, DWORD timestamp);
|
||||
|
||||
void STDCALL OBS::SaveReplayBufferHotkey(DWORD hotkey, UPARAM param, bool bDown)
|
||||
{
|
||||
if (App->bSaveReplayBufferHotkeyDown && !bDown)
|
||||
|
|
|
@ -142,9 +142,10 @@ struct ReplayBuffer : VideoFileStream
|
|||
save_times.emplace_back(timestamp);
|
||||
}
|
||||
|
||||
static void SetLastFilename(String name)
|
||||
static void SaveComplete(String name, DWORD recordingLengthMS)
|
||||
{
|
||||
App->lastOutputFile = name;
|
||||
App->ReportReplayBufferSavedTrigger(name, recordingLengthMS);
|
||||
}
|
||||
|
||||
static void SetRecording(bool recording)
|
||||
|
@ -194,14 +195,21 @@ static DWORD STDCALL SaveReplayBufferThread(void *arg)
|
|||
signalled = true;
|
||||
};
|
||||
|
||||
DWORD lowest_timestamp = MAXDWORD;
|
||||
DWORD highest_timestamp = 0;
|
||||
|
||||
while (packets.size())
|
||||
{
|
||||
auto &packet = packets.front();
|
||||
if (get<2>(*packet) == stop_ts)
|
||||
break;
|
||||
|
||||
auto timestamp = get<1>(*packet);
|
||||
lowest_timestamp = min(timestamp, lowest_timestamp);
|
||||
highest_timestamp = max(timestamp, highest_timestamp);
|
||||
|
||||
auto &buf = get<3>(*packet);
|
||||
out->AddPacket(buf, get<1>(*packet), get<2>(*packet), get<0>(*packet));
|
||||
out->AddPacket(buf, timestamp, get<2>(*packet), get<0>(*packet));
|
||||
|
||||
if (buf->front() == 0x17)
|
||||
signal();
|
||||
|
@ -210,7 +218,7 @@ static DWORD STDCALL SaveReplayBufferThread(void *arg)
|
|||
}
|
||||
signal();
|
||||
|
||||
ReplayBuffer::SetLastFilename(name);
|
||||
ReplayBuffer::SaveComplete(name, highest_timestamp > lowest_timestamp ? (highest_timestamp - lowest_timestamp) : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3323,6 +3323,12 @@ LRESULT CALLBACK OBS::OBSProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
|
|||
App->RefreshStreamButtons();
|
||||
break;
|
||||
|
||||
case ID_TOGGLERECORDINGREPLAYBUFFER:
|
||||
App->RefreshStreamButtons(true);
|
||||
App->ToggleReplayBuffer();
|
||||
App->RefreshStreamButtons();
|
||||
break;
|
||||
|
||||
case ID_FILE_EXIT:
|
||||
case ID_EXIT:
|
||||
PostQuitMessage(0);
|
||||
|
|
Loading…
Reference in New Issue