4141
4242import java .io .IOException ;
4343import java .nio .charset .StandardCharsets ;
44+ import java .util .stream .Stream ;
4445
4546import javax .annotation .Nonnull ;
4647
4748public class YoutubeTrendingExtractor extends KioskExtractor <StreamInfoItem > {
4849 private JsonObject initialData ;
4950
51+ private static final String VIDEOS_TAB_PARAMS = "4gIOGgxtb3N0X3BvcHVsYXI%3D" ;
52+
5053 public YoutubeTrendingExtractor (final StreamingService service ,
5154 final ListLinkHandler linkHandler ,
5255 final String kioskId ) {
@@ -60,6 +63,7 @@ public void onFetchPage(@Nonnull final Downloader downloader)
6063 final byte [] body = JsonWriter .string (prepareDesktopJsonBuilder (getExtractorLocalization (),
6164 getExtractorContentCountry ())
6265 .value ("browseId" , "FEtrending" )
66+ .value ("params" , VIDEOS_TAB_PARAMS )
6367 .done ())
6468 .getBytes (StandardCharsets .UTF_8 );
6569 // @formatter:on
@@ -94,7 +98,10 @@ public String getName() throws ParsingException {
9498 public InfoItemsPage <StreamInfoItem > getInitialPage () throws ParsingException {
9599 final StreamInfoItemsCollector collector = new StreamInfoItemsCollector (getServiceId ());
96100 final TimeAgoParser timeAgoParser = getTimeAgoParser ();
97- final JsonObject tabContent = getTrendingTabContent ();
101+ final JsonObject tab = getTrendingTab ();
102+ final JsonObject tabContent = tab .getObject ("content" );
103+ final boolean isVideoTab = tab .getObject ("endpoint" ).getObject ("browseEndpoint" )
104+ .getString ("params" , "" ).equals (VIDEOS_TAB_PARAMS );
98105
99106 if (tabContent .has ("richGridRenderer" )) {
100107 tabContent .getObject ("richGridRenderer" )
@@ -110,7 +117,7 @@ public InfoItemsPage<StreamInfoItem> getInitialPage() throws ParsingException {
110117 .forEachOrdered (videoRenderer -> collector .commit (
111118 new YoutubeStreamInfoItemExtractor (videoRenderer , timeAgoParser )));
112119 } else if (tabContent .has ("sectionListRenderer" )) {
113- tabContent .getObject ("sectionListRenderer" )
120+ final Stream < JsonObject > shelves = tabContent .getObject ("sectionListRenderer" )
114121 .getArray ("contents" )
115122 .stream ()
116123 .filter (JsonObject .class ::isInstance )
@@ -120,11 +127,19 @@ public InfoItemsPage<StreamInfoItem> getInitialPage() throws ParsingException {
120127 .stream ())
121128 .filter (JsonObject .class ::isInstance )
122129 .map (JsonObject .class ::cast )
123- .map (content -> content .getObject ("shelfRenderer" ))
124- // Filter Trending shorts and Recently trending sections which have a title,
125- // contrary to normal trends
126- .filter (shelfRenderer -> !shelfRenderer .has ("title" ))
127- .flatMap (shelfRenderer -> shelfRenderer .getObject ("content" )
130+ .map (content -> content .getObject ("shelfRenderer" ));
131+
132+ final Stream <JsonObject > items ;
133+ if (isVideoTab ) {
134+ // The first shelf of the Videos tab contains the normal trends
135+ items = shelves .findFirst ().stream ();
136+ } else {
137+ // Filter Trending shorts and Recently trending sections which have a title,
138+ // contrary to normal trends
139+ items = shelves .filter (shelfRenderer -> !shelfRenderer .has ("title" ));
140+ }
141+
142+ items .flatMap (shelfRenderer -> shelfRenderer .getObject ("content" )
128143 .getObject ("expandedShelfContentsRenderer" )
129144 .getArray ("items" )
130145 .stream ())
@@ -138,7 +153,7 @@ public InfoItemsPage<StreamInfoItem> getInitialPage() throws ParsingException {
138153 return new InfoItemsPage <>(collector , null );
139154 }
140155
141- private JsonObject getTrendingTabContent () throws ParsingException {
156+ private JsonObject getTrendingTab () throws ParsingException {
142157 return initialData .getObject ("contents" )
143158 .getObject ("twoColumnBrowseResultsRenderer" )
144159 .getArray ("tabs" )
@@ -150,7 +165,7 @@ private JsonObject getTrendingTabContent() throws ParsingException {
150165 .filter (tabRenderer -> tabRenderer .has ("content" ))
151166 // There should be at most one tab selected
152167 .findFirst ()
153- .orElseThrow (() -> new ParsingException ( "Could not get \" Now \" trending tab" ))
154- . getObject ( "content" );
168+ .orElseThrow (() ->
169+ new ParsingException ( "Could not get \" Now \" or \" Videos \" trending tab" ) );
155170 }
156171}
0 commit comments