New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

discord-player-youtubei

Package Overview
Dependencies
Maintainers
0
Versions
89
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

discord-player-youtubei - npm Package Compare versions

Comparing version 1.3.6-beta.0 to 1.3.6-beta.1

dist/Youtube-CgkKbU0o.d.ts

0

bin/index.js

@@ -0,0 +0,0 @@ #!/usr/bin/env node

3

dist/experimental/index.d.ts

@@ -5,4 +5,5 @@ import Innertube from 'youtubei.js';

import { Track } from 'discord-player';
import { Y as YoutubeiExtractor } from '../Youtube-Cl8NAitT.js';
import { Y as YoutubeiExtractor } from '../Youtube-CgkKbU0o.js';
import { PassThrough } from 'stream';
import 'undici';
import 'youtubei.js/dist/src/types';

@@ -9,0 +10,0 @@ import 'node:stream';

@@ -1,5 +0,7 @@

import { Y as YoutubeiExtractor } from './Youtube-Cl8NAitT.js';
export { A as AsyncTrackingContext, Q as QueryBridgeModes, R as RefreshInnertubeOptions, S as StreamOptions, T as TrustedTokenConfig, a as YoutubeiOptions } from './Youtube-Cl8NAitT.js';
import { Y as YoutubeiExtractor } from './Youtube-CgkKbU0o.js';
export { A as AsyncTrackingContext, P as PeerInfo, Q as QueryBridgeModes, R as RefreshInnertubeOptions, S as StreamOptions, T as TrustedTokenConfig, a as YoutubeiOptions } from './Youtube-CgkKbU0o.js';
import Innertube, { OAuth2Tokens } from 'youtubei.js';
import * as youtubei_js_agnostic from 'youtubei.js/agnostic';
import { Player } from 'discord-player';
import { ProxyAgent } from 'undici';
import { VideoInfo } from 'youtubei.js/dist/src/parser/youtube';

@@ -12,3 +14,2 @@ import { YTNode } from 'youtubei.js/dist/src/parser/helpers';

import { PassThrough } from 'stream';
import 'discord-player';
import 'node:stream';

@@ -128,4 +129,7 @@ import 'youtubei.js/dist/src/parser/nodes';

declare function defaultPeerUrlBuilder(url: string, id: string): string;
declare function defaultFetch(player: Player, input: RequestInfo | URL, init?: globalThis.RequestInit, proxy?: ProxyAgent): Promise<Response>;
declare function generateOauthTokens(): Promise<void>;
export { ChatMessageType, Errors, type If, LiveChatEvents, YoutubeiExtractor, generateOauthTokens, getLiveChat, getYoutubeiInstance, objectToToken, stream, tokenToObject, validateURL };
export { ChatMessageType, Errors, type If, LiveChatEvents, YoutubeiExtractor, defaultFetch, defaultPeerUrlBuilder, generateOauthTokens, getLiveChat, getYoutubeiInstance, objectToToken, stream, tokenToObject, validateURL };

@@ -37,2 +37,4 @@ "use strict";

YoutubeiExtractor: () => YoutubeiExtractor,
defaultFetch: () => defaultFetch,
defaultPeerUrlBuilder: () => defaultPeerUrlBuilder,
generateOauthTokens: () => generateOauthTokens,

@@ -47,3 +49,3 @@ getLiveChat: () => getLiveChat,

module.exports = __toCommonJS(lib_exports);
var import_youtubei6 = __toESM(require("youtubei.js"));
var import_youtubei7 = __toESM(require("youtubei.js"));

@@ -87,4 +89,3 @@ // lib/common/tokenUtils.ts

var import_discord_player = require("discord-player");
var import_youtubei3 = __toESM(require("youtubei.js"));
var import_undici = require("undici");
var import_youtubei6 = __toESM(require("youtubei.js"));
var import_extractor = require("@discord-player/extractor");

@@ -217,2 +218,242 @@

