vargai 0.4.0-alpha75 → 0.4.0-alpha77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -71,7 +71,7 @@
71
71
  "zod": "^4.2.1"
72
72
  },
73
73
  "sideEffects": false,
74
- "version": "0.4.0-alpha75",
74
+ "version": "0.4.0-alpha77",
75
75
  "exports": {
76
76
  ".": "./src/index.ts",
77
77
  "./ai": "./src/ai-sdk/index.ts",
@@ -85,7 +85,13 @@ function serializeValue(v: unknown): string {
85
85
  return v;
86
86
  }
87
87
  if (v instanceof Uint8Array) {
88
- return Buffer.from(v).toString("base64");
88
+ // Hash binary data instead of base64-encoding to keep cache keys small.
89
+ // Raw base64 can produce 65-110KB strings for audio segments, exceeding
90
+ // Upstash Redis' 32KB key size limit.
91
+ return `uint8:${v.byteLength}:${Bun.hash(v).toString(16)}`;
92
+ }
93
+ if (isVargElement(v)) {
94
+ return `element:${computeCacheKey(v).join(":")}`;
89
95
  }
90
96
  if (Array.isArray(v)) {
91
97
  return `[${v.map(serializeValue).join(",")}]`;
@@ -128,7 +134,7 @@ export function computeCacheKey(element: VargElement): CacheKeyPart[] {
128
134
  } else if (v === null || v === undefined) {
129
135
  key.push(k, v);
130
136
  } else if (v instanceof Uint8Array) {
131
- key.push(k, Buffer.from(v).toString("base64"));
137
+ key.push(k, `uint8:${v.byteLength}:${Bun.hash(v).toString(16)}`);
132
138
  } else if (isVargElement(v)) {
133
139
  key.push(k, ...computeCacheKey(v));
134
140
  } else if (Array.isArray(v) || typeof v === "object") {
@@ -221,6 +221,10 @@ async function sliceSegments(
221
221
  *
222
222
  * Adds a small safety padding (50ms) to capture any trailing silence
223
223
  * that exists in the original audio beyond the segment boundary.
224
+ *
225
+ * Routes through the FFmpegBackend when available (local or cloud/Rendi),
226
+ * falling back to a direct local `ffmpeg` shell command only when no
227
+ * backend exists (top-level `await` outside render()).
224
228
  */
225
229
  const SLICE_PADDING_S = 0.05; // 50ms safety padding
226
230
 
@@ -234,18 +238,45 @@ async function sliceAudio(
234
238
  const suffix = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
235
239
  const outPath = `/tmp/varg-segment-${suffix}.mp3`;
236
240
 
237
- const inputPath = ctx?.backend
238
- ? await ctx.backend.resolvePath(file)
239
- : await file.toTempFile();
241
+ if (ctx?.backend) {
242
+ // Use the backend abstraction (works for both local ffmpeg and cloud/Rendi).
243
+ // -ss goes in input options (before -i for fast seek).
244
+ const result = await ctx.backend.run({
245
+ inputs: [{ path: file, options: ["-ss", String(start)] }],
246
+ outputArgs: [
247
+ "-t",
248
+ String(duration),
249
+ "-acodec",
250
+ "libmp3lame",
251
+ "-q:a",
252
+ "2",
253
+ ],
254
+ outputPath: outPath,
255
+ });
256
+
257
+ // Rendi returns a URL, local backend returns a file path.
258
+ if (result.output.type === "url") {
259
+ const response = await fetch(result.output.url);
260
+ return new Uint8Array(await response.arrayBuffer());
261
+ }
262
+ const sliced = await Bun.file(result.output.path).arrayBuffer();
263
+ try {
264
+ await Bun.file(result.output.path).delete?.();
265
+ } catch {
266
+ /* ignore cleanup errors */
267
+ }
268
+ return new Uint8Array(sliced);
269
+ }
240
270
 
241
- // -ss before -i for fast seek, then re-encode for sample-accurate cut
271
+ // Fallback: no backend (top-level `await` outside render()) use local ffmpeg directly.
272
+ const inputPath = await file.toTempFile();
242
273
  await $`ffmpeg -y -ss ${start} -i ${inputPath} -t ${duration} -acodec libmp3lame -q:a 2 ${outPath}`.quiet();
243
274
 
244
275
  const sliced = await Bun.file(outPath).arrayBuffer();
245
276
  try {
246
277
  await Bun.file(outPath).delete?.();
247
278
  } catch {
248
- /* ignore */
279
+ /* ignore cleanup errors */
249
280
  }
250
281
  return new Uint8Array(sliced);
251
282
  }