fix: alac support

& remove caf to conversion
This commit is contained in:
Maya 2025-09-13 14:54:19 +03:00
parent 0d87e1e064
commit 9467e58d3b
No known key found for this signature in database
1 changed files with 36 additions and 12 deletions

View File

@ -47,11 +47,12 @@ export class FFmpegConverter extends Converter {
new FormatInfo("oga", true, true), new FormatInfo("oga", true, true),
new FormatInfo("opus", true, true), new FormatInfo("opus", true, true),
new FormatInfo("aac", true, true), new FormatInfo("aac", true, true),
new FormatInfo("m4a", true, true), new FormatInfo("alac", true, true), // outputted as m4a
new FormatInfo("m4a", true, true), // can be alac
new FormatInfo("caf", true, false), // can be alac
new FormatInfo("wma", true, true), new FormatInfo("wma", true, true),
new FormatInfo("amr", true, true), new FormatInfo("amr", true, true),
new FormatInfo("ac3", true, true), new FormatInfo("ac3", true, true),
new FormatInfo("alac", true, true),
new FormatInfo("aiff", true, true), new FormatInfo("aiff", true, true),
new FormatInfo("aifc", true, true), new FormatInfo("aifc", true, true),
new FormatInfo("aif", true, true), new FormatInfo("aif", true, true),
@ -64,7 +65,6 @@ export class FFmpegConverter extends Converter {
new FormatInfo("dff", true, false), // dsd new FormatInfo("dff", true, false), // dsd
new FormatInfo("mqa", true, false), new FormatInfo("mqa", true, false),
new FormatInfo("au", true, true), new FormatInfo("au", true, true),
new FormatInfo("caf", true, true),
new FormatInfo("m4b", true, true), new FormatInfo("m4b", true, true),
new FormatInfo("voc", true, true), new FormatInfo("voc", true, true),
new FormatInfo("weba", true, true), new FormatInfo("weba", true, true),
@ -103,6 +103,9 @@ export class FFmpegConverter extends Converter {
public async convert(input: VertFile, to: string): Promise<VertFile> { public async convert(input: VertFile, to: string): Promise<VertFile> {
if (!to.startsWith(".")) to = `.${to}`; if (!to.startsWith(".")) to = `.${to}`;
const isAlac = to === ".alac";
if (isAlac) to = ".m4a";
let conversionError: string | null = null; let conversionError: string | null = null;
const ffmpeg = await this.setupFFmpeg(input); const ffmpeg = await this.setupFFmpeg(input);
@ -138,7 +141,12 @@ export class FFmpegConverter extends Converter {
`wrote ${input.name} to ffmpeg virtual fs`, `wrote ${input.name} to ffmpeg virtual fs`,
); );
const command = await this.buildConversionCommand(ffmpeg, input, to); const command = await this.buildConversionCommand(
ffmpeg,
input,
to,
isAlac,
);
log(["converters", this.name], `FFmpeg command: ${command.join(" ")}`); log(["converters", this.name], `FFmpeg command: ${command.join(" ")}`);
await ffmpeg.exec(command); await ffmpeg.exec(command);
log(["converters", this.name], "executed ffmpeg command"); log(["converters", this.name], "executed ffmpeg command");
@ -280,11 +288,21 @@ export class FFmpegConverter extends Converter {
ffmpeg: FFmpeg, ffmpeg: FFmpeg,
input: VertFile, input: VertFile,
to: string, to: string,
isAlac: boolean = false,
): Promise<string[]> { ): Promise<string[]> {
const inputFormat = input.from.slice(1); const inputFormat = input.from.slice(1);
const outputFormat = to.slice(1); const outputFormat = to.slice(1);
const lossless = ["flac", "alac", "wav", "dsd", "dsf", "dff"]; const lossless = [
"flac",
"m4a",
"caf",
"alac",
"wav",
"dsd",
"dsf",
"dff",
];
const userSetting = Settings.instance.settings.ffmpegQuality; const userSetting = Settings.instance.settings.ffmpegQuality;
const userSampleRate = Settings.instance.settings.ffmpegSampleRate; const userSampleRate = Settings.instance.settings.ffmpegSampleRate;
const customSampleRate = const customSampleRate =
@ -398,7 +416,7 @@ export class FFmpegConverter extends Converter {
const hasAlbumArt = keepMetadata const hasAlbumArt = keepMetadata
? await this.extractAlbumArt(ffmpeg) ? await this.extractAlbumArt(ffmpeg)
: false; : false;
const codecArgs = toArgs(to); const codecArgs = toArgs(to, isAlac);
if (hasAlbumArt) { if (hasAlbumArt) {
log( log(
@ -439,7 +457,7 @@ export class FFmpegConverter extends Converter {
"yuv420p", "yuv420p",
"-r", "-r",
"1", "1",
...codecArgs, ...toArgs(to, isAlac),
...metadataArgs, ...metadataArgs,
...audioBitrateArgs, ...audioBitrateArgs,
...sampleRateArgs, ...sampleRateArgs,
@ -453,7 +471,7 @@ export class FFmpegConverter extends Converter {
["converters", this.name], ["converters", this.name],
`Converting audio ${input.from} to audio ${to}`, `Converting audio ${input.from} to audio ${to}`,
); );
const { audio: audioCodec } = getCodecs(to); const { audio: audioCodec } = getCodecs(to, isAlac);
return [ return [
"-i", "-i",
"input", "input",
@ -534,8 +552,8 @@ export class FFmpegConverter extends Converter {
// //
// i hate you SO much. // i hate you SO much.
// - love, maddie // - love, maddie
const toArgs = (ext: string): string[] => { const toArgs = (ext: string, isAlac: boolean = false): string[] => {
const codecs = getCodecs(ext); const codecs = getCodecs(ext, isAlac);
const args = ["-c:v", codecs.video]; const args = ["-c:v", codecs.video];
switch (codecs.video) { switch (codecs.video) {
@ -573,7 +591,10 @@ const toArgs = (ext: string): string[] => {
return args; return args;
}; };
const getCodecs = (ext: string): { video: string; audio: string } => { const getCodecs = (
ext: string,
isAlac: boolean = false,
): { video: string; audio: string } => {
switch (ext) { switch (ext) {
// video <-> audio // video <-> audio
case ".mp4": case ".mp4":
@ -621,7 +642,10 @@ const getCodecs = (ext: string): { video: string; audio: string } => {
case ".aac": case ".aac":
return { video: "libx264", audio: "aac" }; return { video: "libx264", audio: "aac" };
case ".m4a": case ".m4a":
return { video: "libx264", audio: "aac" }; return {
video: "libx264",
audio: isAlac ? "alac" : "aac",
};
case ".alac": case ".alac":
return { video: "libx264", audio: "alac" }; return { video: "libx264", audio: "alac" };
case ".wma": case ".wma":