Smarter Replay Buffer Options?

FAT9L

New Member
I've done some research and poked around in my settings/plugins, and can't seem to find a way to do what I'm trying to accomplish. For context, I have my replay buffer running all the time, complete with a hotkey and OBS automatically starting minimized at login. This makes it behave essentially the same as a program like Shadowplay. Very convenient, especially with the NVENC encoder. It also performs slightly better than constantly recording, and avoids wasting disk space. No problems or complaints with that.

The issue I'm running into is that I want the replay buffer to not capture redundant footage, if I grab multiple clips from the same "session" (don't know a better term). For example, here's a generic example of how it currently behaves:
  • 00:00:00 - The replay buffer starts, and is recording 5 minutes of footage at a time.
  • 00:06:00 - I press my "save recording" hotkey, which captures 5 minutes (00:01:00 - 00:06:00)
  • 00:07:00 - I hit the hotkey again, which captures 5:00 minutes (00:02:00 - 00:07:00)
  • 00:13:00 - I hit the hotkey again, which captures 5:00 minutes (00:08:00 - 00:13:00)
Here's what I would like to happen instead:
  • 00:00:00 - The replay buffer starts, and is recording 5 minutes of footage at a time.
  • 00:06:00 - I press my "save recording" hotkey, which captures 5:00 minutes (00:01:00 - 00:06:00)
  • 00:07:00 - I hit the hotkey again, which captures ≤ 5 minutes, depending on whether or not I have recently saved a recording. Ideally this would still have a bit of padding on the leading end, let's say 30 seconds (~00:05:30 - 00:07:00 [starting from 00:06:00, minus the 30 second padding])
  • 00:13:00 - I hit the hotkey again, which captures ≤ 5 minutes (00:08:00 - 00:13:00)
Hopefully this makes sense.

I cannot seem to find a way to make this happen. It cuts down on my workflow efficiency when editing later on, due to having redundant footage that I have to skip through an arbitrary amount to find something new. This also consumes more storage space (not a huge concern for me, but annoying), and seems like it would be more efficient than repeatedly encoding/saving part of the replay buffer unnecessarily.

Thoughts, ideas, workarounds, plugins? Anything would help. Thank you in advance.
 

FAT9L

New Member
For what it's worth, I know that Advanced Scene Switcher supports macros to enable/disable the replay buffer, however I don't think that constantly stopping and restarting it every time I save a recording is the best option. I'd guess that it might cause issues as well, or miss parts of recordings between when it's stopped and started.
 

Tomasz Góral

Active Member
OBS don’t remember time of last saving replays.
Replays buffer is circullay, new data arrive, old data is removed.

You need somethings who after save clear replays buffers.
Now i see solution in macro, maybe in future, someone add options to clear buffer after save.
 

KillianM

New Member
Bump - @FAT9L Are you still utilising Advanced Scene Switcher for this purpose? Looking to set this up myself as I also do not like the overlap in recordings.
 

FAT9L

New Member
Bump - @FAT9L Are you still utilising Advanced Scene Switcher for this purpose? Looking to set this up myself as I also do not like the overlap in recordings.
I have not yet found a decent workaround or a way to make it happen.

I've poked around in a few different tools, done extensive research, and tried every possible thing I can think of, short of creating my own plugin. Nothing seems to be right for my use case.
 

FAT9L

New Member
Bump - @FAT9L Are you still utilising Advanced Scene Switcher for this purpose? Looking to set this up myself as I also do not like the overlap in recordings.
@KillianM
As I think you've already seen, this was fixed with the latest release shown here:

There is still the slight problem that you lose a couple of seconds between recordings, however I'm willing to accept that tradeoff. Best of luck.
 

anthonybaldwin

New Member
I was looking into this myself and found this thread. While there is probably a simple way to do the same or smarter with a Lua script, I'm using my Elgato Stream Deck and the OBS plugin w/in a multi action key to reset the buffer. The key simply saves buffer, waits, stops buffer, waits, then starts the buffer again.
  • OBS Studio: Replay Buffer Save
  • Delay (2000ms)
  • OBS Studio: Replay Buffer (Stop)
  • Delay (2000ms)
  • OBS Studio: Replay Buffer (Start)
Note: 1000ms also does the trick, but not including a delay did not. I'm erring on the side of caution with 2000ms.

Screenshot 2022-12-09 130933.png
 
Last edited:

HAMODE3389

New Member
I was looking into this myself and found this thread. While there is probably a simple way to do the same or smarter with a Lua script, I'm using my Elgato Stream Deck and the OBS plugin w/in a multi action key to reset the buffer. The key simply saves buffer, waits, stops buffer, waits, then starts the buffer again.
  • OBS Studio: Replay Buffer Save
  • Delay (2000ms)
  • OBS Studio: Replay Buffer (Stop)
  • Delay (2000ms)
  • OBS Studio: Replay Buffer (Start)
Note: 1000ms also does the trick, but not including a delay did not. I'm erring on the side of caution with 2000ms.

View attachment 89573
Lua:
obs = obslua

function script_description()
    return "Stops and re-enables replay buffer when a replay is saved."
end

function script_load(settings)
    obs.obs_frontend_add_event_callback(on_event)
end

function on_event(event)
    if event == obs.OBS_FRONTEND_EVENT_REPLAY_BUFFER_SAVED then
        toggle_replay_buffer()
    end
