Setting the file. One moment.
Gemini Pipeline Test · Media Use · heygen-com/hyperframes · Skills Docs
ContentsBack to the top of the page ⋯
scripts/11 files
(opens in a new tab)
audio/scripts/ gemini-pipeline.test.mjs
JavaScript · 113 lines · 4 KB
// Exercise the actual engine and provider together; only the paid API and
9 // external audio tools are fixtures. This is not a live synthesis/render test.
10 for ( const expired of [ false , true ]) {
11 for ( const only of [ "tts" , "tts,bgm,sfx" ]) {
12 test ( `Gemini engine returns caption metadata with ${ expired ? "expired" : "absent"} HeyGen credentials (${ only })` , ( t ) => {
13 const dir = mkdtempSync ( join ( tmpdir (), "hf-gemini-pipeline-" ));
14 t. after (() => rmSync (dir, { recursive: true , force: true }));
15 const config = join (dir, "heygen" );
16 mkdirSync (config);
17 if (expired)
18 writeFileSync (
19 join (config, "credentials" ),
20 JSON . stringify ({
21 oauth: { access_token: "expired-fixture" , expires_at: "2000-01-01T00:00:00Z" },
22 }),
23 );
24 const bin = join (dir, "bin" );
25 mkdirSync (bin);
26 const preload = join (dir, "fetch.mjs" );
27 writeFileSync (
28 preload,
29 `
30 import assert from 'node:assert/strict';
31 globalThis.fetch = async (url, options) => {
32 assert.equal(url, 'https://generativelanguage.googleapis.com/v1beta/interactions');
33 const body = JSON.parse(options.body);
34 assert.equal(body.model, 'gemini-3.8-flash-lite-tts');
35 assert.equal(body.input[0].content[0].annotations[0].style, 'Line direction');
36 const bytes = Buffer.alloc(48);
37 bytes.write('RIFF'); bytes.write('WAVE', 8);
38 return Response.json({status:'completed', steps:[{type:'model_output', content:[
39 {type:'audio', mime_type:'audio/wav', data:bytes.toString('base64')}
40 ]}]});
41 };
42 ` ,
43 );
44 writeFileSync (
45 join (bin, "npx" ),
46 `#!${ process . execPath }
47 const assert = require('node:assert/strict');
48 const fs = require('node:fs');
49 const path = require('node:path');
50 const args = process.argv.slice(2);
51 assert.deepEqual(args.slice(0, 3), ['hyperframes', 'transcribe', 'assets/voice/intro.wav']);
52 assert.ok(fs.existsSync(args[2]));
53 assert.equal(args[args.indexOf('--model')+1], 'small.en');
54 fs.writeFileSync(path.join(args[args.indexOf('--dir')+1], 'transcript.json'), JSON.stringify([
55 {text:'Hello',start:0.1,end:0.4}, {text:'there.',start:0.5,end:0.9}
56 ]));
57 ` ,
58 { mode: 0o755 },
59 );
60 writeFileSync ( join (bin, "ffprobe" ), "#!/bin/sh \n echo 1.25 \n " , { mode: 0o755 });
61 writeFileSync ( join (dir, ".env" ), "" );
62 writeFileSync (
63 join (dir, "audio_request.json" ),
64 JSON . stringify ({
65 provider: "gemini" ,
66 tts_model: "gemini-3.8-flash-lite-tts" ,
67 style: "Global direction" ,
68 lines: [{ id: "intro" , text: "Hello there." , style: "Line direction" }],
69 bgm: { mode: "none" },
70 }),
71 );
72 const result = spawnSync (
73 process.execPath,
74 [
75 "--import" ,
76 preload,
77 new URL ( "./audio.mjs" , import . meta .url).pathname,
78 "--hyperframes" ,
79 dir,
80 "--only" ,
81 only,
82 ],
83 {
84 encoding: "utf8" ,
85 env: {
86 ... process.env,
87 HEYGEN_CONFIG_DIR: config,
88 HEYGEN_API_KEY: "" ,
89 HYPERFRAMES_API_KEY: "" ,
90 GEMINI_API_KEY: "fixture-key" ,
91 PATH: `${ bin }:${ process . env . PATH }` ,
92 },
93 },
94 );
95 assert. equal (result.status, 0 , result.stderr);
96 const meta = JSON . parse ( readFileSync ( join (dir, "audio_meta.json" ), "utf8" ));
97 assert. equal (meta.tts_provider, "gemini" );
98 assert. equal (meta.voice_id, "Kore" );
99 assert. deepEqual (meta.voices, [
100 {
101 id: "intro" ,
102 path: "assets/voice/intro.wav" ,
103 duration_s: 1.25 ,
104 words: [
105 { id: "w0" , text: "Hello" , start: 0.1 , end: 0.4 },
106 { id: "w1" , text: "there." , start: 0.5 , end: 0.9 },
107 ],
108 },
109 ]);
110 assert. equal (meta.total_duration_s, 1.25 );
111 });
112 }
113 }