← back to Rentv
fix(boomer-voice): correct the stale comment naming the WRONG voice_id (EoZq → the current czUP clone) + normalize CRE shorthand for TTS ('1.27 msf'→'1.27 million square feet') + strip title trailing punctuation and fix empty-core double-space in the VO
749cf6e92b9181122a83b3b3130cde6536006036 · 2026-08-06 09:28:25 -0700 · Steve
Files touched
Diff
commit 749cf6e92b9181122a83b3b3130cde6536006036
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Aug 6 09:28:25 2026 -0700
fix(boomer-voice): correct the stale comment naming the WRONG voice_id (EoZq → the current czUP clone) + normalize CRE shorthand for TTS ('1.27 msf'→'1.27 million square feet') + strip title trailing punctuation and fix empty-core double-space in the VO
---
server.js | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/server.js b/server.js
index 1db5f58e..d67b68cd 100644
--- a/server.js
+++ b/server.js
@@ -1053,18 +1053,27 @@ app.post('/api/content/email', adminOnly, async (req, res) => {
});
// ── Content Studio → "Boomer" video/voice ───────────────────────────────────
-// Narrates the GENERATED post in Steve Bloom's ("Boomer") cloned ElevenLabs voice
-// (VOICE_ID EoZqhGRrFYVEnxL4P2So, the VO he recorded 2026-07-31). Reuses the async
+// Narrates the GENERATED post in Steve Bloom's ("Boomer") cloned ElevenLabs voice. The actual
+// voice_id is the CURRENT fresh clone czUPGx5phxE6qpQ46nRS (social-video-gen.mjs default; the older
+// EoZqhGRrFYVEnxL4P2So / 6x9fou9Xwqy5FH5seKdC clones sounded wrong and are retired). Reuses the async
// social-video job infra — poll via GET /api/social/video/:jobId. mode:'voice' → mp3
// only; mode:'video' → photo + Ken-Burns + voice mp4. Cost: ElevenLabs ~$0.30/1k chars
// (returned to the client); ffmpeg is local $0. Admin-only; renders only, nothing posts.
+// Normalize CRE shorthand for SPEECH so the TTS reads "1.27 million square feet", not "1.27 m s f".
+const forSpeech = (s) => String(s || '')
+ .replace(/(\d[\d,.]*)\s*msf\b/gi, '$1 million square feet')
+ .replace(/(\d[\d,.]*)\s*k\s*sf\b/gi, '$1 thousand square feet')
+ .replace(/\bsq\.?\s?ft\.?\b/gi, 'square feet')
+ .replace(/\bsf\b/gi, 'square feet')
+ .replace(/\s+/g, ' ').trim();
function boomerScript(title, highlights, body) {
- const t = clean(title, 200).replace(/\s+/g, ' ').trim();
+ // strip a trailing sentence-ender off the title so "...Sold!" doesn't become "...Sold!." in the VO
+ const t = forSpeech(clean(title, 200)).replace(/[.!?]+$/, '').trim();
let core = '';
if (Array.isArray(highlights) && highlights.length) core = highlights.map(h => clean(h, 300)).filter(Boolean).slice(0, 4).join(' ');
if (!core) core = clean(body, 800).split(/(?<=[.!?])\s+/).map(s => s.trim()).filter(Boolean).slice(0, 3).join(' ');
- core = core.replace(/\s+/g, ' ').trim();
- const vo = `This is Boom with RENTV. ${t}. ${core} For the full story, visit rentv dot com.`;
+ core = forSpeech(core);
+ const vo = `This is Boom with RENTV. ${t}. ${core ? core + ' ' : ''}For the full story, visit rentv dot com.`;
return vo.slice(0, 1100); // cap ~1.1k chars ≈ $0.33 so a single clip's TTS cost stays bounded
}
app.post('/api/content/boomer', adminOnly, (req, res) => {
← 27f2cd04 News map: market-activity stats panel (count + deal volume +
·
back to Rentv
·
PR intel: router-level capability gate (b1) — every /api/pr 1be2f46b →