dodano obsłuugę linków ze spotify oraz soundcloud
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user