mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
promp and replay tweaks
This commit is contained in:
@@ -20,7 +20,7 @@ Rules:
|
|||||||
- Ignore obvious bot commands and responses in chat.
|
- Ignore obvious bot commands and responses in chat.
|
||||||
|
|
||||||
Chat style:
|
Chat style:
|
||||||
- Always use English.
|
- Only send messages in English. Do not use other languages.
|
||||||
- If speaking, send one short live-chat line.
|
- If speaking, send one short live-chat line.
|
||||||
- Keep it concise and informal (roughly 3-14 words).
|
- Keep it concise and informal (roughly 3-14 words).
|
||||||
- Chat output must be spoken text only.
|
- Chat output must be spoken text only.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const FFMPEG_BIN = process.env.FFMPEG_BIN || 'ffmpeg';
|
|||||||
const SEGMENT_ROOT = path.join(resolveDataDir(), 'replay-segments');
|
const SEGMENT_ROOT = path.join(resolveDataDir(), 'replay-segments');
|
||||||
const SEGMENT_SECONDS = Math.max(1, Number.parseInt(process.env.REPLAY_SEGMENT_SECONDS || '1', 10));
|
const SEGMENT_SECONDS = Math.max(1, Number.parseInt(process.env.REPLAY_SEGMENT_SECONDS || '1', 10));
|
||||||
const BUFFER_SECONDS = Math.max(20, Number.parseInt(process.env.REPLAY_BUFFER_SECONDS || '45', 10));
|
const BUFFER_SECONDS = Math.max(20, Number.parseInt(process.env.REPLAY_BUFFER_SECONDS || '45', 10));
|
||||||
const CLEANUP_INTERVAL_MS = 10_000;
|
const CLEANUP_INTERVAL_MS = Math.max(500, Number.parseInt(process.env.REPLAY_TICK_MS || '2000', 10));
|
||||||
const BUILD_DURATION_MS = Math.max(5000, Number.parseInt(process.env.REPLAY_DURATION_MS || '35000', 10));
|
const BUILD_DURATION_MS = Math.max(5000, Number.parseInt(process.env.REPLAY_DURATION_MS || '35000', 10));
|
||||||
const BUILD_GUARD_MS = Math.max(200, Number.parseInt(process.env.REPLAY_GUARD_MS || '1200', 10));
|
const BUILD_GUARD_MS = Math.max(200, Number.parseInt(process.env.REPLAY_GUARD_MS || '1200', 10));
|
||||||
const TARGET_FPS = Math.max(10, Number.parseInt(process.env.REPLAY_TARGET_FPS || '30', 10));
|
const TARGET_FPS = Math.max(10, Number.parseInt(process.env.REPLAY_TARGET_FPS || '30', 10));
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ const replayBuilder = createReplayBuilder({
|
|||||||
});
|
});
|
||||||
registerReplaySocketHooks({ tryTriggerReplay, validateSources, getDefaultWebSources });
|
registerReplaySocketHooks({ tryTriggerReplay, validateSources, getDefaultWebSources });
|
||||||
|
|
||||||
|
async function buildReplayVideoFresh(options = {}) {
|
||||||
|
await tick();
|
||||||
|
return replayBuilder.buildReplayVideo(options);
|
||||||
|
}
|
||||||
|
|
||||||
function getReplayHealthSnapshot() {
|
function getReplayHealthSnapshot() {
|
||||||
return segmentStore.getReplayHealthSnapshot({ BUILD_DURATION_MS, roverManager, getRoomCameras });
|
return segmentStore.getReplayHealthSnapshot({ BUILD_DURATION_MS, roverManager, getRoomCameras });
|
||||||
}
|
}
|
||||||
@@ -98,7 +103,7 @@ start().catch((err) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
buildReplayVideo: replayBuilder.buildReplayVideo,
|
buildReplayVideo: buildReplayVideoFresh,
|
||||||
tryTriggerReplay,
|
tryTriggerReplay,
|
||||||
getReplayState,
|
getReplayState,
|
||||||
replayEvents,
|
replayEvents,
|
||||||
|
|||||||
@@ -52,6 +52,22 @@ function buildChatEventsForWindow(startMs, endMs, limit = 22, preWindowCount = 1
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createReplayBuilder({ execFileAsync, fsp, ensureDir, renderSidebarVideo, getVideoEntriesForSource, getAudioEntriesForRover, overlapping }) {
|
function createReplayBuilder({ execFileAsync, fsp, ensureDir, renderSidebarVideo, getVideoEntriesForSource, getAudioEntriesForRover, overlapping }) {
|
||||||
|
function resolveReplayWindow({ sources = [], nowMs, guardMs, durationMs }) {
|
||||||
|
const tentativeEnd = nowMs - guardMs;
|
||||||
|
const sourceEnds = [];
|
||||||
|
for (const source of sources) {
|
||||||
|
const sourceId = String(source.id);
|
||||||
|
const allEntries = getVideoEntriesForSource({ type: String(source.type), id: sourceId });
|
||||||
|
if (!Array.isArray(allEntries) || !allEntries.length) continue;
|
||||||
|
const bounded = allEntries.filter((entry) => Number.isFinite(entry?.endMs) && entry.endMs <= tentativeEnd);
|
||||||
|
if (!bounded.length) continue;
|
||||||
|
const latest = bounded.reduce((best, entry) => (entry.endMs > best.endMs ? entry : best), bounded[0]);
|
||||||
|
sourceEnds.push(latest.endMs);
|
||||||
|
}
|
||||||
|
const alignedEnd = sourceEnds.length ? Math.min(...sourceEnds) : tentativeEnd;
|
||||||
|
return { tEnd: alignedEnd, tStart: alignedEnd - durationMs };
|
||||||
|
}
|
||||||
|
|
||||||
async function concatFiles(inputPaths, outPath) {
|
async function concatFiles(inputPaths, outPath) {
|
||||||
const listPath = `${outPath}.concat.txt`;
|
const listPath = `${outPath}.concat.txt`;
|
||||||
const body = inputPaths.map((file) => `file '${file.replace(/'/g, "'\\''")}'`).join('\n');
|
const body = inputPaths.map((file) => `file '${file.replace(/'/g, "'\\''")}'`).join('\n');
|
||||||
@@ -74,8 +90,12 @@ function createReplayBuilder({ execFileAsync, fsp, ensureDir, renderSidebarVideo
|
|||||||
|
|
||||||
async function buildReplayVideo({ sources = [], title = '', requester = '', includeSidebar = true } = {}) {
|
async function buildReplayVideo({ sources = [], title = '', requester = '', includeSidebar = true } = {}) {
|
||||||
if (!Array.isArray(sources) || !sources.length) throw new Error('No replay sources selected');
|
if (!Array.isArray(sources) || !sources.length) throw new Error('No replay sources selected');
|
||||||
const tEnd = Date.now() - BUILD_GUARD_MS;
|
const { tEnd, tStart } = resolveReplayWindow({
|
||||||
const tStart = tEnd - BUILD_DURATION_MS;
|
sources,
|
||||||
|
nowMs: Date.now(),
|
||||||
|
guardMs: BUILD_GUARD_MS,
|
||||||
|
durationMs: BUILD_DURATION_MS,
|
||||||
|
});
|
||||||
const resolvedTitle = sanitizeReplayTitle(title, resolveDefaultReplayTitle(requester, sources));
|
const resolvedTitle = sanitizeReplayTitle(title, resolveDefaultReplayTitle(requester, sources));
|
||||||
const tmpDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'mrr-replay-v2-'));
|
const tmpDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'mrr-replay-v2-'));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user