dodano obsłuugę linków ze spotify oraz soundcloud

This commit is contained in:
Patryk Koreń
2026-01-03 22:48:46 +01:00
parent 28b6546c25
commit 6ad7e01957
7 changed files with 1299 additions and 23 deletions

View File

@@ -1,41 +1,65 @@
import { spawn } from "node:child_process";
import { DATA_DIR } from "../main";
import { DATA_DIR, spotify } from "../main";
import ytSearch from 'yt-search';
export async function getAudioFile(url: string): Promise<string> {
const id = extractId(url)
const id = await extractId(url)
console.log(`ID: ${id}`);
let path: string;
try {
path = await findFileById(id)
} catch (e) {
await downloadYTVideo(url)
await downloadAudio(url)
console.log(`downloaded ${id}`)
path = await findFileById(id)
}
return path
}
export function extractId(url: string): string {
const idMatch = /[?&]v=([a-zA-Z0-9_-]{11})/.exec(url);
if (!idMatch) throw new Error("Cannot extract video ID");
const id = idMatch[1];
console.log(`ID: ${id}`);
return id
export async function extractId(url: string): Promise<string> {
if (url.startsWith("https://soundcloud")) { // soundcloud
const ytDlpBin = process.env.YT_DLP_BIN_PATH! ?? "yt-dlp";
return await new Promise<string>((resolve, reject) => {
const p = spawn(ytDlpBin, [
"--print", "%(id)s",
url,
]);
let out = ""
p.stderr.on("data", d => process.stderr.write(d));
p.stdout.on("data", d => out += d.toString());
p.on("close", code => code === 0 ? resolve(out.trim()) : reject(new Error("yt-dlp extract id failed")));
});
} else {
const idMatch = /[?&]v=([a-zA-Z0-9_-]{11})/.exec(url);
if (!idMatch) throw new Error("Cannot extract video ID");
const id = idMatch[1];
return id
}
}
export async function downloadYTVideo(url: string): Promise<void> {
export async function downloadAudio(url: string): Promise<void> {
const ytDlpBin = process.env.YT_DLP_BIN_PATH! ?? "yt-dlp";
await new Promise<void>((resolve, reject) => {
const p = spawn(ytDlpBin, [
"-x",
"--audio-format", "opus",
// "--audio-format", "opus",
"--audio-quality", "0",
"--no-playlist",
"--paths", DATA_DIR,
"--paths", `temp:/tmp`,
"--paths", `home:${DATA_DIR}`,
url,
]);
p.stderr.on("data", d => process.stderr.write(d));
p.on("close", code => code === 0 ? resolve() : reject(new Error("yt-dlp failed")));
p.stdout.on("data", d => process.stdout.write(d))
p.on("close", code => {
console.log("Pobieranie exit code: ", code)
code === 0 ? resolve() : reject(new Error("yt-dlp failed"))
});
});
}
@@ -44,7 +68,7 @@ export async function findFileById(id: string): Promise<string> {
const find = spawn("find", [
DATA_DIR,
"-type", "f",
"-iname", `*${id}*.opus`,
"-iname", `*${id}*`,
"-exec", "readlink", "-f", "{}", ";",
]);
@@ -93,3 +117,21 @@ export function formatFilePath(path: string): string {
.replace(/\[.*\].opus/, "")
.trim();
}
export async function spotifyToYouTube(spotifyUrl: string) {
const data = await spotify.clientCredentialsGrant()
// console.log(data, {
// clientId: process.env.SPOTIFY_CLIENT_ID,
// clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
// }, spotify)
spotify.setAccessToken(data.body.access_token)
const trackId = spotifyUrl.split('/track/')[1].split('?')[0];
const track = await spotify.getTrack(trackId);
const query = `${track.body.name} ${track.body.artists[0].name}`;
const result = await ytSearch(query);
return result.videos[0].url;
}