Compare commits

..

8 Commits

Author SHA1 Message Date
github-actions[bot]
1e29019a07 chore(main): release 10.2.0 (#688)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-25 10:52:50 -03:00
Luan
6765f4e0d7 fix(Player): Bump cache version (#702)
We should always do this after updating the sig/nsig code, it's so that the old cache gets ignored : ).
2024-07-25 10:48:24 -03:00
absidue
3048f70f60 fix(Player): Fix extracting the n-token decipher algorithm again (#701) 2024-07-25 10:07:00 -03:00
Brahim Hadriche
090539b28f feat(parser): add classdata to unhandled parse errors (#691) 2024-07-24 15:55:20 -03:00
Brahim Hadriche
6d0bc89be1 fix(parser): ignore MiniGameCardView node (#692) 2024-07-24 15:54:37 -03:00
GurumNyang
a5f62093a1 feature(proto): Add comment_id to commentSectionParams (#693) 2024-07-24 15:54:14 -03:00
absidue
a352ddeb9d feat(Format): Add is_secondary for detecting secondary audio tracks (#697) 2024-07-24 15:53:27 -03:00
Brahim Hadriche
0f8f92a28a fix(parser): ThumbnailView background color (#686) 2024-07-11 14:31:27 -03:00
12 changed files with 76 additions and 36 deletions

View File

@@ -1,5 +1,22 @@
# Changelog
## [10.2.0](https://github.com/LuanRT/YouTube.js/compare/v10.1.0...v10.2.0) (2024-07-25)
### Features
* **Format:** Add `is_secondary` for detecting secondary audio tracks ([#697](https://github.com/LuanRT/YouTube.js/issues/697)) ([a352dde](https://github.com/LuanRT/YouTube.js/commit/a352ddeb9db001e99f49025048ad0942d84f1b3e))
* **parser:** add classdata to unhandled parse errors ([#691](https://github.com/LuanRT/YouTube.js/issues/691)) ([090539b](https://github.com/LuanRT/YouTube.js/commit/090539b28f9bc3387d01e37325ba5741b33b1765))
* **proto:** Add `comment_id` to commentSectionParams ([#693](https://github.com/LuanRT/YouTube.js/issues/693)) ([a5f6209](https://github.com/LuanRT/YouTube.js/commit/a5f62093a18705fc822abd86beaa81788b6535ce))
### Bug Fixes
* **parser:** ignore MiniGameCardView node ([#692](https://github.com/LuanRT/YouTube.js/issues/692)) ([6d0bc89](https://github.com/LuanRT/YouTube.js/commit/6d0bc89be18f27a8ce74517f5cab5020d6790328))
* **parser:** ThumbnailView background color ([#686](https://github.com/LuanRT/YouTube.js/issues/686)) ([0f8f92a](https://github.com/LuanRT/YouTube.js/commit/0f8f92a28a5b6143e890626b22ce570730a0cf09))
* **Player:** Bump cache version ([#702](https://github.com/LuanRT/YouTube.js/issues/702)) ([6765f4e](https://github.com/LuanRT/YouTube.js/commit/6765f4e0d791c657fc7411e9cdd2c0f9284e9982))
* **Player:** Fix extracting the n-token decipher algorithm again ([#701](https://github.com/LuanRT/YouTube.js/issues/701)) ([3048f70](https://github.com/LuanRT/YouTube.js/commit/3048f70f60756884bd7b591d770f7b6343cfa259))
## [10.1.0](https://github.com/LuanRT/YouTube.js/compare/v10.0.0...v10.1.0) (2024-07-10)

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "youtubei.js",
"version": "10.1.0",
"version": "10.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "youtubei.js",
"version": "10.1.0",
"version": "10.2.0",
"funding": [
"https://github.com/sponsors/LuanRT"
],

View File

@@ -1,6 +1,6 @@
{
"name": "youtubei.js",
"version": "10.1.0",
"version": "10.2.0",
"description": "A wrapper around YouTube's private API. Supports YouTube, YouTube Music, YouTube Kids and YouTube Studio (WIP).",
"type": "module",
"types": "./dist/src/platform/lib.d.ts",

View File

@@ -220,20 +220,13 @@ export default class Player {
}
static extractNSigSourceCode(data: string): string {
let sc = getStringBetweenStrings(data, 'b=a.split("")', '}return b.join("")}');
const match = data.match(/b=(?:a\.split\(|String\.prototype\.split\.call\(a,)""\).*?\}return (?:b\.join\(|Array\.prototype\.join\.call\(b,)""\)\}/s);
if (sc)
return `function descramble_nsig(a) { let b=a.split("")${sc}} return b.join(""); } descramble_nsig(nsig)`;
if (!match) {
throw new PlayerError('Failed to extract n-token decipher algorithm');
}
sc = getStringBetweenStrings(data, 'b=String.prototype.split.call(a,"")', '}return Array.prototype.join.call(b,"")}');
if (sc)
return `function descramble_nsig(a) { let b=String.prototype.split.call(a, "")${sc}} return Array.prototype.join.call(b, ""); } descramble_nsig(nsig)`;
// We really should throw an error here to avoid errors later, returning a pass-through function for backwards-compatibility
Log.warn(TAG, 'Failed to extract n-token decipher algorithm');
return 'function descramble_nsig(a) { return a; } descramble_nsig(nsig)';
return `function descramble_nsig(a) { let ${match[0]} descramble_nsig(nsig)`;
}
get url(): string {
@@ -241,6 +234,6 @@ export default class Player {
}
static get LIBRARY_VERSION(): number {
return 10;
return 11;
}
}

View File

@@ -6,7 +6,7 @@ export default class CollectionThumbnailView extends YTNode {
static type = 'CollectionThumbnailView';
primary_thumbnail: ThumbnailView | null;
stack_color: {
stack_color?: {
light_theme: number;
dark_theme: number;
};
@@ -15,9 +15,11 @@ export default class CollectionThumbnailView extends YTNode {
super();
this.primary_thumbnail = Parser.parseItem(data.primaryThumbnail, ThumbnailView);
this.stack_color = {
light_theme: data.stackColor.lightTheme,
dark_theme: data.stackColor.darkTheme
};
if (data.stackColor) {
this.stack_color = {
light_theme: data.stackColor.lightTheme,
dark_theme: data.stackColor.darkTheme
};
}
}
}

View File

@@ -7,7 +7,7 @@ export default class ThumbnailBadgeView extends YTNode {
icon_name: string;
text: string;
badge_style: string;
background_color: {
background_color?: {
light_theme: number;
dark_theme: number;
};
@@ -18,9 +18,11 @@ export default class ThumbnailBadgeView extends YTNode {
this.icon_name = data.icon.sources[0].clientResource.imageName;
this.text = data.text;
this.badge_style = data.badgeStyle;
this.background_color = {
light_theme: data.backgroundColor.lightTheme,
dark_theme: data.backgroundColor.darkTheme
};
if (data.backgroundColor) {
this.background_color = {
light_theme: data.backgroundColor.lightTheme,
dark_theme: data.backgroundColor.darkTheme
};
}
}
}

View File

@@ -9,7 +9,7 @@ export default class ThumbnailView extends YTNode {
image: Thumbnail[];
overlays: (ThumbnailOverlayBadgeView | ThumbnailHoverOverlayView)[];
background_color: {
background_color?: {
light_theme: number;
dark_theme: number;
};
@@ -19,9 +19,11 @@ export default class ThumbnailView extends YTNode {
this.image = Thumbnail.fromResponse(data.image);
this.overlays = Parser.parseArray(data.overlays, [ ThumbnailOverlayBadgeView, ThumbnailHoverOverlayView ]);
this.background_color = {
light_theme: data.backgroundColor.lightTheme,
dark_theme: data.backgroundColor.darkTheme
};
if (data.backgroundColor) {
this.background_color = {
light_theme: data.backgroundColor.lightTheme,
dark_theme: data.backgroundColor.darkTheme
};
}
}
}

View File

@@ -57,6 +57,7 @@ export default class Format {
language?: string | null;
is_dubbed?: boolean;
is_descriptive?: boolean;
is_secondary?: boolean;
is_original?: boolean;
color_info?: {
primaries?: string;
@@ -213,7 +214,8 @@ export default class Format {
const audio_content = xtags?.find((x) => x.startsWith('acont='))?.split('=')[1];
this.is_dubbed = audio_content === 'dubbed';
this.is_descriptive = audio_content === 'descriptive';
this.is_original = audio_content === 'original' || (!this.is_dubbed && !this.is_descriptive && !this.is_drc);
this.is_secondary = audio_content === 'secondary';
this.is_original = audio_content === 'original' || (!this.is_dubbed && !this.is_descriptive && !this.is_secondary && !this.is_drc);
}
// Some text tracks don't have xtags while others do

View File

@@ -77,7 +77,8 @@ const IGNORED_LIST = new Set([
'BrandVideoSingleton',
'StatementBanner',
'GuideSigninPromo',
'AdsEngagementPanelContent'
'AdsEngagementPanelContent',
'MiniGameCardView'
]);
const RUNTIME_NODES = new Map<string, YTNodeConstructor>(Object.entries(YTNodes));
@@ -94,7 +95,8 @@ let ERROR_HANDLER: ParserErrorHandler = ({ classname, ...context }: ParserError)
new InnertubeError(
`Something went wrong at ${classname}!\n` +
`This is a bug, please report it at ${Platform.shim.info.bugs_url}`, {
stack: context.error.stack
stack: context.error.stack,
classdata: JSON.stringify(context.classdata, null, 2)
}
)
);

View File

@@ -21,6 +21,7 @@ export declare namespace $.youtube.GetCommentsSectionParams.Params {
videoId: string;
sortBy: number;
type: number;
commentId?: string;
}
}
@@ -31,6 +32,7 @@ export function getDefaultValue(): $.youtube.GetCommentsSectionParams.Params.Opt
videoId: "",
sortBy: 0,
type: 0,
commentId: undefined,
};
}
@@ -46,6 +48,7 @@ export function encodeJson(value: $.youtube.GetCommentsSectionParams.Params.Opti
if (value.videoId !== undefined) result.videoId = tsValueToJsonValueFns.string(value.videoId);
if (value.sortBy !== undefined) result.sortBy = tsValueToJsonValueFns.int32(value.sortBy);
if (value.type !== undefined) result.type = tsValueToJsonValueFns.int32(value.type);
if (value.commentId !== undefined) result.commentId = tsValueToJsonValueFns.string(value.commentId);
return result;
}
@@ -54,6 +57,7 @@ export function decodeJson(value: any): $.youtube.GetCommentsSectionParams.Param
if (value.videoId !== undefined) result.videoId = jsonValueToTsValueFns.string(value.videoId);
if (value.sortBy !== undefined) result.sortBy = jsonValueToTsValueFns.int32(value.sortBy);
if (value.type !== undefined) result.type = jsonValueToTsValueFns.int32(value.type);
if (value.commentId !== undefined) result.commentId = jsonValueToTsValueFns.string(value.commentId);
return result;
}
@@ -77,6 +81,12 @@ export function encodeBinary(value: $.youtube.GetCommentsSectionParams.Params.Op
[15, tsValueToWireValueFns.int32(tsValue)],
);
}
if (value.commentId !== undefined) {
const tsValue = value.commentId;
result.push(
[16, tsValueToWireValueFns.string(tsValue)],
);
}
return serialize(result);
}
@@ -105,5 +115,12 @@ export function decodeBinary(binary: Uint8Array): $.youtube.GetCommentsSectionPa
if (value === undefined) break field;
result.type = value;
}
field: {
const wireValue = wireFields.get(16);
if (wireValue === undefined) break field;
const value = wireValueToTsValueFns.string(wireValue);
if (value === undefined) break field;
result.commentId = value;
}
return result;
}

View File

@@ -155,7 +155,8 @@ export function encodeMessageParams(channel_id: string, video_id: string): strin
export function encodeCommentsSectionParams(video_id: string, options: {
type?: number,
sort_by?: 'TOP_COMMENTS' | 'NEWEST_FIRST'
sort_by?: 'TOP_COMMENTS' | 'NEWEST_FIRST',
comment_id?: string
} = {}): string {
const sort_options = {
TOP_COMMENTS: 0,
@@ -171,7 +172,8 @@ export function encodeCommentsSectionParams(video_id: string, options: {
opts: {
videoId: video_id,
sortBy: sort_options[options.sort_by || 'TOP_COMMENTS'],
type: options.type || 2
type: options.type || 2,
commentId: options.comment_id || ''
},
target: 'comments-section'
}

View File

@@ -162,6 +162,7 @@ message GetCommentsSectionParams {
required string video_id = 4;
required int32 sort_by = 6;
required int32 type = 15;
optional string comment_id = 16;
}
message RepliesOptions {