Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/handlers/FFmpeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,40 @@ import mime from "mime";
import normalizeMimeType from "../normalizeMimeType.ts";
import CommonFormats from "src/CommonFormats.ts";

export function getSpecialAudioFormats(): FileFormat[] {
return [
{
name: "Ogg Opus Audio",
format: "opus",
extension: "ogg",
mime: CommonFormats.OGG.mime,
from: true,
to: false,
internal: "ogg",
category: "audio",
lossless: false
},
{
name: "Ogg Vorbis Audio",
format: "vorbis",
extension: "ogg",
mime: CommonFormats.OGG.mime,
from: false,
to: true,
internal: "ogg",
category: "audio",
lossless: false
}
];
}

export function getCodecArgsForFormat(outputFormat: FileFormat): string[] {
if (outputFormat.internal === "ogg" && outputFormat.format === "vorbis") {
return ["-c:a", "libvorbis"];
}
return [];
}

class FFmpegHandler implements FormatHandler {

static formatNames: Map<string, string> = new Map([
Expand Down Expand Up @@ -258,6 +292,7 @@ class FFmpegHandler implements FormatHandler {
// Add PNG input explicitly - FFmpeg otherwise treats both PNG and
// APNG as the same thing.
this.supportedFormats.push(CommonFormats.PNG.builder("png").allowFrom());
this.supportedFormats.push(...getSpecialAudioFormats());

this.#ffmpeg.terminate();

Expand Down Expand Up @@ -302,6 +337,7 @@ class FFmpegHandler implements FormatHandler {
} else if (outputFormat.internal === "asf") {
command.push("-b:v", "15M", "-b:a", "192k");
}
command.push(...getCodecArgsForFormat(outputFormat));
if (args) command.push(...args);
command.push("output");

Expand Down
40 changes: 40 additions & 0 deletions test/handlers/ffmpeg.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect, test } from "bun:test";
import CommonFormats from "../../src/CommonFormats.ts";
import { getCodecArgsForFormat, getSpecialAudioFormats } from "../../src/handlers/FFmpeg.ts";

test("ffmpeg exposes distinct ogg opus and ogg vorbis aliases", () => {
const formats = getSpecialAudioFormats();

expect(formats).toEqual([
{
name: "Ogg Opus Audio",
format: "opus",
extension: "ogg",
mime: CommonFormats.OGG.mime,
from: true,
to: false,
internal: "ogg",
category: "audio",
lossless: false
},
{
name: "Ogg Vorbis Audio",
format: "vorbis",
extension: "ogg",
mime: CommonFormats.OGG.mime,
from: false,
to: true,
internal: "ogg",
category: "audio",
lossless: false
}
]);
});

test("ffmpeg forces libvorbis for ogg vorbis output", () => {
const vorbisFormat = getSpecialAudioFormats()[1];
expect(getCodecArgsForFormat(vorbisFormat)).toEqual(["-c:a", "libvorbis"]);

const plainOgg = CommonFormats.OGG.builder("ogg").allowTo();
expect(getCodecArgsForFormat(plainOgg)).toEqual([]);
});