unpiped :(
This commit is contained in:
parent
9e061e2ff4
commit
1b72a87764
2 changed files with 85 additions and 53 deletions
|
@ -14,23 +14,25 @@ yt.usage = "[search term]";
|
|||
yt.callback = async function (msg, line) {
|
||||
if (!line) return "Arguments are required.";
|
||||
|
||||
const req = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`).then((x) =>
|
||||
x.json()
|
||||
);
|
||||
const req = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=5&part=snippet&type=video&q=${encodeURIComponent(line)}`
|
||||
).then((res) => res.json());
|
||||
|
||||
const topVid = req.items[0];
|
||||
|
||||
let out = `**${safeString(parseHtmlEntities(topVid.title))}** | \`${safeString(
|
||||
parseHtmlEntities(topVid.uploaderName)
|
||||
)}\`\nhttps://youtube.com${topVid.url}\n\n**__See Also:__**\n`;
|
||||
let out = `**${safeString(parseHtmlEntities(topVid.snippet.title))}** | \`${safeString(
|
||||
parseHtmlEntities(topVid.snippet.channelTitle)
|
||||
)}\`\nhttps://youtu.be/${topVid.id.videoId}\n\n**__See Also:__**\n`;
|
||||
|
||||
for (let i = 1; i < 5; i++) {
|
||||
const vid = req.items[i];
|
||||
if (!vid) continue;
|
||||
|
||||
out += `- **${safeString(parseHtmlEntities(vid.title))}** | By: \`${safeString(
|
||||
parseHtmlEntities(vid.uploaderName)
|
||||
)}\` | <https://youtube.com${vid.url}>\n`;
|
||||
out += `- **${safeString(parseHtmlEntities(vid.snippet.title))}** | By: \`${safeString(
|
||||
parseHtmlEntities(vid.snippet.channelTitle)
|
||||
)}\` | <https://youtu.be/${vid.id.videoId}>\n`;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
@ -60,15 +62,17 @@ fyt.usage = "[search term]";
|
|||
fyt.callback = async function (msg, line) {
|
||||
if (!line) return "Arguments are required.";
|
||||
|
||||
const req = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`).then((x) =>
|
||||
x.json()
|
||||
);
|
||||
const req = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=2&part=snippet&type=video&q=${encodeURIComponent(line)}`
|
||||
).then((res) => res.json());
|
||||
|
||||
const vid = req.items[0];
|
||||
|
||||
return `**${safeString(parseHtmlEntities(vid.title))}** | \`${safeString(
|
||||
parseHtmlEntities(vid.uploaderName)
|
||||
)}\`\nhttps://youtube.com${vid.url}`;
|
||||
return `**${safeString(parseHtmlEntities(vid.snippet.title))}** | \`${safeString(
|
||||
parseHtmlEntities(vid.snippet.channelTitle)
|
||||
)}\`\nhttps://youtu.be/${vid.id.videoId}`;
|
||||
};
|
||||
hf.registerCommand(fyt);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const {Collection} = require("@projectdysnomia/dysnomia");
|
||||
|
||||
const {Readable} = require("node:stream");
|
||||
const ffprobe = require("node-ffprobe");
|
||||
|
||||
const Command = require("#lib/command.js");
|
||||
|
@ -55,20 +54,18 @@ async function processPlaylist(url, type, shuffle = false, limit = -1, offset =
|
|||
const playlistId = url.match(REGEX_YOUTUBE_PLAYLIST)?.[4] ?? url.match(REGEX_YOUTUBE_PLAYLIST_SHORT)?.[0];
|
||||
if (!playlistId) return null;
|
||||
|
||||
const baseUrl = "/playlists/" + playlistId;
|
||||
const baseUrl = `https://www.googleapis.com/youtube/v3/playlistItems?key=${hf.apikeys.google}&part=snippet&playlistId=${playlistId}&maxResults=50`;
|
||||
|
||||
const data = await fetch(hf.config.piped_api + baseUrl).then((res) => res.json());
|
||||
const data = await fetch(baseUrl).then((res) => res.json());
|
||||
|
||||
playlist = data.relatedStreams;
|
||||
playlist = data.items;
|
||||
|
||||
let pageToken = data.nextpage;
|
||||
while (pageToken?.startsWith("{")) {
|
||||
const pageData = await fetch(
|
||||
hf.config.piped_api + "/nextpage" + baseUrl + "&nextpage=" + encodeURIComponent(pageToken)
|
||||
).then((res) => res.json());
|
||||
if (pageData.nextpage) pageToken = pageData.nextpage;
|
||||
let pageToken = data.nextPageToken;
|
||||
while (pageToken != null) {
|
||||
const pageData = await fetch(baseUrl + "&pageToken=" + encodeURIComponent(pageToken)).then((res) => res.json());
|
||||
if (pageData.nextPageToken) pageToken = pageData.nextPageToken;
|
||||
|
||||
playlist = [...playlist, ...pageData.relatedStreams];
|
||||
playlist = [...playlist, ...pageData.items];
|
||||
}
|
||||
} else if (type === "sc") {
|
||||
const clientId = await getSoundcloudClientID();
|
||||
|
@ -176,7 +173,6 @@ async function createVoiceConnection(guild_id, voice_id, text_id) {
|
|||
return state;
|
||||
}
|
||||
|
||||
const REGEX_HLS_AUDIO_TRACK = /#EXT-X-MEDIA:URI="(.+?)",TYPE=AUDIO,/;
|
||||
async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppress = false, queueNext = false}) {
|
||||
if (!url) return;
|
||||
|
||||
|
@ -189,7 +185,8 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
|||
media,
|
||||
stream = false;
|
||||
|
||||
if (type == "yt") {
|
||||
// this is only whitelisted because residential ip being used
|
||||
if (type == "yt" && hf.config.yt_whitelist.includes(guild_id)) {
|
||||
let info;
|
||||
let id = url;
|
||||
try {
|
||||
|
@ -201,27 +198,53 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
|||
id = uri.searchParams.get("v");
|
||||
}
|
||||
}
|
||||
info = await fetch(`${hf.config.piped_api}/streams/${id}`).then((res) => res.json());
|
||||
info = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=${id}&fields=items%2Fsnippet&key=${hf.apikeys.google}`
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((data) => data?.items?.[0]);
|
||||
} catch (err) {
|
||||
await textChannel.createMessage({
|
||||
content: `:warning: Failed to get metadata: \`\`\`\n${err}\n\`\`\``,
|
||||
});
|
||||
}
|
||||
|
||||
title = info?.title;
|
||||
length = info?.duration * 1000;
|
||||
thumbnail = info?.thumbnailUrl;
|
||||
title = info?.snippet?.title;
|
||||
|
||||
const hlsUrl = new URL(info.hls);
|
||||
const hlsBase = await fetch(info.hls)
|
||||
.then((res) => res.text())
|
||||
.then((data) => data.replaceAll("/api/manifest/", `https://${hlsUrl.hostname}/api/manifest/`));
|
||||
const thumbnails = info?.snippet?.thumbnails;
|
||||
thumbnail = thumbnails?.maxres?.url ?? thumbnails?.standard?.url;
|
||||
|
||||
media = Readable.from(
|
||||
await fetch(hlsBase.match(REGEX_HLS_AUDIO_TRACK)[1])
|
||||
.then((res) => res.text())
|
||||
.then((data) => data.replaceAll("/videoplayback/", `https://${hlsUrl.hostname}/videoplayback/`))
|
||||
);
|
||||
const [, h, m, s] = info.contentDetails.duration.match(/P.*?T(\d+H)?(\d+M)?(\d+S)/);
|
||||
length =
|
||||
((h != null ? parseInt(h.replace("H", "")) * 60 * 60 : 0) +
|
||||
(m != null ? parseInt(m.replace("M", "")) * 60 : 0) +
|
||||
parseInt(s.replace("S", ""))) *
|
||||
1000;
|
||||
|
||||
let stream;
|
||||
if (!connection.connection.playing) {
|
||||
try {
|
||||
stream = await fetch(hf.config.cobalt_api, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Api-Key ${hf.apikeys.cobalt}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
url: `https://youtu.be/${id}`,
|
||||
downloadMode: "audio",
|
||||
filenameStyle: "basic",
|
||||
}),
|
||||
}).then((res) => res.json());
|
||||
} catch (err) {
|
||||
await textChannel.createMessage({
|
||||
content: `:warning: Failed to get stream: \`\`\`\n${err}\n\`\`\``,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
media = stream?.url;
|
||||
} else if (type == "sc") {
|
||||
if (url?.startsWith("sc:")) url = url.replace(/^sc:/, "https://soundcloud.com/");
|
||||
const client_id = await getSoundcloudClientID();
|
||||
|
@ -314,7 +337,7 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
|||
} else {
|
||||
if (!media) {
|
||||
textChannel.createMessage({
|
||||
content: `:warning: No usable media was found for \`${url}\`. May possibly be due to region restrictions or paywalls.`,
|
||||
content: type == "yt" ? "youtube :b:roke" : `:warning: No usable media was found for \`${url}\`.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -367,18 +390,23 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
|||
}
|
||||
|
||||
async function youtubeSearch(msg, str) {
|
||||
const {items} = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(str)}&filter=videos`).then((x) =>
|
||||
x.json()
|
||||
);
|
||||
const {items} = await fetch(
|
||||
`https://www.googleapis.com/youtube/v3/search?key=${
|
||||
hf.apikeys.google
|
||||
}&maxResults=5&part=snippet&type=video&q=${encodeURIComponent(str)}`
|
||||
).then((res) => res.json());
|
||||
|
||||
const selection = items.map((item) => ({
|
||||
value: "https://youtube.com" + item.url,
|
||||
key: item.url.replace("/watch?v=", ""),
|
||||
display: `${parseHtmlEntities(item.title).substring(0, 99)}${parseHtmlEntities(item.title).length > 99 ? "…" : ""}`,
|
||||
description: `from ${parseHtmlEntities(item.uploaderName).substring(0, 95)}${
|
||||
parseHtmlEntities(item.uploaderName).length > 95 ? "…" : ""
|
||||
}`,
|
||||
}));
|
||||
const selection = items.map((item) => {
|
||||
const title = parseHtmlEntities(item.snippet.title);
|
||||
const channel = parseHtmlEntities(item.snippet.channelTitle);
|
||||
|
||||
return {
|
||||
value: "https://youtu.be/" + item.id.videoId,
|
||||
key: item.id.videoId,
|
||||
display: `${title.substring(0, 99)}${title.length > 99 ? "…" : ""}`,
|
||||
description: `from ${channel.substring(0, 95)}${channel.length > 95 ? "…" : ""}`,
|
||||
};
|
||||
});
|
||||
|
||||
try {
|
||||
return await selectionMessage(msg, "Search results:", selection);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue