diff --git a/packages/producer/src/services/htmlCompiler.remoteDownloadOnce.test.ts b/packages/producer/src/services/htmlCompiler.remoteDownloadOnce.test.ts
new file mode 100644
index 0000000000..5749026a44
--- /dev/null
+++ b/packages/producer/src/services/htmlCompiler.remoteDownloadOnce.test.ts
@@ -0,0 +1,39 @@
+import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
+import { tmpdir } from "node:os";
+import { join } from "node:path";
+import { afterEach, expect, it, vi } from "vitest";
+import { compileForRender } from "./htmlCompiler.js";
+
+const downloads = vi.hoisted(() => [] as { url: string; destDir: string }[]);
+vi.mock("../utils/urlDownloader.js", async (importOriginal) => ({
+ ...(await importOriginal()),
+ downloadToTemp: async (url: string, destDir: string) => {
+ downloads.push({ url, destDir });
+ throw new Error("offline test");
+ },
+ fetchPublicHttpsText: async () => {
+ throw new Error("offline test");
+ },
+}));
+
+const dirs: string[] = [];
+afterEach(() => {
+ downloads.length = 0;
+ for (const dir of dirs.splice(0)) rmSync(dir, { recursive: true, force: true });
+});
+
+// The download cache is keyed by url and folder: one folder is what makes the second request a cache hit.
+it("asks for a remote video in one folder for both its duration probe and its localisation", async () => {
+ const dir = mkdtempSync(join(tmpdir(), "hf-remote-once-"));
+ dirs.push(dir);
+ const url = "https://media.example.com/clip.mp4";
+ const htmlPath = join(dir, "index.html");
+ writeFileSync(
+ htmlPath,
+ ``,
+ );
+ await compileForRender(dir, htmlPath, join(dir, "out"), { allowSystemFontCapture: false });
+ const forClip = downloads.filter((call) => call.url === url);
+ expect(forClip.length).toBeGreaterThanOrEqual(2);
+ expect(new Set(forClip.map((call) => call.destDir)).size).toBe(1);
+});
diff --git a/packages/producer/src/services/htmlCompiler.ts b/packages/producer/src/services/htmlCompiler.ts
index b7c2e78ce5..72857aab2c 100644
--- a/packages/producer/src/services/htmlCompiler.ts
+++ b/packages/producer/src/services/htmlCompiler.ts
@@ -504,9 +504,10 @@ async function resolveMediaDuration(
let filePath = src;
if (isHttpUrl(src)) {
- if (!existsSync(downloadDir)) mkdirSync(downloadDir, { recursive: true });
+ const remoteDir = join(downloadDir, REMOTE_MEDIA_SUBDIR);
+ if (!existsSync(remoteDir)) mkdirSync(remoteDir, { recursive: true });
try {
- filePath = await downloadToTemp(src, downloadDir, undefined, undefined, undefined, {
+ filePath = await downloadToTemp(src, remoteDir, undefined, undefined, undefined, {
onTelemetry: logRemoteDownloadTelemetry,
});
} catch {