diff --git a/packages/core/src/content/transcript/providers/youtube/yt-dlp.ts b/packages/core/src/content/transcript/providers/youtube/yt-dlp.ts index 5be81394..671b8e96 100644 --- a/packages/core/src/content/transcript/providers/youtube/yt-dlp.ts +++ b/packages/core/src/content/transcript/providers/youtube/yt-dlp.ts @@ -216,6 +216,17 @@ export const fetchTranscriptWithYtDlp = async ({ if (result.notes.length > 0) notes.push(...result.notes); return { text: result.text, provider: result.provider, error: result.error, notes }; } catch (error) { + if ( + error instanceof Error && + error.message.includes("unable to obtain file audio codec with ffprobe") + ) { + return { + text: "", + provider: null, + error: null, + notes: [...notes, "yt-dlp: Media has no audio stream"], + }; + } return { text: null, provider: null, diff --git a/tests/transcript.yt-dlp.test.ts b/tests/transcript.yt-dlp.test.ts index 1cfd6e9a..8ae36fc2 100644 --- a/tests/transcript.yt-dlp.test.ts +++ b/tests/transcript.yt-dlp.test.ts @@ -125,6 +125,32 @@ describe("yt-dlp transcript helper", () => { expect(result.error?.message).toMatch(/yt-dlp exited with code 1/); }); + it("returns empty text and a note when yt-dlp fails with 'unable to obtain file audio codec'", async () => { + spawnMock.mockImplementation(() => { + const proc = new EventEmitter() as any; + proc.stdout = new PassThrough(); + proc.stderr = new PassThrough(); + process.nextTick(() => { + proc.stderr.write( + "ERROR: Postprocessing: WARNING: unable to obtain file audio codec with ffprobe\n", + ); + proc.stderr.end(); + process.nextTick(() => proc.emit("close", 1, null)); + }); + return proc; + }); + + const result = await fetchTranscriptWithYtDlp({ + ytDlpPath: "/usr/bin/yt-dlp", + openaiApiKey: "OPENAI", + url: "https://youtu.be/dQw4w9WgXcQ", + }); + + expect(result.text).toBe(""); + expect(result.error).toBeNull(); + expect(result.notes).toContain("yt-dlp: Media has no audio stream"); + }); + it("passes --no-playlist to yt-dlp", async () => { mockSpawnSuccess(); (globalThis.fetch as unknown as ReturnType).mockResolvedValue(