Skip to content

Commit 93a90b8

Browse files
authored
Merge pull request #1094 from AudricV/yt_support-more-channel-headers
[YouTube] Support more channel headers
2 parents 7936987 + 44b664a commit 93a90b8

6 files changed

Lines changed: 875 additions & 59 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelHelper.java

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,68 @@ private static void checkIfChannelResponseIsValid(@Nonnull final JsonObject json
219219
*/
220220
public static final class ChannelHeader {
221221

222+
/**
223+
* Types of supported YouTube channel headers.
224+
*/
225+
public enum HeaderType {
226+
227+
/**
228+
* A {@code c4TabbedHeaderRenderer} channel header type.
229+
*
230+
* <p>
231+
* This header is returned on the majority of channels and contains the channel's name,
232+
* its banner and its avatar and its subscriber count in most cases.
233+
* </p>
234+
*/
235+
C4_TABBED,
236+
237+
/**
238+
* An {@code interactiveTabbedHeaderRenderer} channel header type.
239+
*
240+
* <p>
241+
* This header is returned for gaming topic channels, and only contains the channel's
242+
* name, its banner and a poster as its "avatar".
243+
* </p>
244+
*/
245+
INTERACTIVE_TABBED,
246+
247+
/**
248+
* A {@code carouselHeaderRenderer} channel header type.
249+
*
250+
* <p>
251+
* This header returns only the channel's name, its avatar and its subscriber count.
252+
* </p>
253+
*/
254+
CAROUSEL,
255+
256+
/**
257+
* A {@code pageHeaderRenderer} channel header type.
258+
*
259+
* <p>
260+
* This header returns only the channel's name and its avatar.
261+
* </p>
262+
*/
263+
PAGE
264+
}
265+
222266
/**
223267
* The channel header JSON response.
224268
*/
225269
@Nonnull
226270
public final JsonObject json;
227271

228272
/**
229-
* Whether the header is a {@code carouselHeaderRenderer}.
273+
* The type of the channel header.
230274
*
231275
* <p>
232-
* See the class documentation for more details.
276+
* See the documentation of the {@link HeaderType} class for more details.
233277
* </p>
234278
*/
235-
public final boolean isCarouselHeader;
279+
public final HeaderType headerType;
236280

237-
private ChannelHeader(@Nonnull final JsonObject json, final boolean isCarouselHeader) {
281+
private ChannelHeader(@Nonnull final JsonObject json, final HeaderType headerType) {
238282
this.json = json;
239-
this.isCarouselHeader = isCarouselHeader;
283+
this.headerType = headerType;
240284
}
241285
}
242286

@@ -254,7 +298,7 @@ public static Optional<ChannelHeader> getChannelHeader(
254298

255299
if (header.has("c4TabbedHeaderRenderer")) {
256300
return Optional.of(header.getObject("c4TabbedHeaderRenderer"))
257-
.map(json -> new ChannelHeader(json, false));
301+
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.C4_TABBED));
258302
} else if (header.has("carouselHeaderRenderer")) {
259303
return header.getObject("carouselHeaderRenderer")
260304
.getArray("contents")
@@ -264,7 +308,14 @@ public static Optional<ChannelHeader> getChannelHeader(
264308
.filter(item -> item.has("topicChannelDetailsRenderer"))
265309
.findFirst()
266310
.map(item -> item.getObject("topicChannelDetailsRenderer"))
267-
.map(json -> new ChannelHeader(json, true));
311+
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.CAROUSEL));
312+
} else if (header.has("pageHeaderRenderer")) {
313+
return Optional.of(header.getObject("pageHeaderRenderer"))
314+
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.PAGE));
315+
} else if (header.has("interactiveTabbedHeaderRenderer")) {
316+
return Optional.of(header.getObject("interactiveTabbedHeaderRenderer"))
317+
.map(json -> new ChannelHeader(json,
318+
ChannelHeader.HeaderType.INTERACTIVE_TABBED));
268319
} else {
269320
return Optional.empty();
270321
}

0 commit comments

Comments
 (0)