Add fluent-ffmpeg dependency and refactor AAC to FLAC conversion logic

This commit is contained in:
Seth 2025-04-20 03:12:29 -04:00
parent df0627dea2
commit 34e6265cae
3 changed files with 26 additions and 11 deletions

View file

@ -8,6 +8,7 @@
"@types/fluent-ffmpeg": "^2.1.27",
"ffmpeg-static": "^5.2.0",
"flac-stream-tagger": "^1.0.10",
"fluent-ffmpeg": "^2.1.3",
},
"devDependencies": {
"@types/bun": "latest",
@ -31,6 +32,8 @@
"agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
"async": ["async@0.2.10", "", {}, "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="],
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"bun-types": ["bun-types@1.2.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-b5ITZMnVdf3m1gMvJHG+gIfeJHiQPJak0f7925Hxu6ZN5VKA8AGy4GZ4lM+Xkn6jtWxg5S3ldWvfmXdvnkp3GQ=="],
@ -47,6 +50,8 @@
"flac-stream-tagger": ["flac-stream-tagger@1.0.10", "", { "dependencies": { "imageinfo": "^1.0.4" } }, "sha512-RqXyWnwx5xGTUuTCxzCCKK085sVxZzVCPwe1LShj1bDAn8zglhYcAPBorL4R0pK6+IIJtJsUuief3AawpNwIjw=="],
"fluent-ffmpeg": ["fluent-ffmpeg@2.1.3", "", { "dependencies": { "async": "^0.2.9", "which": "^1.1.1" } }, "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q=="],
"http-response-object": ["http-response-object@3.0.2", "", { "dependencies": { "@types/node": "^10.0.3" } }, "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA=="],
"https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
@ -55,6 +60,8 @@
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"parse-cache-control": ["parse-cache-control@1.0.1", "", {}, "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg=="],
@ -73,6 +80,8 @@
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"which": ["which@1.3.1", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "./bin/which" } }, "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ=="],
"http-response-object/@types/node": ["@types/node@10.17.60", "", {}, "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="],
}
}

View file

@ -11,7 +11,8 @@
"@tidal-music/auth": "^1.3.4",
"@types/fluent-ffmpeg": "^2.1.27",
"ffmpeg-static": "^5.2.0",
"flac-stream-tagger": "^1.0.10"
"flac-stream-tagger": "^1.0.10",
"fluent-ffmpeg": "^2.1.3"
},
"devDependencies": {
"@types/bun": "latest"

View file

@ -1,6 +1,9 @@
import { FlacStreamTagger } from "flac-stream-tagger";
import Ffmpeg from "fluent-ffmpeg";
import ffmpegPath from "ffmpeg-static";
import { PassThrough } from "stream";
Ffmpeg.setFfmpegPath(ffmpegPath as string);
export default class {
authHeaders: { [key: string]: string }
@ -10,18 +13,20 @@ export default class {
}
async convertAacToFlac(buffer: ArrayBuffer) {
const fileId = Bun.nanoseconds().toString(36);
const inputStream = new PassThrough();
inputStream.end(Buffer.from(buffer));
Bun.write(`tmp/${fileId}.aac`, Buffer.from(buffer))
const outputChunks: Buffer[] = [];
await Bun.$`${ffmpegPath} -i tmp/${fileId}.aac -c:a flac tmp/${fileId}.flac`.quiet()
await Bun.file(`tmp/${fileId}.aac`).delete();
const flac = Bun.file(`tmp/${fileId}.flac`)
const audioBuffer = await flac.arrayBuffer();
await flac.delete()
return audioBuffer;
await new Promise((resolve, reject) => {
Ffmpeg(inputStream)
.audioCodec("flac")
.format("flac")
.on("error", reject)
.on("end", resolve)
.pipe()
.on("data", chunk => outputChunks.push(chunk));
});
}
async fetchTrack(id: number) {