Skip to content

Commit 21c3aad

Browse files
committed
[YouTube] Add trending music extractor
This kiosk is meant to return official music videos, but it also returns unofficial content and autogenerated tracks, hence the kiosk name. Making requests with an unsupported YouTube Charts country leads to a 400 HTTP error, so for these countries a ContentNotSupportedException is thrown by the extractor.
1 parent f4203e6 commit 21c3aad

3 files changed

Lines changed: 103 additions & 0 deletions

File tree

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeLiveExtractor;
4040
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingGamingVideosExtractor;
4141
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingMoviesAndShowsTrailersExtractor;
42+
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingMusicExtractor;
4243
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingPodcastsEpisodesExtractor;
4344
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
4445
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelTabLinkHandlerFactory;
@@ -50,6 +51,7 @@
5051
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingGamingVideosLinkHandlerFactory;
5152
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingLinkHandlerFactory;
5253
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingMoviesAndShowsTrailersLinkHandlerFactory;
54+
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingMusicLinkHandlerFactory;
5355
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingPodcastsEpisodesLinkHandlerFactory;
5456
import org.schabi.newpipe.extractor.stream.StreamExtractor;
5557
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
@@ -171,6 +173,8 @@ public KioskList getKioskList() throws ExtractionException {
171173
YoutubeTrendingGamingVideosLinkHandlerFactory.INSTANCE;
172174
final ListLinkHandlerFactory trendingMoviesAndShowsLHF =
173175
YoutubeTrendingMoviesAndShowsTrailersLinkHandlerFactory.INSTANCE;
176+
final ListLinkHandlerFactory trendingMusicLHF =
177+
YoutubeTrendingMusicLinkHandlerFactory.INSTANCE;
174178

175179
try {
176180
list.addKioskEntry(
@@ -206,6 +210,14 @@ public KioskList getKioskList() throws ExtractionException {
206210
trendingMoviesAndShowsLHF,
207211
YoutubeTrendingMoviesAndShowsTrailersLinkHandlerFactory.KIOSK_ID
208212
);
213+
list.addKioskEntry(
214+
(streamingService, url, id) -> new YoutubeTrendingMusicExtractor(
215+
YoutubeService.this,
216+
trendingMusicLHF.fromUrl(url),
217+
id),
218+
trendingMusicLHF,
219+
YoutubeTrendingMusicLinkHandlerFactory.KIOSK_ID
220+
);
209221
list.addKioskEntry(
210222
(streamingService, url, id) -> new YoutubeTrendingExtractor(
211223
YoutubeService.this,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.schabi.newpipe.extractor.services.youtube.extractors.kiosk;
2+
3+
import org.schabi.newpipe.extractor.StreamingService;
4+
import org.schabi.newpipe.extractor.downloader.Downloader;
5+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
6+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
7+
import org.schabi.newpipe.extractor.exceptions.ParsingException;
8+
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
9+
10+
import javax.annotation.Nonnull;
11+
import java.io.IOException;
12+
13+
public class YoutubeTrendingMusicExtractor extends YoutubeChartsBaseKioskExtractor {
14+
15+
public YoutubeTrendingMusicExtractor(final StreamingService streamingService,
16+
final ListLinkHandler linkHandler,
17+
final String kioskId) {
18+
super(streamingService, linkHandler, kioskId, "TRENDING_VIDEOS");
19+
}
20+
21+
@Override
22+
public void onFetchPage(@Nonnull final Downloader downloader)
23+
throws IOException, ExtractionException {
24+
if (!YT_CHARTS_SUPPORTED_COUNTRY_CODES.contains(
25+
getExtractorContentCountry().getCountryCode())) {
26+
throw new ContentNotSupportedException(
27+
"YouTube Charts doesn't support this country for trending music videos charts");
28+
}
29+
super.onFetchPage(downloader);
30+
}
31+
32+
@Nonnull
33+
@Override
34+
public String getName() throws ParsingException {
35+
// This is the official YouTube Charts name, even if autogenerated tracks and unofficial
36+
// contents are returned
37+
return "Trending Music Videos";
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
2+
3+
import org.schabi.newpipe.extractor.exceptions.ParsingException;
4+
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
5+
import org.schabi.newpipe.extractor.utils.Utils;
6+
7+
import java.net.MalformedURLException;
8+
import java.net.URL;
9+
import java.util.List;
10+
import java.util.Locale;
11+
12+
public final class YoutubeTrendingMusicLinkHandlerFactory
13+
extends ListLinkHandlerFactory {
14+
15+
public static final String KIOSK_ID = "trending_music";
16+
17+
public static final YoutubeTrendingMusicLinkHandlerFactory INSTANCE =
18+
new YoutubeTrendingMusicLinkHandlerFactory();
19+
20+
private static final String PATH = "/charts/TrendingVideos";
21+
22+
private YoutubeTrendingMusicLinkHandlerFactory() {
23+
}
24+
25+
@Override
26+
public String getUrl(final String id,
27+
final List<String> contentFilter,
28+
final String sortFilter)
29+
throws ParsingException, UnsupportedOperationException {
30+
return "https://charts.youtube.com" + PATH + "/RightNow";
31+
}
32+
33+
@Override
34+
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
35+
return KIOSK_ID;
36+
}
37+
38+
@Override
39+
public boolean onAcceptUrl(final String url) throws ParsingException {
40+
final URL urlObj;
41+
try {
42+
urlObj = Utils.stringToURL(url);
43+
} catch (final MalformedURLException e) {
44+
return false;
45+
}
46+
47+
return Utils.isHTTP(urlObj)
48+
&& "charts.youtube.com".equals(urlObj.getHost().toLowerCase(Locale.ROOT))
49+
// Accept URLs not containing the /RightNow part
50+
&& urlObj.getPath().startsWith(PATH);
51+
}
52+
}

0 commit comments

Comments
 (0)