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) {
|
yt.callback = async function (msg, line) {
|
||||||
if (!line) return "Arguments are required.";
|
if (!line) return "Arguments are required.";
|
||||||
|
|
||||||
const req = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`).then((x) =>
|
const req = await fetch(
|
||||||
x.json()
|
`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];
|
const topVid = req.items[0];
|
||||||
|
|
||||||
let out = `**${safeString(parseHtmlEntities(topVid.title))}** | \`${safeString(
|
let out = `**${safeString(parseHtmlEntities(topVid.snippet.title))}** | \`${safeString(
|
||||||
parseHtmlEntities(topVid.uploaderName)
|
parseHtmlEntities(topVid.snippet.channelTitle)
|
||||||
)}\`\nhttps://youtube.com${topVid.url}\n\n**__See Also:__**\n`;
|
)}\`\nhttps://youtu.be/${topVid.id.videoId}\n\n**__See Also:__**\n`;
|
||||||
|
|
||||||
for (let i = 1; i < 5; i++) {
|
for (let i = 1; i < 5; i++) {
|
||||||
const vid = req.items[i];
|
const vid = req.items[i];
|
||||||
if (!vid) continue;
|
if (!vid) continue;
|
||||||
|
|
||||||
out += `- **${safeString(parseHtmlEntities(vid.title))}** | By: \`${safeString(
|
out += `- **${safeString(parseHtmlEntities(vid.snippet.title))}** | By: \`${safeString(
|
||||||
parseHtmlEntities(vid.uploaderName)
|
parseHtmlEntities(vid.snippet.channelTitle)
|
||||||
)}\` | <https://youtube.com${vid.url}>\n`;
|
)}\` | <https://youtu.be/${vid.id.videoId}>\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -60,15 +62,17 @@ fyt.usage = "[search term]";
|
||||||
fyt.callback = async function (msg, line) {
|
fyt.callback = async function (msg, line) {
|
||||||
if (!line) return "Arguments are required.";
|
if (!line) return "Arguments are required.";
|
||||||
|
|
||||||
const req = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(line)}&filter=videos`).then((x) =>
|
const req = await fetch(
|
||||||
x.json()
|
`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];
|
const vid = req.items[0];
|
||||||
|
|
||||||
return `**${safeString(parseHtmlEntities(vid.title))}** | \`${safeString(
|
return `**${safeString(parseHtmlEntities(vid.snippet.title))}** | \`${safeString(
|
||||||
parseHtmlEntities(vid.uploaderName)
|
parseHtmlEntities(vid.snippet.channelTitle)
|
||||||
)}\`\nhttps://youtube.com${vid.url}`;
|
)}\`\nhttps://youtu.be/${vid.id.videoId}`;
|
||||||
};
|
};
|
||||||
hf.registerCommand(fyt);
|
hf.registerCommand(fyt);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const {Collection} = require("@projectdysnomia/dysnomia");
|
const {Collection} = require("@projectdysnomia/dysnomia");
|
||||||
|
|
||||||
const {Readable} = require("node:stream");
|
|
||||||
const ffprobe = require("node-ffprobe");
|
const ffprobe = require("node-ffprobe");
|
||||||
|
|
||||||
const Command = require("#lib/command.js");
|
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];
|
const playlistId = url.match(REGEX_YOUTUBE_PLAYLIST)?.[4] ?? url.match(REGEX_YOUTUBE_PLAYLIST_SHORT)?.[0];
|
||||||
if (!playlistId) return null;
|
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;
|
let pageToken = data.nextPageToken;
|
||||||
while (pageToken?.startsWith("{")) {
|
while (pageToken != null) {
|
||||||
const pageData = await fetch(
|
const pageData = await fetch(baseUrl + "&pageToken=" + encodeURIComponent(pageToken)).then((res) => res.json());
|
||||||
hf.config.piped_api + "/nextpage" + baseUrl + "&nextpage=" + encodeURIComponent(pageToken)
|
if (pageData.nextPageToken) pageToken = pageData.nextPageToken;
|
||||||
).then((res) => res.json());
|
|
||||||
if (pageData.nextpage) pageToken = pageData.nextpage;
|
|
||||||
|
|
||||||
playlist = [...playlist, ...pageData.relatedStreams];
|
playlist = [...playlist, ...pageData.items];
|
||||||
}
|
}
|
||||||
} else if (type === "sc") {
|
} else if (type === "sc") {
|
||||||
const clientId = await getSoundcloudClientID();
|
const clientId = await getSoundcloudClientID();
|
||||||
|
@ -176,7 +173,6 @@ async function createVoiceConnection(guild_id, voice_id, text_id) {
|
||||||
return state;
|
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}) {
|
async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppress = false, queueNext = false}) {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
|
|
||||||
|
@ -189,7 +185,8 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
||||||
media,
|
media,
|
||||||
stream = false;
|
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 info;
|
||||||
let id = url;
|
let id = url;
|
||||||
try {
|
try {
|
||||||
|
@ -201,27 +198,53 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
||||||
id = uri.searchParams.get("v");
|
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) {
|
} catch (err) {
|
||||||
await textChannel.createMessage({
|
await textChannel.createMessage({
|
||||||
content: `:warning: Failed to get metadata: \`\`\`\n${err}\n\`\`\``,
|
content: `:warning: Failed to get metadata: \`\`\`\n${err}\n\`\`\``,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
title = info?.title;
|
title = info?.snippet?.title;
|
||||||
length = info?.duration * 1000;
|
|
||||||
thumbnail = info?.thumbnailUrl;
|
|
||||||
|
|
||||||
const hlsUrl = new URL(info.hls);
|
const thumbnails = info?.snippet?.thumbnails;
|
||||||
const hlsBase = await fetch(info.hls)
|
thumbnail = thumbnails?.maxres?.url ?? thumbnails?.standard?.url;
|
||||||
.then((res) => res.text())
|
|
||||||
.then((data) => data.replaceAll("/api/manifest/", `https://${hlsUrl.hostname}/api/manifest/`));
|
|
||||||
|
|
||||||
media = Readable.from(
|
const [, h, m, s] = info.contentDetails.duration.match(/P.*?T(\d+H)?(\d+M)?(\d+S)/);
|
||||||
await fetch(hlsBase.match(REGEX_HLS_AUDIO_TRACK)[1])
|
length =
|
||||||
.then((res) => res.text())
|
((h != null ? parseInt(h.replace("H", "")) * 60 * 60 : 0) +
|
||||||
.then((data) => data.replaceAll("/videoplayback/", `https://${hlsUrl.hostname}/videoplayback/`))
|
(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") {
|
} else if (type == "sc") {
|
||||||
if (url?.startsWith("sc:")) url = url.replace(/^sc:/, "https://soundcloud.com/");
|
if (url?.startsWith("sc:")) url = url.replace(/^sc:/, "https://soundcloud.com/");
|
||||||
const client_id = await getSoundcloudClientID();
|
const client_id = await getSoundcloudClientID();
|
||||||
|
@ -314,7 +337,7 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
||||||
} else {
|
} else {
|
||||||
if (!media) {
|
if (!media) {
|
||||||
textChannel.createMessage({
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -367,18 +390,23 @@ async function enqueue({guild_id, voice_id, text_id, url, type, addedBy, suppres
|
||||||
}
|
}
|
||||||
|
|
||||||
async function youtubeSearch(msg, str) {
|
async function youtubeSearch(msg, str) {
|
||||||
const {items} = await fetch(`${hf.config.piped_api}/search?q=${encodeURIComponent(str)}&filter=videos`).then((x) =>
|
const {items} = await fetch(
|
||||||
x.json()
|
`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) => ({
|
const selection = items.map((item) => {
|
||||||
value: "https://youtube.com" + item.url,
|
const title = parseHtmlEntities(item.snippet.title);
|
||||||
key: item.url.replace("/watch?v=", ""),
|
const channel = parseHtmlEntities(item.snippet.channelTitle);
|
||||||
display: `${parseHtmlEntities(item.title).substring(0, 99)}${parseHtmlEntities(item.title).length > 99 ? "…" : ""}`,
|
|
||||||
description: `from ${parseHtmlEntities(item.uploaderName).substring(0, 95)}${
|
return {
|
||||||
parseHtmlEntities(item.uploaderName).length > 95 ? "…" : ""
|
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 {
|
try {
|
||||||
return await selectionMessage(msg, "Search results:", selection);
|
return await selectionMessage(msg, "Search results:", selection);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue