mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-20 04:51:16 +00:00
feat(ytkids): add getChannel() (#292)
This commit is contained in:
@@ -7,6 +7,7 @@ YouTube Kids is a modified version of the YouTube app, with a simplified interfa
|
||||
* Kids
|
||||
* [.search(query)](#search)
|
||||
* [.getInfo(video_id)](#getinfo)
|
||||
* [.getChannel(channel_id)](#getchannel)
|
||||
* [.getHomeFeed()](#gethomefeed)
|
||||
|
||||
<a name="search"></a>
|
||||
@@ -64,6 +65,33 @@ Retrieves video info.
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<a name="getchannel"></a>
|
||||
### getChannel(channel_id)
|
||||
|
||||
Retrieves channel info.
|
||||
|
||||
**Returns:** `Promise.<Channel>`
|
||||
|
||||
| Param | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| channel_id | `string` | The channel id |
|
||||
|
||||
<details>
|
||||
<summary>Methods & Getters</summary>
|
||||
<p>
|
||||
|
||||
- `<channel>#getContinuation()`
|
||||
- Retrieves next batch of videos.
|
||||
|
||||
- `<channel>#has_continuation`
|
||||
- Returns whether there are more videos to retrieve.
|
||||
|
||||
- `<channel>#page`
|
||||
- Returns the original InnerTube response(s), parsed and sanitized.
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
<a name="gethomefeed"></a>
|
||||
### getHomeFeed()
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ class Feed {
|
||||
|
||||
const memo = concatMemos(
|
||||
this.#page.contents_memo,
|
||||
this.#page.continuation_contents_memo,
|
||||
this.#page.on_response_received_commands_memo,
|
||||
this.#page.on_response_received_endpoints_memo,
|
||||
this.#page.on_response_received_actions_memo,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import Search from '../parser/ytkids/Search';
|
||||
import HomeFeed from '../parser/ytkids/HomeFeed';
|
||||
import VideoInfo from '../parser/ytkids/VideoInfo';
|
||||
import Channel from '../parser/ytkids/Channel';
|
||||
import type Session from './Session';
|
||||
|
||||
import { generateRandomString } from '../utils/Utils';
|
||||
|
||||
class Kids {
|
||||
@@ -45,6 +47,15 @@ class Kids {
|
||||
return new VideoInfo(response, this.#session.actions, cpn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the contents of the given channel.
|
||||
* @param channel_id - The channel id.
|
||||
*/
|
||||
async getChannel(channel_id: string): Promise<Channel> {
|
||||
const response = await this.#session.actions.execute('/browse', { browseId: channel_id, client: 'YTKIDS' });
|
||||
return new Channel(this.#session.actions, response.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the home feed.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,8 @@ class ItemSection extends YTNode {
|
||||
|
||||
header: CommentsHeader | ItemSectionHeader | ItemSectionTabbedHeader | null;
|
||||
contents;
|
||||
target_id;
|
||||
target_id?: string;
|
||||
continuation?: string;
|
||||
|
||||
constructor(data: any) {
|
||||
super();
|
||||
@@ -20,6 +21,10 @@ class ItemSection extends YTNode {
|
||||
if (data.targetId || data.sectionIdentifier) {
|
||||
this.target_id = data?.target_id || data?.sectionIdentifier;
|
||||
}
|
||||
|
||||
if (data.continuations) {
|
||||
this.continuation = data.continuations?.at(0)?.nextContinuationData?.continuation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -269,6 +269,8 @@ export default class Parser {
|
||||
}
|
||||
|
||||
static parseLC(data: any) {
|
||||
if (data.itemSectionContinuation)
|
||||
return new ItemSectionContinuation(data.itemSectionContinuation);
|
||||
if (data.sectionListContinuation)
|
||||
return new SectionListContinuation(data.sectionListContinuation);
|
||||
if (data.liveChatContinuation)
|
||||
@@ -387,7 +389,22 @@ export default class Parser {
|
||||
|
||||
export type ParsedResponse = ReturnType<typeof Parser.parseResponse>;
|
||||
|
||||
// Continuation nodes
|
||||
// Continuation
|
||||
|
||||
export class ItemSectionContinuation extends YTNode {
|
||||
static readonly type = 'itemSectionContinuation';
|
||||
|
||||
contents: ObservedArray<YTNode> | null;
|
||||
continuation?: string;
|
||||
|
||||
constructor(data: any) {
|
||||
super();
|
||||
this.contents = Parser.parseArray(data.contents);
|
||||
if (data.continuations) {
|
||||
this.continuation = data.continuations?.at(0)?.nextContinuationData?.continuation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class AppendContinuationItemsAction extends YTNode {
|
||||
static readonly type = 'appendContinuationItemsAction';
|
||||
|
||||
34
src/parser/ytkids/Channel.ts
Normal file
34
src/parser/ytkids/Channel.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import Feed from '../../core/Feed';
|
||||
import Actions from '../../core/Actions';
|
||||
import C4TabbedHeader from '../classes/C4TabbedHeader';
|
||||
import ItemSection from '../classes/ItemSection';
|
||||
import { ItemSectionContinuation } from '..';
|
||||
|
||||
class Channel extends Feed {
|
||||
header?: C4TabbedHeader;
|
||||
contents?: ItemSection | ItemSectionContinuation;
|
||||
|
||||
constructor(actions: Actions, data: any, already_parsed = false) {
|
||||
super(actions, data, already_parsed);
|
||||
this.header = this.page.header?.item().as(C4TabbedHeader);
|
||||
this.contents = this.memo.getType(ItemSection).first() || this.page.continuation_contents?.as(ItemSectionContinuation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves next batch of videos.
|
||||
*/
|
||||
async getContinuation(): Promise<Channel> {
|
||||
const response = await this.actions.execute('/browse', {
|
||||
continuation: this.contents?.continuation,
|
||||
client: 'YTKIDS'
|
||||
});
|
||||
|
||||
return new Channel(this.actions, response.data);
|
||||
}
|
||||
|
||||
get has_continuation(): boolean {
|
||||
return !!this.contents?.continuation;
|
||||
}
|
||||
}
|
||||
|
||||
export default Channel;
|
||||
@@ -33,5 +33,9 @@ export const CHANNELS = [
|
||||
{
|
||||
ID: 'UCXuqSBlHAE6Xw-yeJA0Tunw',
|
||||
NAME: 'Linus Tech Tips'
|
||||
},
|
||||
{
|
||||
ID: 'UCpbpfcZfo-hoDAx2m1blFhg',
|
||||
NAME: 'Learning Blocks'
|
||||
}
|
||||
];
|
||||
@@ -238,6 +238,11 @@ describe('YouTube.js Tests', () => {
|
||||
const info = await yt.kids.getInfo(VIDEOS[6].ID);
|
||||
expect(info.basic_info?.id).toBe(VIDEOS[6].ID);
|
||||
});
|
||||
|
||||
it('should retrieve a channel', async () => {
|
||||
const channel = await yt.kids.getChannel(CHANNELS[1].ID);
|
||||
expect(channel.videos.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user