ariaa
Version:
A CLI for music lovers
90 lines • 3.92 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
import { logger } from "#lib/structures";
import { path } from "@ffmpeg-installer/ffmpeg";
import { MultiBar, Presets } from "cli-progress";
import { blueBright, greenBright, underline } from "colorette";
import ffmpeg from "fluent-ffmpeg";
import { rm, writeFile } from "node:fs/promises";
import { tmpdir } from "os";
import { join } from "path";
import sanitize from "sanitize-filename";
import { request } from "undici";
import ytdl from "@distube/ytdl-core";
import { getConfig, musicPath } from "./config.js";
import { wait } from "./functions.js";
import { getGenre } from "./genre.js";
import { filter, parse, saveTmpAudio } from "./music.js";
import { getArtist } from "./spotify.js";
async function saveAlbum(videos, album, overrideformat) {
ffmpeg.setFfmpegPath(path);
const bars = new MultiBar(
{
hideCursor: true,
stopOnComplete: true,
clearOnComplete: true,
format: `Downloading | ${blueBright("{bar}")} {percentage}% | ETA: ${greenBright("{eta}")}s`
},
Presets.shades_classic
);
const { format, bitrate } = getConfig(true);
const coverUrl = album.images[0].url;
overrideformat ??= format;
logger.debug(`Saving in ${underline(overrideformat)} format`);
const coverStream = await request(coverUrl).then((res) => res.body.arrayBuffer());
const tmpImg = join(tmpdir(), `${(Math.random() + 1).toString(36)}.jpg`);
await writeFile(tmpImg, Buffer.from(coverStream));
const date = `${new Date(album.release_date).getUTCFullYear()}`;
const genre = getGenre((await getArtist(album.artists[0].id)).genres);
const promises = [];
for (const [i, vid] of videos.entries()) {
const promise = download(vid, bars, overrideformat, album, bitrate, i, tmpImg, genre, date);
promises.push(promise);
}
await Promise.all(promises);
logger.info(`Successfully saved ${underline(album.name)}`);
if (tmpImg) await rm(tmpImg);
}
__name(saveAlbum, "saveAlbum");
async function download(vid, bars, overrideformat, album, bitrate, i, tmpImg, genre, date) {
const metadata = album.tracks.items[i];
const bar = bars.create(vid.duration * 2 / 1e3, 0);
const stream = ytdl(vid.url, { quality: "highestaudio", highWaterMark: 1 << 25 });
const tmpAudio = join(tmpdir(), `${(Math.random() + 1).toString(36)}.${overrideformat}`);
await saveTmpAudio(stream, tmpAudio, bar, bitrate);
return new Promise((resolve, reject) => {
try {
const file = ffmpeg(tmpAudio).outputOptions("-acodec", "libmp3lame", "-b:a", `${bitrate}k`, "-id3v2_version", "3").on("progress", (p) => {
bar.update(Math.floor(parse(p.timemark.slice(3))) + vid.duration / 1e3);
}).on("end", async () => {
bar.update(vid.duration * 2 / 1e3);
bar.stop();
await rm(tmpAudio);
await wait(1e3);
resolve();
}).outputOptions(`-metadata`, `album=${album.name}`).outputOptions(`-metadata`, `title=${filter(metadata?.name)}`).outputOptions(`-metadata`, `track=${metadata.track_number}`).outputOptions(`-metadata`, `genre=${genre}`).outputOptions(`-metadata`, `artist=${metadata?.artists.map((r) => r.name).join(", ")}`).outputOptions(`-metadata`, `album_artist=${album.artists[0].name}`).outputOptions(`-metadata`, `date=${date}`);
if (tmpImg) {
file.input(tmpImg).outputOptions(
"-map",
"0:0",
"-map",
"1:0",
"-disposition:v",
"attached_pic",
"-metadata:s:v",
'title="Album cover"',
"-metadata:s:v",
'comment="Cover (Front)"'
);
}
file.saveToFile(musicPath(sanitize(metadata.name), overrideformat, sanitize(album.name)));
} catch (error) {
reject(error);
}
});
}
__name(download, "download");
export {
saveAlbum
};
//# sourceMappingURL=saveAlbum.js.map