var import_node_async_hooks = require("async_hooks");
// lib/utils/index.ts
var import_undici = require("undici");
var import_youtubei5 = require("youtubei.js");
// lib/utils/live/LiveChat.ts
var import_tiny_typed_emitter = require("tiny-typed-emitter");
// lib/utils/live/LiveChatAuthor.ts
var LiveChatAuthor = class {
username;
url;
thumbnail;
verifiedChannel;
verifiedArtist;
isMod;
id;
raw;
constructor(author) {
this.username = author.name;
this.url = author.url;
this.thumbnail = author.best_thumbnail?.url ?? author.thumbnails[0].url;
this.verifiedChannel = author.is_verified || false;
this.verifiedArtist = author.is_verified_artist || false;
this.isMod = author.is_moderator || false;
this.id = author.id;
this.raw = author;
}
};
// lib/utils/live/LiveChatMessage.ts
var ChatMessageType = /* @__PURE__ */ ((ChatMessageType2) => {
ChatMessageType2[ChatMessageType2["Regular"] = 1] = "Regular";
ChatMessageType2[ChatMessageType2["Premium"] = 2] = "Premium";
ChatMessageType2[ChatMessageType2["PremiumSticker"] = 3] = "PremiumSticker";
return ChatMessageType2;
})(ChatMessageType || {});
var LiveChatMessage = class {
author;
type;
content;
timestamp;
constructor(chatUpdate, type) {
this.author = new LiveChatAuthor(
chatUpdate.author
);
this.type = type;
this.timestamp = chatUpdate.timestamp || Date.now();
if (chatUpdate.type === "LiveChatTextMessage" || chatUpdate.type === "LiveChatPaidMessage") {
this.content = chatUpdate.message.toString();
}
}
};
// lib/utils/live/LiveChat.ts
var import_youtubei3 = require("youtubei.js");
var LiveChatEvents = {
MessageCreate: "messageCreate",
StreamEnd: "streamEnd"
};
var LiveChat = class {
chat;
#eventEmitter = new import_tiny_typed_emitter.TypedEmitter();
#hasListener = {
[LiveChatEvents.MessageCreate]: false,
[LiveChatEvents.StreamEnd]: false
};
// this is scuffed but i cant access 'this' inside other non-arrow functions
chatUpdateHandler = (action) => {
if (action.is(import_youtubei3.YTNodes.AddChatItemAction)) {
const { item } = action.as(import_youtubei3.YTNodes.AddChatItemAction);
switch (item.type) {
case "LiveChatTextMessage": {
this.#eventEmitter.emit(
LiveChatEvents.MessageCreate,
new LiveChatMessage(item, 1 /* Regular */)
);
break;
}
case "LiveChatPaidMessage": {
this.#eventEmitter.emit(
LiveChatEvents.MessageCreate,
new LiveChatMessage(item, 2 /* Premium */)
);
break;
}
case "LiveChatPaidSticker": {
this.#eventEmitter.emit(
LiveChatEvents.MessageCreate,
new LiveChatMessage(item, 3 /* PremiumSticker */)
);
break;
}
default: {
break;
}
}
}
};
#chatEndHandler = () => {
this.#eventEmitter.emit(LiveChatEvents.StreamEnd);
};
constructor(chat) {
this.chat = chat;
}
on(event, handler) {
switch (event) {
case LiveChatEvents.MessageCreate: {
if (!this.#hasListener[LiveChatEvents.MessageCreate]) {
this.chat.on("chat-update", this.chatUpdateHandler);
this.#hasListener[LiveChatEvents.MessageCreate] = true;
}
this.#eventEmitter.on(event, handler);
}
case LiveChatEvents.StreamEnd: {
if (!this.#hasListener[LiveChatEvents.StreamEnd]) {
this.chat.on("end", this.#chatEndHandler);
}
}
}
}
destroy() {
if (this.#hasListener[LiveChatEvents.MessageCreate])
this.chat.off("chat-update", this.chatUpdateHandler);
if (this.#hasListener[LiveChatEvents.StreamEnd])
this.chat.off("end", this.#chatEndHandler);
this.chat.stop();
}
};
// lib/utils/live/getLiveChat.ts
var YOUTUBE_URL_REGEX = /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube(?:-nocookie)?\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|live\/|v\/)?)([\w\-]+)(\S+)?$/;
function parseYoutubeVideo(videoUrl) {
if (!YOUTUBE_URL_REGEX.test(videoUrl))
throw new Error("This is not a valid video URL");
const idExtractor = new URL(videoUrl);
let id = idExtractor.searchParams.get("v");
if (!id) id = videoUrl.split("/").at(-1)?.split("?").at(0);
return id;
}
async function getLiveChat(videoUrl, ext) {
const instance = YoutubeiExtractor.instance ?? ext;
if (!instance)
throw new Error("Invoked getLiveChat before player.extractors.register");
const innertube = instance.innerTube;
const videoId = parseYoutubeVideo(videoUrl);
const info = await innertube.getInfo(videoId);
if (!info.basic_info.is_live) return null;
const chat = info.getLiveChat();
chat.start();
return new LiveChat(chat);
}
// lib/utils/downloader/index.ts
var import_youtubei4 = __toESM(require("youtubei.js"));
var Errors = {
InvalidURL: new Error("Invalid URL: Expected a URL got a string instead"),
InvalidYTURL: new Error(
"Invalid YouTube URL: Expected a YouTube URL but got something else"
),
NoDownload: new Error("Unable to download video")
};
var YOUTUBE_REGEX = /^(https:\/\/(www\.)?youtu(\.be\/[A-Za-z0-9]{11}(.+)?|be\.com\/watch\?v=[A-Za-z0-9]{11}(&.+)?))/gm;
function validateURL(url) {
try {
return new URL(url);
} catch {
return false;
}
}
async function stream(url, skipStream, options, tube) {
const urlObj = validateURL(url);
if (!urlObj) throw Errors.InvalidURL;
if (!YOUTUBE_REGEX.test(url)) throw Errors.InvalidYTURL;
const vidId = urlObj.searchParams.get("v") || url.split("/").at(-1).split("?").at(0);
const yt = tube || await import_youtubei4.default.create({
retrieve_player: false
});
const info = await yt.getBasicInfo(vidId, "IOS");
const fmt = info.chooseFormat(
options || {
format: "mp4",
quality: "best",
type: "audio"
}
);
if (!fmt.url || !fmt.content_length) throw Errors.NoDownload;
const downloadedUrl = `${fmt.url}&cpn=${info.cpn}`;
const stream2 = skipStream ? null : createWebReadableStream(downloadedUrl, fmt.content_length, yt);
const readable = stream2 ? await createReadableFromWeb(stream2) : null;
return {
basicInfo: info.basic_info,
formatInfo: fmt,
stream: readable,
downloadedUrl
};
}
// lib/utils/index.ts
function defaultPeerUrlBuilder(url, id) {
return `${url}/${id}`;
}
function defaultFetch(player, input, init, proxy) {
let requestInit = {
...init
};
if (proxy) {
requestInit.dispatcher = proxy;
return import_youtubei5.Platform.shim.fetch(input, requestInit);
} else {
try {
const rotator = player.routePlanner?.getIP();
if (rotator?.ip) {
const dispatch = new import_undici.Agent({
localAddress: rotator.ip
});
requestInit.dispatcher = dispatch;
}
} catch {
}
return import_youtubei5.Platform.shim.fetch(input, requestInit);
}
}
// lib/common/peerDownloader.ts
function peerDownloader(id, peer) {
const peerUrl = typeof peer.parse === "function" ? peer.parse(peer.url, id) : defaultPeerUrlBuilder(peer.url, id);
return peerUrl;
}
// lib/common/extractVideoID.ts
function extractVideoId(vid) {
const YOUTUBE_REGEX2 = /^https:\/\/(www\.)?youtu(\.be\/[A-Za-z0-9]{11}(.+)?|be\.com\/watch\?v=[A-Za-z0-9]{11}(&.+)?)/;
if (!YOUTUBE_REGEX2.test(vid)) throw new Error("Invalid youtube url");
let id = new URL(vid).searchParams.get("v");
if (!id) id = vid.split("/").at(-1)?.split("?").at(0);
return id;
}
// lib/Extractor/Youtube.ts
var YoutubeiExtractor = class _YoutubeiExtractor extends import_discord_player.BaseExtractor {

@@ -230,3 +471,3 @@ static identifier = "com.retrouser955.discord-player.discord-player-youtubei";

const oauthKeys = this.innerTube.session.oauth.oauth2_tokens;
const newTube = await import_youtubei3.default.create({
const newTube = await import_youtubei6.default.create({
visitor_data: visitorData,

@@ -267,22 +508,5 @@ po_token: token.poToken,

}
this.innerTube = await import_youtubei3.default.create({
this.innerTube = await import_youtubei6.default.create({
...INNERTUBE_OPTIONS,
fetch: (input, init) => {
let requestInit = {
...init
};
try {
const rotator = this.context.player.routePlanner?.getIP();
if (rotator?.ip) {
this.context.player.debug(
`[EXT: discord-player-youtubei] APPLYING IP ROTATION CONFIG. ATTEMPTING TO USE ${rotator.ip}`
);
requestInit.dispatcher = new import_undici.Agent({
localAddress: rotator.ip
});
}
} catch {
}
return import_youtubei3.Platform.shim.fetch(input, requestInit);
}
fetch: (input, init) => defaultFetch(this.context.player, input, init, this.options.proxy)
});

@@ -299,2 +523,8 @@ if (typeof this.options.createStream === "function") {

async () => {
if (this.options.peers && this.options.peers.length > 0) {
return peerDownloader(
extractVideoId(q.url),
this.options.peers[Math.round(Math.random() * (this.options.peers.length - 1))]
);
}
return streamFromYT(q, this.innerTube, {

@@ -313,3 +543,3 @@ overrideDownloadOptions: this.options.overrideDownloadOptions

this.context.player.debug(
info.contents?.contents ? `Signed into YouTube using the name: ${info.contents.contents[0].is(import_youtubei3.YTNodes.AccountItem) ? info.contents.contents[0].as(import_youtubei3.YTNodes.AccountItem).account_name.text ?? "UNKNOWN ACCOUNT" : "UNKNOWN ACCOUNT"}` : `Signed into YouTube using the client name: ${this.innerTube.session.client_name}@${this.innerTube.session.client_version}`
info.contents?.contents ? `Signed into YouTube using the name: ${info.contents.contents[0].is(import_youtubei6.YTNodes.AccountItem) ? info.contents.contents[0].as(import_youtubei6.YTNodes.AccountItem).account_name.text ?? "UNKNOWN ACCOUNT" : "UNKNOWN ACCOUNT"}` : `Signed into YouTube using the client name: ${this.innerTube.session.client_name}@${this.innerTube.session.client_version}`
);

@@ -672,195 +902,2 @@ } catch (error) {

// lib/utils/live/LiveChat.ts
var import_tiny_typed_emitter = require("tiny-typed-emitter");
// lib/utils/live/LiveChatAuthor.ts
var LiveChatAuthor = class {
username;
url;
thumbnail;
verifiedChannel;
verifiedArtist;
isMod;
id;
raw;
constructor(author) {
this.username = author.name;
this.url = author.url;
this.thumbnail = author.best_thumbnail?.url ?? author.thumbnails[0].url;
this.verifiedChannel = author.is_verified || false;
this.verifiedArtist = author.is_verified_artist || false;
this.isMod = author.is_moderator || false;
this.id = author.id;
this.raw = author;
}
};
// lib/utils/live/LiveChatMessage.ts
var ChatMessageType = /* @__PURE__ */ ((ChatMessageType2) => {
ChatMessageType2[ChatMessageType2["Regular"] = 1] = "Regular";
ChatMessageType2[ChatMessageType2["Premium"] = 2] = "Premium";
ChatMessageType2[ChatMessageType2["PremiumSticker"] = 3] = "PremiumSticker";
return ChatMessageType2;
})(ChatMessageType || {});
var LiveChatMessage = class {
author;
type;
content;
timestamp;
constructor(chatUpdate, type) {
this.author = new LiveChatAuthor(
chatUpdate.author
);
this.type = type;
this.timestamp = chatUpdate.timestamp || Date.now();
if (chatUpdate.type === "LiveChatTextMessage" || chatUpdate.type === "LiveChatPaidMessage") {
this.content = chatUpdate.message.toString();
}
}
};
// lib/utils/live/LiveChat.ts
var import_youtubei4 = require("youtubei.js");
var LiveChatEvents = {
MessageCreate: "messageCreate",
StreamEnd: "streamEnd"
};
var LiveChat = class {
chat;
#eventEmitter = new import_tiny_typed_emitter.TypedEmitter();
#hasListener = {
[LiveChatEvents.MessageCreate]: false,
[LiveChatEvents.StreamEnd]: false
};
// this is scuffed but i cant access 'this' inside other non-arrow functions
chatUpdateHandler = (action) => {
if (action.is(import_youtubei4.YTNodes.AddChatItemAction)) {
const { item } = action.as(import_youtubei4.YTNodes.AddChatItemAction);
switch (item.type) {
case "LiveChatTextMessage": {
this.#eventEmitter.emit(
LiveChatEvents.MessageCreate,
new LiveChatMessage(item, 1 /* Regular */)
);
break;
}
case "LiveChatPaidMessage": {
this.#eventEmitter.emit(
LiveChatEvents.MessageCreate,
new LiveChatMessage(item, 2 /* Premium */)
);
break;
}
case "LiveChatPaidSticker": {
this.#eventEmitter.emit(
LiveChatEvents.MessageCreate,
new LiveChatMessage(item, 3 /* PremiumSticker */)
);
break;
}
default: {
break;
}
}
}
};
#chatEndHandler = () => {
this.#eventEmitter.emit(LiveChatEvents.StreamEnd);
};
constructor(chat) {
this.chat = chat;
}
on(event, handler) {
switch (event) {
case LiveChatEvents.MessageCreate: {
if (!this.#hasListener[LiveChatEvents.MessageCreate]) {
this.chat.on("chat-update", this.chatUpdateHandler);
this.#hasListener[LiveChatEvents.MessageCreate] = true;
}
this.#eventEmitter.on(event, handler);
}
case LiveChatEvents.StreamEnd: {
if (!this.#hasListener[LiveChatEvents.StreamEnd]) {
this.chat.on("end", this.#chatEndHandler);
}
}
}
}
destroy() {
if (this.#hasListener[LiveChatEvents.MessageCreate])
this.chat.off("chat-update", this.chatUpdateHandler);
if (this.#hasListener[LiveChatEvents.StreamEnd])
this.chat.off("end", this.#chatEndHandler);
this.chat.stop();
}
};
// lib/utils/live/getLiveChat.ts
var YOUTUBE_URL_REGEX = /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube(?:-nocookie)?\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|live\/|v\/)?)([\w\-]+)(\S+)?$/;
function parseYoutubeVideo(videoUrl) {
if (!YOUTUBE_URL_REGEX.test(videoUrl))
throw new Error("This is not a valid video URL");
const idExtractor = new URL(videoUrl);
let id = idExtractor.searchParams.get("v");
if (!id) id = videoUrl.split("/").at(-1)?.split("?").at(0);
return id;
}
async function getLiveChat(videoUrl, ext) {
const instance = YoutubeiExtractor.instance ?? ext;
if (!instance)
throw new Error("Invoked getLiveChat before player.extractors.register");
const innertube = instance.innerTube;
const videoId = parseYoutubeVideo(videoUrl);
const info = await innertube.getInfo(videoId);
if (!info.basic_info.is_live) return null;
const chat = info.getLiveChat();
chat.start();
return new LiveChat(chat);
}
// lib/utils/downloader/index.ts
var import_youtubei5 = __toESM(require("youtubei.js"));
var Errors = {
InvalidURL: new Error("Invalid URL: Expected a URL got a string instead"),
InvalidYTURL: new Error(
"Invalid YouTube URL: Expected a YouTube URL but got something else"
),
NoDownload: new Error("Unable to download video")
};
var YOUTUBE_REGEX = /^(https:\/\/(www\.)?youtu(\.be\/[A-Za-z0-9]{11}(.+)?|be\.com\/watch\?v=[A-Za-z0-9]{11}(&.+)?))/gm;
function validateURL(url) {
try {
return new URL(url);
} catch {
return false;
}
}
async function stream(url, skipStream, options, tube) {
const urlObj = validateURL(url);
if (!urlObj) throw Errors.InvalidURL;
if (!YOUTUBE_REGEX.test(url)) throw Errors.InvalidYTURL;
const vidId = urlObj.searchParams.get("v") || url.split("/").at(-1).split("?").at(0);
const yt = tube || await import_youtubei5.default.create({
retrieve_player: false
});
const info = await yt.getBasicInfo(vidId, "IOS");
const fmt = info.chooseFormat(
options || {
format: "mp4",
quality: "best",
type: "audio"
}
);
if (!fmt.url || !fmt.content_length) throw Errors.NoDownload;
const downloadedUrl = `${fmt.url}&cpn=${info.cpn}`;
const stream2 = skipStream ? null : createWebReadableStream(downloadedUrl, fmt.content_length, yt);
const readable = stream2 ? await createReadableFromWeb(stream2) : null;
return {
basicInfo: info.basic_info,
formatInfo: fmt,
stream: readable,
downloadedUrl
};
}
// lib/index.ts

@@ -875,3 +912,3 @@ var exit = (message, clean) => {

async function generateOauthTokens() {
const youtube = await import_youtubei6.default.create({
const youtube = await import_youtubei7.default.create({
retrieve_player: false

@@ -903,2 +940,4 @@ });

YoutubeiExtractor,
defaultFetch,
defaultPeerUrlBuilder,
generateOauthTokens,

@@ -905,0 +944,0 @@ getLiveChat,

{
"name": "discord-player-youtubei",
"version": "1.3.6-beta.0",
"version": "1.3.6-beta.1",
"description": "An unofficial package to test the use of youtubei in discord-player v6.",

@@ -34,8 +34,13 @@ "main": "dist/index.js",

},
"bin": "bin/index.js",
"bin": {
"discord-player-youtubei": "bin/index.js"
},
"packageManager": "yarn@4.3.1",
"exports": {
".": "./dist/index.js",
"./experimental": "./dist/experimental/index.js"
"./experimental": {
"types": "./dist/experimental/index.d.ts",
"default": "./dist/experimental/index.js"
}
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc