Comparing version 0.0.14 to 0.0.15
@@ -14,3 +14,3 @@ /// <reference types="node" /> | ||
loadFurhter(): Promise<any>; | ||
getByType(type: typeof Video | typeof Playlist | typeof Channel): (Video | Channel | Playlist)[]; | ||
getByType(type: typeof Video | typeof Playlist | typeof Channel): (Video | Playlist | Channel)[]; | ||
} |
@@ -8,3 +8,3 @@ import { Channel } from "../interfaces/Channel"; | ||
declare function getNumberFromText(str: string): number; | ||
declare function processRendererItems(arr: Array<any>, httpclient: WrappedHTTPClient): (Channel | Video | Playlist | undefined)[]; | ||
declare function processRendererItems(arr: Array<any>, httpclient: WrappedHTTPClient): (Video | Channel | Playlist | undefined)[]; | ||
declare const _default: { | ||
@@ -11,0 +11,0 @@ recursiveSearchForPair: typeof recursiveSearchForPair; |
@@ -77,2 +77,7 @@ "use strict"; | ||
} | ||
else if (elem.gridChannelRenderer) { | ||
var channel = new Channel_1.Channel(httpclient); | ||
channel.fromGridChannelRenderer(elem.gridChannelRenderer); | ||
return channel; | ||
} | ||
else if (elem.playlistRenderer) { | ||
@@ -79,0 +84,0 @@ var playlist = new Playlist_1.Playlist(httpclient); |
import { WrappedHTTPClient } from "../WrappedHTTPClient"; | ||
import { ChannelBadge } from "./ChannelBadge"; | ||
import { Thumbnail } from "./Thumbnail"; | ||
import { ChannelLink } from "./ChannelLink"; | ||
import { ContinuatedList } from "../main"; | ||
export declare class Channel { | ||
@@ -8,8 +10,17 @@ #private; | ||
title?: string; | ||
description?: string; | ||
shortDescription?: string; | ||
badges?: Array<ChannelBadge>; | ||
thumbnails?: Array<Thumbnail>; | ||
banners?: Array<Thumbnail>; | ||
mobileBanners?: Array<Thumbnail>; | ||
tvBanners?: Array<Thumbnail>; | ||
videoCount?: number; | ||
subscribed?: boolean; | ||
subscriberCount?: number; | ||
country?: string; | ||
viewCount?: number; | ||
joinDate?: Date; | ||
channelLinks?: Array<ChannelLink>; | ||
otherChannels?: Array<Channel>; | ||
httpclient: WrappedHTTPClient; | ||
@@ -23,4 +34,9 @@ constructor(httpclient: WrappedHTTPClient); | ||
fromPlaylistVideoRendererBylineText(obj: any): void; | ||
fromGridChannelRenderer(obj: any): void; | ||
loadAll(): Promise<void>; | ||
loadDetailsFromAboutPage(): Promise<void>; | ||
loadDetailsFromChannelsPages(): Promise<void>; | ||
getUploadList(): ContinuatedList; | ||
subscribe(): Promise<boolean>; | ||
unsubscribe(): Promise<boolean>; | ||
} |
@@ -16,3 +16,3 @@ "use strict"; | ||
}; | ||
var _Channel_instances, _Channel_cleanup; | ||
var _Channel_instances, _Channel_parseC4FromHeader, _Channel_parseOwnerBadges, _Channel_cleanup; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -23,2 +23,3 @@ exports.Channel = void 0; | ||
const HTTPClient_1 = require("./HTTPClient"); | ||
const main_1 = require("../main"); | ||
class Channel { | ||
@@ -36,16 +37,5 @@ constructor(httpclient) { | ||
const ownerBadgeContainer = helpers_1.default.recursiveSearchForKey("ownerBadges", obj); | ||
if (ownerBadgeContainer.length > 0) { | ||
const badgeRenderers = helpers_1.default.recursiveSearchForKey("metadataBadgeRenderer", ownerBadgeContainer); | ||
if (badgeRenderers.length > 0) { | ||
this.badges = new Array(); | ||
for (const badgeRenderer of badgeRenderers) { | ||
this.badges.push({ | ||
name: helpers_1.default.recursiveSearchForKey("label", badgeRenderer)[0], | ||
icon: helpers_1.default.recursiveSearchForKey("iconType", badgeRenderer)[0], | ||
}); | ||
} | ||
} | ||
} | ||
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_parseOwnerBadges).call(this, ownerBadgeContainer); | ||
const ownerThumbnailContainer = helpers_1.default.recursiveSearchForKey("channelThumbnailWithLinkRenderer", obj)[0]; | ||
if (ownerBadgeContainer) { | ||
if (ownerThumbnailContainer) { | ||
this.thumbnails = helpers_1.default.recursiveSearchForKey("thumbnails", ownerThumbnailContainer)[0]; | ||
@@ -74,14 +64,3 @@ } | ||
const ownerBadgeContainer = helpers_1.default.recursiveSearchForKey("ownerBadges", obj); | ||
if (ownerBadgeContainer.length > 0) { | ||
const badgeRenderers = helpers_1.default.recursiveSearchForKey("metadataBadgeRenderer", ownerBadgeContainer); | ||
if (badgeRenderers.length > 0) { | ||
this.badges = new Array(); | ||
for (const badgeRenderer of badgeRenderers) { | ||
this.badges.push({ | ||
name: helpers_1.default.recursiveSearchForKey("label", badgeRenderer)[0], | ||
icon: helpers_1.default.recursiveSearchForKey("iconType", badgeRenderer)[0], | ||
}); | ||
} | ||
} | ||
} | ||
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_parseOwnerBadges).call(this, ownerBadgeContainer); | ||
this.subscribed = helpers_1.default.recursiveSearchForKey("subscribed", obj)[0]; | ||
@@ -128,2 +107,108 @@ __classPrivateFieldGet(this, _Channel_instances, "m", _Channel_cleanup).call(this); | ||
} | ||
fromGridChannelRenderer(obj) { | ||
this.channelId = helpers_1.default.recursiveSearchForKey("channelId", obj).join(""); | ||
this.subscribed = helpers_1.default.recursiveSearchForKey("subscribed", obj)[0]; | ||
const titleContainer = helpers_1.default.recursiveSearchForKey("title", obj)[0]; | ||
if (titleContainer) { | ||
this.title = helpers_1.default.recursiveSearchForKey("simpleText", titleContainer).join(""); | ||
} | ||
const thumbnailContainer = helpers_1.default.recursiveSearchForKey("thumbnails", obj)[0]; | ||
if (thumbnailContainer) { | ||
this.thumbnails = thumbnailContainer; | ||
} | ||
} | ||
loadAll() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this.loadDetailsFromAboutPage(); | ||
yield this.loadDetailsFromChannelsPages(); | ||
}); | ||
} | ||
loadDetailsFromAboutPage() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const channelAbout = yield this.httpclient.request({ | ||
method: HTTPClient_1.HTTPRequestMethod.POST, | ||
url: constants_1.ENDPOINT_BROWSE, | ||
data: { | ||
browseId: this.channelId, | ||
params: channelBrowseType.DETAILS | ||
} | ||
}); | ||
const aboutJSON = yield JSON.parse(channelAbout.data); | ||
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_parseC4FromHeader).call(this, aboutJSON); | ||
const aboutRenderer = helpers_1.default.recursiveSearchForKey("channelAboutFullMetadataRenderer", aboutJSON); | ||
const descriptionContainer = helpers_1.default.recursiveSearchForKey("description", aboutRenderer)[0]; | ||
if (descriptionContainer) | ||
this.description = helpers_1.default.recursiveSearchForKey("simpleText", descriptionContainer).join(""); | ||
const countryContainer = helpers_1.default.recursiveSearchForKey("country", aboutRenderer)[0]; | ||
if (countryContainer) | ||
this.country = helpers_1.default.recursiveSearchForKey("simpleText", countryContainer).join(""); | ||
const joinDateContainer = helpers_1.default.recursiveSearchForKey("joinedDateText", aboutRenderer)[0]; | ||
if (joinDateContainer) { | ||
const dateParts = helpers_1.default.recursiveSearchForKey("text", joinDateContainer).join("").split(" "); | ||
dateParts.shift(); | ||
this.joinDate = new Date(dateParts.join(", ")); | ||
} | ||
const viewCountContainer = helpers_1.default.recursiveSearchForKey("viewCountText", aboutRenderer)[0]; | ||
if (viewCountContainer) | ||
this.viewCount = helpers_1.default.getNumberFromText(helpers_1.default.recursiveSearchForKey("simpleText", viewCountContainer).join("")); | ||
const links = helpers_1.default.recursiveSearchForKey("primaryLinks", aboutRenderer)[0]; | ||
if (links) { | ||
this.channelLinks = links.map((link) => { | ||
var linkObj = { | ||
title: helpers_1.default.recursiveSearchForKey("simpleText", link).join(""), | ||
url: helpers_1.default.recursiveSearchForKey("url", helpers_1.default.recursiveSearchForKey("navigationEndpoint", link)[0])[0], | ||
thumbnails: helpers_1.default.recursiveSearchForKey("thumbnails", link)[0] | ||
}; | ||
if (linkObj.url && linkObj.url.startsWith("https://www.youtube.com/redirect?")) { | ||
linkObj.url = new URL(linkObj.url).searchParams.get("q"); | ||
} | ||
return linkObj; | ||
}); | ||
} | ||
}); | ||
} | ||
loadDetailsFromChannelsPages() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const channelChannels = yield this.httpclient.request({ | ||
method: HTTPClient_1.HTTPRequestMethod.POST, | ||
url: constants_1.ENDPOINT_BROWSE, | ||
data: { | ||
browseId: this.channelId, | ||
params: channelBrowseType.CHANNELS | ||
} | ||
}); | ||
const channelsJSON = yield JSON.parse(channelChannels.data); | ||
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_parseC4FromHeader).call(this, channelsJSON); | ||
let channelsTabRenderer = helpers_1.default.recursiveSearchForKey("tabRenderer", channelsJSON); | ||
channelsTabRenderer = channelsTabRenderer.find((a) => a.title.toLowerCase() == "channels"); | ||
let channelItems = helpers_1.default.recursiveSearchForKey("items", channelsTabRenderer); | ||
if (channelItems.length > 0) { | ||
channelItems = channelItems.flat(1); | ||
this.otherChannels = helpers_1.default.processRendererItems(channelItems, this.httpclient); | ||
} | ||
}); | ||
} | ||
getUploadList() { | ||
return new main_1.ContinuatedList({ | ||
method: HTTPClient_1.HTTPRequestMethod.POST, | ||
url: constants_1.ENDPOINT_BROWSE, | ||
data: { | ||
browseId: this.channelId, | ||
params: channelBrowseType.VIDEOS | ||
} | ||
}, (data) => { | ||
let videosTabRenderer = helpers_1.default.recursiveSearchForKey("tabRenderer", data); | ||
videosTabRenderer = videosTabRenderer.find((a) => a.title.toLowerCase() == "videos"); | ||
if (videosTabRenderer) { | ||
const gridRendererContainer = helpers_1.default.recursiveSearchForKey("gridRenderer", videosTabRenderer)[0]; | ||
if (gridRendererContainer) { | ||
const items = helpers_1.default.recursiveSearchForKey("items", gridRendererContainer)[0]; | ||
return items; | ||
} | ||
} | ||
else { | ||
return helpers_1.default.recursiveSearchForKey("continuationItems", data)[0]; | ||
} | ||
}, this.httpclient, true); | ||
} | ||
subscribe() { | ||
@@ -165,3 +250,27 @@ return __awaiter(this, void 0, void 0, function* () { | ||
exports.Channel = Channel; | ||
_Channel_instances = new WeakSet(), _Channel_cleanup = function _Channel_cleanup() { | ||
_Channel_instances = new WeakSet(), _Channel_parseC4FromHeader = function _Channel_parseC4FromHeader(obj) { | ||
const headerContainer = helpers_1.default.recursiveSearchForKey("c4TabbedHeaderRenderer", obj)[0]; | ||
if (headerContainer) { | ||
this.title = headerContainer.title; | ||
this.subscribed = helpers_1.default.recursiveSearchForKey("subscribed", headerContainer)[0]; | ||
__classPrivateFieldGet(this, _Channel_instances, "m", _Channel_parseOwnerBadges).call(this, helpers_1.default.recursiveSearchForKey("badges", headerContainer)); | ||
const subscriberCountContainer = helpers_1.default.recursiveSearchForKey("subscriberCountText", headerContainer)[0]; | ||
if (subscriberCountContainer) | ||
this.subscriberCount = helpers_1.default.getNumberFromText(helpers_1.default.recursiveSearchForKey("simpleText", subscriberCountContainer).join("")); | ||
this.thumbnails = helpers_1.default.recursiveSearchForKey("thumbnails", headerContainer.avatar)[0]; | ||
this.banners = helpers_1.default.recursiveSearchForKey("thumbnails", headerContainer.banner)[0]; | ||
this.mobileBanners = helpers_1.default.recursiveSearchForKey("thumbnails", headerContainer.mobileBanner)[0]; | ||
this.tvBanners = helpers_1.default.recursiveSearchForKey("thumbnails", headerContainer.tvBanner)[0]; | ||
} | ||
}, _Channel_parseOwnerBadges = function _Channel_parseOwnerBadges(ownerBadgeContainer) { | ||
if (ownerBadgeContainer.length > 0) { | ||
const badgeRenderers = helpers_1.default.recursiveSearchForKey("metadataBadgeRenderer", ownerBadgeContainer); | ||
if (badgeRenderers.length > 0) { | ||
this.badges = badgeRenderers.map((badgeRenderer) => ({ | ||
name: helpers_1.default.recursiveSearchForKey("label", badgeRenderer)[0], | ||
icon: helpers_1.default.recursiveSearchForKey("iconType", badgeRenderer)[0], | ||
})); | ||
} | ||
} | ||
}, _Channel_cleanup = function _Channel_cleanup() { | ||
if (this.thumbnails) | ||
@@ -173,1 +282,7 @@ this.thumbnails.forEach((a) => { | ||
}; | ||
var channelBrowseType; | ||
(function (channelBrowseType) { | ||
channelBrowseType["DETAILS"] = "EgVhYm91dA%3D%3D"; | ||
channelBrowseType["CHANNELS"] = "EghjaGFubmVscw%3D%3D"; | ||
channelBrowseType["VIDEOS"] = "EgZ2aWRlb3M%3D"; | ||
})(channelBrowseType || (channelBrowseType = {})); |
@@ -10,2 +10,3 @@ import { Authenticator } from "./Authenticator"; | ||
import { Playlist } from "./interfaces/Playlist"; | ||
import { Channel } from "./main"; | ||
export default class IYoutube { | ||
@@ -21,2 +22,3 @@ #private; | ||
getPlaylist(playlistId: string): Promise<Playlist>; | ||
getChannel(channelId: string): Promise<Channel>; | ||
getExplorer(): Explorer; | ||
@@ -23,0 +25,0 @@ getUser(): User; |
@@ -31,2 +31,3 @@ "use strict"; | ||
const constants_1 = require("./constants"); | ||
const main_1 = require("./main"); | ||
class IYoutube { | ||
@@ -67,2 +68,11 @@ constructor(httpClient, storageAdapater) { | ||
} | ||
getChannel(channelId) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.throwErrorIfNotReady(); | ||
var ch = new main_1.Channel(this.wrappedHttpClient); | ||
ch.channelId = channelId; | ||
yield ch.loadAll(); | ||
return ch; | ||
}); | ||
} | ||
getExplorer() { | ||
@@ -69,0 +79,0 @@ return __classPrivateFieldGet(this, _IYoutube_explorer, "f"); |
{ | ||
"name": "iyoutube", | ||
"version": "0.0.14", | ||
"version": "0.0.15", | ||
"description": "The ultimate unofficial YouTube API Client for Javascript", | ||
@@ -9,2 +9,3 @@ "main": "output/main.js", | ||
"test": "npm run compile && node test/test.js", | ||
"testignored": "npm run compile && node test/testIgnored.js", | ||
"compile": "tsc", | ||
@@ -11,0 +12,0 @@ "simplepublish": "npm version patch -m 'Fix' && npm publish --access=public ./ && git push" |
@@ -81,2 +81,6 @@ import { Channel } from "../interfaces/Channel"; | ||
return channel; | ||
} else if(elem.gridChannelRenderer) { | ||
var channel = new Channel(httpclient); | ||
channel.fromGridChannelRenderer(elem.gridChannelRenderer); | ||
return channel; | ||
} | ||
@@ -83,0 +87,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { ENDPOINT_SUBSCRIBE, ENDPOINT_UNSUBSCRIBE } from "../constants"; | ||
import { ENDPOINT_BROWSE, ENDPOINT_SUBSCRIBE, ENDPOINT_UNSUBSCRIBE } from "../constants"; | ||
import helpers from "../fetchers/helpers" | ||
@@ -7,2 +7,4 @@ import { WrappedHTTPClient } from "../WrappedHTTPClient"; | ||
import { Thumbnail } from "./Thumbnail"; | ||
import { ChannelLink } from "./ChannelLink"; | ||
import { ContinuatedList } from "../main"; | ||
@@ -12,8 +14,17 @@ export class Channel { | ||
title?: string; | ||
description?: string; | ||
shortDescription?: string; | ||
badges?: Array<ChannelBadge>; | ||
thumbnails?: Array<Thumbnail>; | ||
banners?: Array<Thumbnail>; | ||
mobileBanners?: Array<Thumbnail>; | ||
tvBanners?: Array<Thumbnail>; | ||
videoCount?: number; | ||
subscribed?: boolean; | ||
subscriberCount?: number; | ||
country?: string; | ||
viewCount?: number; | ||
joinDate?: Date; | ||
channelLinks?: Array<ChannelLink>; | ||
otherChannels?: Array<Channel>; | ||
@@ -34,17 +45,6 @@ httpclient: WrappedHTTPClient; | ||
const ownerBadgeContainer = helpers.recursiveSearchForKey("ownerBadges", obj); | ||
if(ownerBadgeContainer.length > 0) { | ||
const badgeRenderers = helpers.recursiveSearchForKey("metadataBadgeRenderer", ownerBadgeContainer); | ||
if(badgeRenderers.length > 0) { | ||
this.badges = new Array(); | ||
for(const badgeRenderer of badgeRenderers) { | ||
this.badges.push({ | ||
name: helpers.recursiveSearchForKey("label", badgeRenderer)[0], | ||
icon: helpers.recursiveSearchForKey("iconType", badgeRenderer)[0], | ||
}); | ||
} | ||
} | ||
} | ||
this.#parseOwnerBadges(ownerBadgeContainer); | ||
const ownerThumbnailContainer = helpers.recursiveSearchForKey("channelThumbnailWithLinkRenderer", obj)[0]; | ||
if(ownerBadgeContainer) { | ||
if(ownerThumbnailContainer) { | ||
this.thumbnails = helpers.recursiveSearchForKey("thumbnails", ownerThumbnailContainer)[0]; | ||
@@ -81,14 +81,3 @@ } | ||
const ownerBadgeContainer = helpers.recursiveSearchForKey("ownerBadges", obj); | ||
if(ownerBadgeContainer.length > 0) { | ||
const badgeRenderers = helpers.recursiveSearchForKey("metadataBadgeRenderer", ownerBadgeContainer); | ||
if(badgeRenderers.length > 0) { | ||
this.badges = new Array(); | ||
for(const badgeRenderer of badgeRenderers) { | ||
this.badges.push({ | ||
name: helpers.recursiveSearchForKey("label", badgeRenderer)[0], | ||
icon: helpers.recursiveSearchForKey("iconType", badgeRenderer)[0], | ||
}); | ||
} | ||
} | ||
} | ||
this.#parseOwnerBadges(ownerBadgeContainer); | ||
@@ -145,2 +134,162 @@ this.subscribed = helpers.recursiveSearchForKey("subscribed", obj)[0]; | ||
fromGridChannelRenderer(obj: any) { | ||
this.channelId = helpers.recursiveSearchForKey("channelId", obj).join(""); | ||
this.subscribed = helpers.recursiveSearchForKey("subscribed", obj)[0]; | ||
const titleContainer = helpers.recursiveSearchForKey("title", obj)[0]; | ||
if(titleContainer) { | ||
this.title = helpers.recursiveSearchForKey("simpleText", titleContainer).join(""); | ||
} | ||
const thumbnailContainer = helpers.recursiveSearchForKey("thumbnails", obj)[0]; | ||
if(thumbnailContainer) { | ||
this.thumbnails = thumbnailContainer; | ||
} | ||
} | ||
async loadAll() { | ||
await this.loadDetailsFromAboutPage(); | ||
await this.loadDetailsFromChannelsPages(); | ||
} | ||
async loadDetailsFromAboutPage() { | ||
const channelAbout = await this.httpclient.request({ | ||
method: HTTPRequestMethod.POST, | ||
url: ENDPOINT_BROWSE, | ||
data: { | ||
browseId: this.channelId, | ||
params: channelBrowseType.DETAILS | ||
} | ||
}); | ||
const aboutJSON = await JSON.parse(channelAbout.data); | ||
this.#parseC4FromHeader(aboutJSON); | ||
const aboutRenderer = helpers.recursiveSearchForKey("channelAboutFullMetadataRenderer", aboutJSON); | ||
const descriptionContainer = helpers.recursiveSearchForKey("description", aboutRenderer)[0]; | ||
if(descriptionContainer) | ||
this.description = helpers.recursiveSearchForKey("simpleText", descriptionContainer).join(""); | ||
const countryContainer = helpers.recursiveSearchForKey("country", aboutRenderer)[0]; | ||
if(countryContainer) | ||
this.country = helpers.recursiveSearchForKey("simpleText", countryContainer).join(""); | ||
const joinDateContainer = helpers.recursiveSearchForKey("joinedDateText", aboutRenderer)[0]; | ||
if(joinDateContainer) { | ||
const dateParts = helpers.recursiveSearchForKey("text", joinDateContainer).join("").split(" "); | ||
dateParts.shift(); //Remove the 'Joined' Prefix | ||
this.joinDate = new Date(dateParts.join(", ")); | ||
} | ||
const viewCountContainer = helpers.recursiveSearchForKey("viewCountText", aboutRenderer)[0]; | ||
if(viewCountContainer) | ||
this.viewCount = helpers.getNumberFromText(helpers.recursiveSearchForKey("simpleText", viewCountContainer).join("")); | ||
const links = helpers.recursiveSearchForKey("primaryLinks", aboutRenderer)[0]; | ||
if(links) { | ||
this.channelLinks = links.map((link:any) => { | ||
var linkObj:ChannelLink = { | ||
title: helpers.recursiveSearchForKey("simpleText", link).join(""), | ||
url: helpers.recursiveSearchForKey("url", helpers.recursiveSearchForKey("navigationEndpoint", link)[0])[0], | ||
thumbnails: helpers.recursiveSearchForKey("thumbnails", link)[0] | ||
} | ||
//Resolve YouTube Redirect Links | ||
if(linkObj.url && linkObj.url.startsWith("https://www.youtube.com/redirect?")) { | ||
linkObj.url = new URL(linkObj.url).searchParams.get("q") as string; | ||
} | ||
return linkObj; | ||
}); | ||
} | ||
} | ||
async loadDetailsFromChannelsPages() { | ||
const channelChannels = await this.httpclient.request({ | ||
method: HTTPRequestMethod.POST, | ||
url: ENDPOINT_BROWSE, | ||
data: { | ||
browseId: this.channelId, | ||
params: channelBrowseType.CHANNELS | ||
} | ||
}); | ||
const channelsJSON = await JSON.parse(channelChannels.data); | ||
this.#parseC4FromHeader(channelsJSON); | ||
let channelsTabRenderer = helpers.recursiveSearchForKey("tabRenderer", channelsJSON); | ||
channelsTabRenderer = channelsTabRenderer.find((a:any) => a.title.toLowerCase() == "channels"); | ||
let channelItems = helpers.recursiveSearchForKey("items", channelsTabRenderer); | ||
if(channelItems.length > 0) { | ||
channelItems = channelItems.flat(1); //Join all Arrays of Items together (for multiple headings) | ||
this.otherChannels = helpers.processRendererItems(channelItems, this.httpclient) as Array<Channel>; | ||
} | ||
} | ||
#parseC4FromHeader(obj:any) { | ||
const headerContainer = helpers.recursiveSearchForKey("c4TabbedHeaderRenderer", obj)[0]; | ||
if(headerContainer) { | ||
this.title = headerContainer.title; | ||
this.subscribed = helpers.recursiveSearchForKey("subscribed", headerContainer)[0]; | ||
this.#parseOwnerBadges(helpers.recursiveSearchForKey("badges", headerContainer)); | ||
const subscriberCountContainer = helpers.recursiveSearchForKey("subscriberCountText", headerContainer)[0]; | ||
if(subscriberCountContainer) | ||
this.subscriberCount = helpers.getNumberFromText(helpers.recursiveSearchForKey("simpleText", subscriberCountContainer).join("")); | ||
this.thumbnails = helpers.recursiveSearchForKey("thumbnails", headerContainer.avatar)[0]; | ||
this.banners = helpers.recursiveSearchForKey("thumbnails", headerContainer.banner)[0]; | ||
this.mobileBanners = helpers.recursiveSearchForKey("thumbnails", headerContainer.mobileBanner)[0]; | ||
this.tvBanners = helpers.recursiveSearchForKey("thumbnails", headerContainer.tvBanner)[0]; | ||
} | ||
} | ||
#parseOwnerBadges(ownerBadgeContainer:Array<any>) { | ||
if(ownerBadgeContainer.length > 0) { | ||
const badgeRenderers = helpers.recursiveSearchForKey("metadataBadgeRenderer", ownerBadgeContainer); | ||
if(badgeRenderers.length > 0) { | ||
this.badges = badgeRenderers.map((badgeRenderer:any) => ({ | ||
name: helpers.recursiveSearchForKey("label", badgeRenderer)[0], | ||
icon: helpers.recursiveSearchForKey("iconType", badgeRenderer)[0], | ||
})); | ||
} | ||
} | ||
} | ||
#cleanup() { | ||
if(this.thumbnails) this.thumbnails.forEach((a) => { | ||
if(a.url.startsWith("//")) a.url = "https:" + a.url; | ||
}) | ||
} | ||
getUploadList():ContinuatedList { | ||
return new ContinuatedList( | ||
//Http Request Options | ||
{ | ||
method: HTTPRequestMethod.POST, | ||
url: ENDPOINT_BROWSE, | ||
data: { | ||
browseId: this.channelId, | ||
params: channelBrowseType.VIDEOS | ||
} | ||
}, | ||
// Data Processor | ||
(data:any) => { | ||
let videosTabRenderer = helpers.recursiveSearchForKey("tabRenderer", data); | ||
videosTabRenderer = videosTabRenderer.find((a:any) => a.title.toLowerCase() == "videos"); | ||
if(videosTabRenderer) { | ||
const gridRendererContainer = helpers.recursiveSearchForKey("gridRenderer", videosTabRenderer)[0]; | ||
if(gridRendererContainer) { | ||
const items = helpers.recursiveSearchForKey("items", gridRendererContainer)[0]; | ||
return items; | ||
} | ||
} else { | ||
return helpers.recursiveSearchForKey("continuationItems", data)[0]; | ||
} | ||
}, this.httpclient, true); | ||
} | ||
async subscribe() { | ||
@@ -177,8 +326,8 @@ const res = await this.httpclient.request({ | ||
} | ||
} | ||
#cleanup() { | ||
if(this.thumbnails) this.thumbnails.forEach((a) => { | ||
if(a.url.startsWith("//")) a.url = "https:" + a.url; | ||
}) | ||
} | ||
enum channelBrowseType { | ||
DETAILS = "EgVhYm91dA%3D%3D", | ||
CHANNELS = "EghjaGFubmVscw%3D%3D", | ||
VIDEOS = "EgZ2aWRlb3M%3D", | ||
} |
@@ -12,2 +12,3 @@ import { Authenticator } from "./Authenticator"; | ||
import { DEBUG } from "./constants"; | ||
import { Channel } from "./main"; | ||
@@ -56,2 +57,10 @@ export default class IYoutube { | ||
async getChannel(channelId: string):Promise<Channel> { | ||
this.throwErrorIfNotReady(); | ||
var ch = new Channel(this.wrappedHttpClient); | ||
ch.channelId = channelId; | ||
await ch.loadAll(); | ||
return ch; | ||
} | ||
getExplorer():Explorer { | ||
@@ -58,0 +67,0 @@ return this.#explorer; |
160320
71
3212