end

function toggle_replay_buffer()
    local replay_buffer_active = obs.obs_frontend_replay_buffer_active()
   
    if replay_buffer_active then
        obs.obs_frontend_replay_buffer_stop()
        obs.timer_add(start_replay_buffer, 2000)  -- Re-enable after 2 second
    end
end

function start_replay_buffer()
    obs.timer_remove(start_replay_buffer)
    obs.obs_frontend_replay_buffer_start()
end
Credit: ChatGPT
 

mee

New Member
Until the much-requested smarter replay buffer without overlap/waste gets implemented, one can "hack it" with Advanced Scene Switcher macros. The disadvantage is that you can potentially lose about 1 second of footage *after* every replay save (aka the time OBS takes to clumsily stop&restart the buffer)

1. install the Advanced Scene Switcher plugin https://obsproject.com/forum/resources/advanced-scene-switcher.395/
2. Tools -> Advanced Scene Switcher -> Macro -> right click the Macros menu on the left -> Import -> paste the code -> OK
JSON:
{
	"macros": [{
		"name": "replay-anti-overlap",
		"pause": false,
		"parallel": false,
		"onChange": true,
		"skipExecOnStart": false,
		"stopActionsIfNotDone": false,
		"group": true,
		"groupData": {
			"collapsed": false,
			"size": 2
		}
	}, {
		"name": "part1",
		"pause": false,
		"parallel": false,
		"onChange": false,
		"skipExecOnStart": false,
		"stopActionsIfNotDone": false,
		"group": false,
		"dockSettings": {
			"register": false,
			"hasRunButton": true,
			"hasPauseButton": true,
			"hasStatusLabel": false,
			"highlightIfConditionsTrue": false,
			"runButtonText": "Run",
			"pauseButtonText": "Pause",
			"unpauseButtonText": "Unpause",
			"conditionsTrueStatusText": "Conditions are true.",
			"conditionsFalseStatusText": "Conditions are false."
		},
		"macroActionConditionSplitterPosition": [{
			"pos": 210
		}, {
			"pos": 210
		}],
		"macroElseActionSplitterPosition": [{
			"pos": 172
		}, {
			"pos": 0
		}],
		"registerHotkeys": false,
		"pauseHotkey": [],
		"unpauseHotkey": [],
		"togglePauseHotkey": [],
		"conditions": [{
			"segmentSettings": {
				"collapsed": false,
				"useCustomLabel": false,
				"customLabel": "My label"
			},
			"id": "replay_buffer",
			"logic": 0,
			"durationModifier": {
				"time_constraint": 0,
				"seconds": {
					"value": {
						"value": 1.0,
						"type": 0
					},
					"unit": 0,
					"version": 1
				}
			},
			"state": 2
		}],
		"actions": [{
			"segmentSettings": {
				"collapsed": false,
				"useCustomLabel": false,
				"customLabel": "My label"
			},
			"id": "replay_buffer",
			"enabled": true,
			"action": 0
		}],
		"elseActions": [],
		"inputVariables": []
	}, {
		"name": "part2",
		"pause": false,
		"parallel": false,
		"onChange": false,
		"skipExecOnStart": false,
		"stopActionsIfNotDone": false,
		"group": false,
		"dockSettings": {
			"register": false,
			"hasRunButton": true,
			"hasPauseButton": true,
			"hasStatusLabel": false,
			"highlightIfConditionsTrue": false,
			"runButtonText": "Run",
			"pauseButtonText": "Pause",
			"unpauseButtonText": "Unpause",
			"conditionsTrueStatusText": "Conditions are true.",
			"conditionsFalseStatusText": "Conditions are false."
		},
		"macroActionConditionSplitterPosition": [{
			"pos": 210
		}, {
			"pos": 210
		}],
		"macroElseActionSplitterPosition": [{
			"pos": 172
		}, {
			"pos": 0
		}],
		"registerHotkeys": false,
		"pauseHotkey": [],
		"unpauseHotkey": [],
		"togglePauseHotkey": [],
		"conditions": [{
			"segmentSettings": {
				"collapsed": false,
				"useCustomLabel": false,
				"customLabel": "My label"
			},
			"id": "macro",
			"logic": 0,
			"durationModifier": {
				"time_constraint": 4,
				"seconds": {
					"value": {
						"value": 1.0,
						"type": 0
					},
					"unit": 0,
					"version": 1
				}
			},
			"macros": [],
			"macro": "part1",
			"type": 1,
			"condition": 0,
			"count": {
				"value": 0,
				"type": 0
			},
			"multiStateCount": {
				"value": 0,
				"type": 0
			},
			"multiStateCondition": 2,
			"actionIndex": {
				"value": 1,
				"type": 0
			},
			"version": 1
		}],
		"actions": [{
			"segmentSettings": {
				"collapsed": false,
				"useCustomLabel": false,
				"customLabel": "My label"
			},
			"id": "replay_buffer",
			"enabled": true,
			"action": 1
		}],
		"elseActions": [],
		"inputVariables": []
	}],
	"variables": [],
	"actionQueues": [],
	"version": "1.26.4"
}
This macro is a bit more reliable than the more barebones ones that wait for a fixed number of milliseconds, because by being slightly faster it tries to waste as little footage as possible
 
Top