Skip to content

Commit

Permalink
"My own" ytdl (thanks @konsumer)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSainEyereg committed Jul 13, 2024
1 parent 3713579 commit de5fc30
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 109 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"dependencies": {
"@discordjs/opus": "^0.9.0",
"@discordjs/voice": "^0.17.0",
"@distube/ytdl-core": "^4.13.5",
"discord.js": "^14.11.0",
"dotenv": "^16.3.1",
"ffmpeg-static": "^5.2.0",
Expand Down
2 changes: 2 additions & 0 deletions src/commands/music/Play.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export default class Play extends Command {
thumbnailUrl: info.video_details.thumbnails[0].url,
duration: info.video_details.durationInSec,
url: info.video_details.url,
id: info.video_details.id,
requestedBy: member
};
queue.list.push(song);
Expand All @@ -138,6 +139,7 @@ export default class Play extends Command {
thumbnailUrl: info.thumbnails[0].url,
duration: info.durationInSec,
url: info.url,
id: info.id,
requestedBy: member
})));

Expand Down
19 changes: 3 additions & 16 deletions src/components/MusicQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,18 @@ import { type VoiceChannel, BaseGuildTextChannel, BaseGuildVoiceChannel, Guild,

import fetch from "node-fetch";
import play from "play-dl";
import ytdl, { Filter } from "@distube/ytdl-core";
import { YMApi } from "ym-api";

import config from "../config";
import { LoopMode, MusicServices } from "../enums";
import { Song } from "../interfaces/music";
import { critical } from "./messages";
import { cookieHeaderParser } from "./utils";
import { streamYTAudio } from "./ytdl";

const { music: { youtube, spotify, yandex, volumeDefault } } = config;
const wait = promisify(setTimeout);
const ymApi = new YMApi();

const ytdlOptions = {
filter: "audioonly" as Filter,
highWaterMark: 1 << 62,
liveBuffer: 1 << 62,
dlChunkSize: 0,
quality: "highestaudio",
// requestOptions: {
// ...youtube.cookie && { headers: youtube }
// }
agent: ytdl.createAgent(cookieHeaderParser(youtube.cookie))
};

export default class MusicQueue {
guild: Guild;
textChannel: BaseGuildTextChannel;
Expand Down Expand Up @@ -179,7 +166,7 @@ export default class MusicQueue {
if (song.duration > 61 * 60)
throw new Error("Sorry. Due to some technical limitations, I can't play tracks longer than 60 minutes");

stream = ytdl(song.url, ytdlOptions);
stream = await streamYTAudio(song.id as string);
}
if (song.service === MusicServices.SoundCloud) {
const pdl = await play.stream(song.url);
Expand All @@ -195,7 +182,7 @@ export default class MusicQueue {
if (res[0].durationInSec > 61 * 60)
throw new Error("Sorry. Due to some technical limitations, I can't play tracks longer than 60 minutes");

stream = ytdl(res[0].url, ytdlOptions);
stream = await streamYTAudio(res[0].id as string);
}
if (song.service === MusicServices.Yandex) {
const downloadInfo = await ymApi.getTrackDownloadInfo(song.id as number);
Expand Down
71 changes: 71 additions & 0 deletions src/components/ytdl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Readable } from "node:stream";
import fetch from "node-fetch";

export enum AudioQuality {
Low = "AUDIO_QUALITY_LOW",
Medium = "AUDIO_QUALITY_MEDIUM",
High = "AUDIO_QUALITY_HIGH"
}

export interface VideoInfo {
streamingData: {
expiresInSeconds: string;
adaptiveFormats: {
url: string;
mimeType: string;
bitrate: number;
width?: number;
height?: number;
fps?: number;
quality: string;
audioQuality?: string;
qualityLabel?: string;
audioSampleRate?: string;
}[];
};
}

export async function getYTInfo(videoId: string): Promise<VideoInfo> {
// hard-coded from https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/youtube.py
const apiKey = "AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc";

const headers = {
"X-YouTube-Client-Name": "5",
"X-YouTube-Client-Version": "19.09.3",
Origin: "https://www.youtube.com",
"User-Agent": "com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)",
"content-type": "application/json"
};

const b = {
context: {
client: {
clientName: "IOS",
clientVersion: "19.09.3",
deviceModel: "iPhone14,3",
userAgent: "com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)",
hl: "en",
timeZone: "UTC",
utcOffsetMinutes: 0
}
},
videoId,
playbackContext: { contentPlaybackContext: { html5Preference: "HTML5_PREF_WANTS" } },
contentCheckOk: true,
racyCheckOk: true
};

return fetch(`https://www.youtube.com/youtubei/v1/player?key${apiKey}&prettyPrint=false`, { method: "POST", body: JSON.stringify(b), headers }).then(r => r.json());
}

export async function streamYTAudio(videoId: string, quality: AudioQuality = AudioQuality.Medium) {
const info = await getYTInfo(videoId);
const audio = info.streamingData.adaptiveFormats.find(f => f.audioQuality === quality);

if (!audio)
throw new Error(`No audio found for quality ${quality}`);

const { body } = await fetch(audio.url);

return Readable.from(body);
}
92 changes: 0 additions & 92 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,6 @@
tslib "^2.5.0"
ws "^8.13.0"

"@distube/ytdl-core@^4.13.5":
version "4.13.5"
resolved "https://registry.yarnpkg.com/@distube/ytdl-core/-/ytdl-core-4.13.5.tgz#f9bacaa43225953d0ccd2a682a31d9dbbc378973"
integrity sha512-g+4UJIR/auAJbia7iB0aWvaJDbs22P53NySWa47b1NT4xMTDJYguxHFArPrvRkcJrb/AgKjv/XoSZGghpL0CJA==
dependencies:
http-cookie-agent "^6.0.5"
m3u8stream "^0.8.6"
miniget "^4.2.3"
sax "^1.4.1"
tough-cookie "^4.1.4"
undici "^6.19.2"

"@eslint-community/eslint-utils@^4.2.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
Expand Down Expand Up @@ -420,13 +408,6 @@ agent-base@6:
dependencies:
debug "4"

agent-base@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317"
integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==
dependencies:
debug "^4.3.4"

ajv@^6.10.0, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
Expand Down Expand Up @@ -1045,13 +1026,6 @@ has-unicode@^2.0.1:
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==

http-cookie-agent@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/http-cookie-agent/-/http-cookie-agent-6.0.5.tgz#23b490439464424a689d80ea7f3a560a4a893ab8"
integrity sha512-sfZ8fDgDP3B1YB+teqSnAK1aPgBu8reUUGxSsndP2XnYN6cM29EURXWXZqQQiaRdor3B4QjpkUNfv21syaO4DA==
dependencies:
agent-base "^7.1.1"

http-response-object@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810"
Expand Down Expand Up @@ -1213,14 +1187,6 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"

m3u8stream@^0.8.6:
version "0.8.6"
resolved "https://registry.yarnpkg.com/m3u8stream/-/m3u8stream-0.8.6.tgz#0d6de4ce8ee69731734e6b616e7b05dd9d9a55b1"
integrity sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==
dependencies:
miniget "^4.2.2"
sax "^1.2.4"

make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
Expand Down Expand Up @@ -1258,11 +1224,6 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.52.0"

miniget@^4.2.2, miniget@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/miniget/-/miniget-4.2.3.tgz#3707a24c7c11c25d359473291638ab28aab349bd"
integrity sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==

minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
Expand Down Expand Up @@ -1486,11 +1447,6 @@ progress@^2.0.3:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==

psl@^1.1.33:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==

pstree.remy@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
Expand All @@ -1501,16 +1457,6 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==

punycode@^2.1.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==

querystringify@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==

queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
Expand Down Expand Up @@ -1539,11 +1485,6 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"

requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==

resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
Expand Down Expand Up @@ -1578,11 +1519,6 @@ sax@>=0.6.0:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==

sax@^1.2.4, sax@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f"
integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==

semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
Expand Down Expand Up @@ -1741,16 +1677,6 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"

tough-cookie@^4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36"
integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==
dependencies:
psl "^1.1.33"
punycode "^2.1.1"
universalify "^0.2.0"
url-parse "^1.5.3"

tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
Expand Down Expand Up @@ -1836,16 +1762,6 @@ undici@^5.22.0:
dependencies:
busboy "^1.6.0"

undici@^6.19.2:
version "6.19.2"
resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.2.tgz#231bc5de78d0dafb6260cf454b294576c2f3cd31"
integrity sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==

universalify@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==

unws@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/unws/-/unws-0.2.3.tgz#c9152a542e3e30f13be006d68caec3f3e2e08856"
Expand All @@ -1858,14 +1774,6 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"

url-parse@^1.5.3:
version "1.5.10"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"

util-deprecate@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
Expand Down

0 comments on commit de5fc30

Please sign in to comment.