Skip to content

Commit 1178a4d

Browse files
Miriadvideopipe
andcommitted
feat: migrate video services to Sanity config system (Phase B)
- remotion.ts: awsRegion, serveUrl, functionName → getConfigValue('remotion_config') - elevenlabs.ts: voiceId → getConfigValue('pipeline_config', 'elevenLabsVoiceId') - gcs.ts: bucketName, projectId → getConfigValue('gcs_config') - All use env var fallbacks for migration safety - Secrets (API keys, AWS credentials) remain as process.env Co-authored-by: videopipe <videopipe@miriad.systems>
1 parent b8939e7 commit 1178a4d

File tree

3 files changed

+26
-27
lines changed

3 files changed

+26
-27
lines changed

lib/services/elevenlabs.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
type WordTimestamp,
1313
type SceneAudioResult,
1414
} from "@/lib/utils/audio-timestamps";
15+
import { getConfigValue } from "@/lib/config";
1516

1617
const ELEVENLABS_API_BASE = "https://api.elevenlabs.io/v1";
1718

@@ -62,9 +63,12 @@ interface TTSWithTimestampsResponse {
6263
* @returns The resolved {@link ElevenLabsConfig}.
6364
* @throws {Error} If required environment variables are missing.
6465
*/
65-
function getConfig(): ElevenLabsConfig {
66+
async function getElevenLabsConfig(): Promise<ElevenLabsConfig> {
6667
const apiKey = process.env.ELEVENLABS_API_KEY;
67-
const voiceId = process.env.ELEVENLABS_VOICE_ID;
68+
const voiceId = await getConfigValue(
69+
"pipeline_config", "elevenLabsVoiceId",
70+
process.env.ELEVENLABS_VOICE_ID || "pNInz6obpgDQGcFmaJgB"
71+
);
6872

6973
if (!apiKey) {
7074
throw new Error(
@@ -73,13 +77,6 @@ function getConfig(): ElevenLabsConfig {
7377
);
7478
}
7579

76-
if (!voiceId) {
77-
throw new Error(
78-
"Missing ELEVENLABS_VOICE_ID environment variable. " +
79-
"Set it in your .env.local or deployment environment."
80-
);
81-
}
82-
8380
return { apiKey, voiceId };
8481
}
8582

@@ -106,7 +103,7 @@ export async function generateSpeech(text: string): Promise<Buffer> {
106103
throw new Error("Cannot generate speech from empty text.");
107104
}
108105

109-
const { apiKey, voiceId } = getConfig();
106+
const { apiKey, voiceId } = await getElevenLabsConfig();
110107

111108
const url = `${ELEVENLABS_API_BASE}/text-to-speech/${voiceId}`;
112109

@@ -244,7 +241,7 @@ export async function generateSpeechWithTimestamps(
244241
throw new Error("Cannot generate speech from empty text.");
245242
}
246243

247-
const { apiKey, voiceId } = getConfig();
244+
const { apiKey, voiceId } = await getElevenLabsConfig();
248245

249246
const url = `${ELEVENLABS_API_BASE}/text-to-speech/${voiceId}/with-timestamps`;
250247

lib/services/gcs.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*/
1515

1616
import * as crypto from "crypto";
17+
import { getConfigValue } from "@/lib/config";
1718

1819
// ---------------------------------------------------------------------------
1920
// Types
@@ -63,9 +64,9 @@ const TOKEN_REFRESH_MARGIN_MS = 5 * 60 * 1000; // 5 minutes
6364
* The private key may contain literal `\\n` sequences from the env var;
6465
* these are converted to real newline characters.
6566
*/
66-
export function getGCSConfig(): GCSConfig {
67-
const bucket = process.env.GCS_BUCKET;
68-
const projectId = process.env.GCS_PROJECT_ID;
67+
export async function getGCSConfig(): Promise<GCSConfig> {
68+
const bucket = await getConfigValue("gcs_config", "bucketName", process.env.GCS_BUCKET);
69+
const projectId = await getConfigValue("gcs_config", "projectId", process.env.GCS_PROJECT_ID);
6970
const clientEmail = process.env.GCS_CLIENT_EMAIL;
7071
let privateKey = process.env.GCS_PRIVATE_KEY;
7172

@@ -205,7 +206,7 @@ async function getAccessToken(): Promise<string> {
205206
return cachedToken.accessToken;
206207
}
207208

208-
const config = getGCSConfig();
209+
const config = await getGCSConfig();
209210
const jwt = createServiceAccountJWT(config);
210211
cachedToken = await exchangeJWTForToken(jwt);
211212
return cachedToken.accessToken;
@@ -231,7 +232,7 @@ export async function uploadToGCS(
231232
path: string,
232233
contentType: string
233234
): Promise<UploadResult> {
234-
const config = getGCSConfig();
235+
const config = await getGCSConfig();
235236
const token = await getAccessToken();
236237

237238
const encodedPath = encodeURIComponent(path);
@@ -338,7 +339,7 @@ export async function getSignedUrl(
338339
expiresInMinutes = 60
339340
): Promise<string> {
340341
// We still validate config to fail fast if env vars are missing
341-
const config = getGCSConfig();
342+
const config = await getGCSConfig();
342343

343344
// For public objects, the public URL is sufficient
344345
void expiresInMinutes; // acknowledged but unused for public objects

lib/services/remotion.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ import {
2222
getRenderProgress,
2323
type AwsRegion,
2424
} from "@remotion/lambda/client";
25+
import { getConfigValue } from "@/lib/config";
2526

2627
// ---------------------------------------------------------------------------
2728
// Types
2829
// ---------------------------------------------------------------------------
2930

30-
export interface RemotionConfig {
31+
export interface RemotionLambdaConfig {
3132
awsAccessKeyId: string;
3233
awsSecretAccessKey: string;
3334
region: string;
@@ -130,11 +131,11 @@ function mapInputProps(input: RenderInput): Record<string, unknown> {
130131
* Get Remotion Lambda configuration from environment variables.
131132
* Throws if any required env var is missing.
132133
*/
133-
export function getRemotionConfig(): RemotionConfig {
134+
export async function getRemotionConfig(): Promise<RemotionLambdaConfig> {
134135
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
135136
const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
136-
const region = process.env.REMOTION_AWS_REGION;
137-
const serveUrl = process.env.REMOTION_SERVE_URL;
137+
const region = await getConfigValue("remotion_config", "awsRegion", process.env.REMOTION_AWS_REGION);
138+
const serveUrl = await getConfigValue("remotion_config", "serveUrl", process.env.REMOTION_SERVE_URL);
138139

139140
const missing: string[] = [];
140141
if (!awsAccessKeyId) missing.push("AWS_ACCESS_KEY_ID");
@@ -161,8 +162,8 @@ export function getRemotionConfig(): RemotionConfig {
161162
/**
162163
* Get the Lambda function name from env or use the default.
163164
*/
164-
function getFunctionName(): string {
165-
return process.env.REMOTION_FUNCTION_NAME || DEFAULT_FUNCTION_NAME;
165+
async function getFunctionName(): Promise<string> {
166+
return getConfigValue("remotion_config", "functionName", process.env.REMOTION_FUNCTION_NAME || DEFAULT_FUNCTION_NAME);
166167
}
167168

168169
// ---------------------------------------------------------------------------
@@ -202,8 +203,8 @@ async function startRender(
202203
composition: string,
203204
input: RenderInput
204205
): Promise<{ renderId: string; bucketName: string }> {
205-
const config = getRemotionConfig();
206-
const functionName = getFunctionName();
206+
const config = await getRemotionConfig();
207+
const functionName = await getFunctionName();
207208
const region = config.region as AwsRegion;
208209

209210
log(`Starting render for composition "${composition}"`, {
@@ -291,8 +292,8 @@ export async function checkRenderProgress(
291292
renderId: string,
292293
bucketName: string
293294
): Promise<RenderProgressResult> {
294-
const config = getRemotionConfig();
295-
const functionName = getFunctionName();
295+
const config = await getRemotionConfig();
296+
const functionName = await getFunctionName();
296297
const region = config.region as AwsRegion;
297298

298299
const progress = await getRenderProgress({

0 commit comments

Comments
 (0)