← back to Dw Marketing Reels
video-runner: give renders narrated audio via auto-resolved HYPERFRAMES_PYTHON
8227e20da7c603b2986ad0e6ef971ddb60d481e4 · 2026-07-22 07:33:08 -0700 · Steve
Auto-resolve the local HyperFrames TTS venv (~/.hyperframes/tts-venv/bin/python)
and inject it only into the render child's env — so auto-rendered reels get
voiceover/BGM without arming or mutating the pm2/server environment. Honours an
explicit HYPERFRAMES_PYTHON if already set.
Files touched
M scripts/video-runner.mjs
Diff
commit 8227e20da7c603b2986ad0e6ef971ddb60d481e4
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jul 22 07:33:08 2026 -0700
video-runner: give renders narrated audio via auto-resolved HYPERFRAMES_PYTHON
Auto-resolve the local HyperFrames TTS venv (~/.hyperframes/tts-venv/bin/python)
and inject it only into the render child's env — so auto-rendered reels get
voiceover/BGM without arming or mutating the pm2/server environment. Honours an
explicit HYPERFRAMES_PYTHON if already set.
---
scripts/video-runner.mjs | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/scripts/video-runner.mjs b/scripts/video-runner.mjs
index 8d5ab6b..fdc4fef 100644
--- a/scripts/video-runner.mjs
+++ b/scripts/video-runner.mjs
@@ -15,10 +15,16 @@ import { existsSync } from 'node:fs';
import { spawn } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
+import { homedir } from 'node:os';
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
const JOBS = join(ROOT, 'data', 'video-jobs.json');
const ARMED = process.env.VIDEO_AUTORUN === '1';
+// HyperFrames needs a Python venv for TTS/BGM audio. Honour an explicit env var if set,
+// else auto-resolve the standard local venv so auto-rendered reels get narrated audio
+// (no arming/env change needed — this only affects the render child's environment).
+const HF_PY = process.env.HYPERFRAMES_PYTHON
+ || (existsSync(join(homedir(), '.hyperframes/tts-venv/bin/python')) ? join(homedir(), '.hyperframes/tts-venv/bin/python') : '');
// A single transient Anthropic API blip ("Server is temporarily limiting requests",
// overloaded, 429/529) used to permanently kill a render. Retry those with backoff.
const MAX_TRIES = Math.max(1, Number(process.env.VIDEO_MAX_TRIES || 3));
@@ -31,7 +37,9 @@ const isTransient = s => /rate limit|temporarily limiting|overloaded|Overloaded|
function runClaude(CLAUDE_BIN, pr) {
return new Promise(resolve => {
let err = '';
- const ch = spawn(CLAUDE_BIN, ['-p', pr], { cwd: ROOT, stdio: ['ignore', 'inherit', 'pipe'] });
+ // Give the render its audio toolchain without mutating the pm2/server env.
+ const env = { ...process.env, ...(HF_PY ? { HYPERFRAMES_PYTHON: HF_PY } : {}) };
+ const ch = spawn(CLAUDE_BIN, ['-p', pr], { cwd: ROOT, env, stdio: ['ignore', 'inherit', 'pipe'] });
ch.stderr.on('data', d => { err += d; process.stderr.write(d); });
ch.on('close', code => resolve({ ok: code === 0, code, err }));
ch.on('error', e => resolve({ ok: false, code: -1, err: String(e.message) }));
← 6eb3061 Harden video-runner: retry transient API rate-limits before
·
back to Dw Marketing Reels
·
auto-save: 2026-07-22T07:42:20 (3 files) — data/video-jobs.j f9fdb8f →