diff --git a/src/components/VideoEditor.tsx b/src/components/VideoEditor.tsx index 3ffb6a67..60497607 100644 --- a/src/components/VideoEditor.tsx +++ b/src/components/VideoEditor.tsx @@ -355,7 +355,7 @@ export default function VideoEditor() { aria-label='Export video' aria-disabled={!file || isProcessing ? "true" : undefined} className={cn( - "w-full flex items-center justify-center gap-3 py-5 rounded-xl", + "w-full flex items-center justify-center gap-3 py-5 min-h-[44px] rounded-xl", "font-display text-2xl tracking-widest transition-all duration-200", file && !isProcessing ? "bg-film-600 hover:bg-film-700 hover:scale-[1.01] text-white shadow-lg shadow-film-200 active:scale-[0.98] cursor-pointer" diff --git a/src/lib/tests/ffmpeg.test.ts b/src/lib/tests/ffmpeg.test.ts index bdde5d41..c2e42e74 100644 --- a/src/lib/tests/ffmpeg.test.ts +++ b/src/lib/tests/ffmpeg.test.ts @@ -3,15 +3,15 @@ import { buildAudioFilter } from "../ffmpeg"; describe("buildAudioFilter", () => { it("should return an empty string for 1.0x speed", () => { - expect(buildAudioFilter(1)).toBe(""); + expect(buildAudioFilter(1, false)).toBe(""); }); it("should chain two 0.5x filters for 0.25x speed", () => { - expect(buildAudioFilter(0.25)).toBe("atempo=0.5,atempo=0.5"); + expect(buildAudioFilter(0.25, false)).toBe("atempo=0.5,atempo=0.5"); }); it("should chain two 2.0x filters for 4.0x speed", () => { - expect(buildAudioFilter(4)).toBe("atempo=2.0,atempo=2"); + expect(buildAudioFilter(4, false)).toBe("atempo=2.0,atempo=2"); }); it("should chain multiple 0.5x filters and a remainder for 0.1x speed", () => { @@ -19,25 +19,30 @@ describe("buildAudioFilter", () => { // 0.2 / 0.5 = 0.4 // 0.4 / 0.5 = 0.8 // Result should be three 0.5s and one 0.8 - expect(buildAudioFilter(0.1)).toBe("atempo=0.5,atempo=0.5,atempo=0.5,atempo=0.8"); + expect(buildAudioFilter(0.1, false)).toBe("atempo=0.5,atempo=0.5,atempo=0.5,atempo=0.8"); }); it("should chain multiple 2.0x filters and a remainder for 3.0x speed", () => { // 3.0 / 2.0 = 1.5 - expect(buildAudioFilter(3)).toBe("atempo=2.0,atempo=1.5"); + expect(buildAudioFilter(3, false)).toBe("atempo=2.0,atempo=1.5"); }); it("should handle boundary values inside the 0.5x-2.0x range without chaining", () => { - expect(buildAudioFilter(0.5)).toBe("atempo=0.5"); - expect(buildAudioFilter(2.0)).toBe("atempo=2"); // Note: Number(2.0.toFixed(4)) -> 2 - expect(buildAudioFilter(1.5)).toBe("atempo=1.5"); - expect(buildAudioFilter(0.75)).toBe("atempo=0.75"); + expect(buildAudioFilter(0.5, false)).toBe("atempo=0.5"); + expect(buildAudioFilter(2.0, false)).toBe("atempo=2"); // Note: Number(2.0.toFixed(4)) -> 2 + expect(buildAudioFilter(1.5, false)).toBe("atempo=1.5"); + expect(buildAudioFilter(0.75, false)).toBe("atempo=0.75"); }); it("should chain properly for very large speeds", () => { // 10 / 2.0 = 5 // 5 / 2.0 = 2.5 // 2.5 / 2.0 = 1.25 - expect(buildAudioFilter(10)).toBe("atempo=2.0,atempo=2.0,atempo=2.0,atempo=1.25"); + expect(buildAudioFilter(10, false)).toBe("atempo=2.0,atempo=2.0,atempo=2.0,atempo=1.25"); + }); + + it("should append loudnorm filter when normalizeAudio is true", () => { + const result = buildAudioFilter(1, true); + expect(result).toContain("loudnorm"); }); });