Files
church-translate/app/_probe-rewrites.mjs
christianandClaude Opus 5 c9eef0672c Church Translate, as it runs at the campuses
Live sermon translation into 100+ languages, running entirely on one Mac per
campus: audio in, voice detection, Whisper on the GPU, NLLB-200 in its own
process, and a built-in web server the congregation reads from on their
phones. No audio leaves the building.

This is the source only. What used to sit beside it — 14 GB of speech and
translation models, 8 GB of voice bundles, 6 GB of natural voices, the Electron
caches, and the app data holding the operator PIN and every service transcript
— is machine state and downloaded assets, and stays in the NAS backup where it
belongs. The vendored node, cloudflared and Windows ffmpeg binaries are out too
(533 MB, re-fetched for packaging); the browser-side runtime beside them is
kept, so a checkout still serves the congregation page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 15:41:21 -04:00

34 lines
1.9 KiB
JavaScript

import { pipeline, env } from '@huggingface/transformers';
import os from 'os'; import path from 'path';
env.allowLocalModels=false;
env.cacheDir=path.join(os.homedir(),'Library/Application Support/Church Translate Models');
const pipe=await pipeline('translation','Xenova/nllb-200-distilled-600M',{dtype:'fp32'});
const say=async(t,l)=>{const o=await pipe(t,{src_lang:'eng_Latn',tgt_lang:l});return (Array.isArray(o)?o[0]:o).translation_text.trim();};
/* Each candidate must EARN its place: the rewrite has to beat the original in
more than one language, or it is just a different guess. */
const PAIRS=[
['Open up to the book of John.', 'Turn to the book of John.'],
['Circle that in your Bible.', 'Mark that in your Bible.'],
['Let that sink in.', 'Think carefully about that.'],
['Walk it out.', 'Put it into practice.'],
['That will preach.', 'That is worth preaching.'],
['Let me unpack that for you.', 'Let me explain that to you.'],
['We are going to camp out here for a minute.','We are going to stay here for a minute.'],
['Give God a hand of praise.', 'Applaud to praise God.'],
['Put a hand on your neighbor.', 'Put a hand on the person next to you.'],
['Drop down to verse ten.', 'Go to verse ten.'],
['Back up to verse one.', 'Go back to verse one.'],
['Are you tracking with me.', 'Are you following me.'],
['I want you to catch this.', 'I want you to understand this.'],
['God showed up.', 'God was present.']
];
const LANGS=['spa_Latn','por_Latn','fra_Latn'];
for (const [before,after] of PAIRS) {
console.log('\n' + before + '\n -> ' + after);
for (const l of LANGS) {
const b=await say(before,l), a=await say(after,l);
console.log(' '+l.slice(0,3)+' was: '+b+'\n now: '+a+(a===b?' (no change)':''));
}
}