[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.
pull/1354/head
AudricV 2025-07-26 23:30:24 +02:00
rodzic f4203e632d
commit 21c3aad320
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DA92EC7905614198
3 zmienionych plików z 103 dodań i 0 usunięć

Wyświetl plik

@ -39,6 +39,7 @@ import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeTrendingE
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeLiveExtractor;
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingGamingVideosExtractor;
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingMoviesAndShowsTrailersExtractor;
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingMusicExtractor;
import org.schabi.newpipe.extractor.services.youtube.extractors.kiosk.YoutubeTrendingPodcastsEpisodesExtractor;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeChannelTabLinkHandlerFactory;
@ -50,6 +51,7 @@ import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLi
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingGamingVideosLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingMoviesAndShowsTrailersLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingMusicLinkHandlerFactory;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeTrendingPodcastsEpisodesLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
@ -171,6 +173,8 @@ public class YoutubeService extends StreamingService {
YoutubeTrendingGamingVideosLinkHandlerFactory.INSTANCE;
final ListLinkHandlerFactory trendingMoviesAndShowsLHF =
YoutubeTrendingMoviesAndShowsTrailersLinkHandlerFactory.INSTANCE;
final ListLinkHandlerFactory trendingMusicLHF =
YoutubeTrendingMusicLinkHandlerFactory.INSTANCE;
try {
list.addKioskEntry(
@ -206,6 +210,14 @@ public class YoutubeService extends StreamingService {
trendingMoviesAndShowsLHF,
YoutubeTrendingMoviesAndShowsTrailersLinkHandlerFactory.KIOSK_ID
);
list.addKioskEntry(
(streamingService, url, id) -> new YoutubeTrendingMusicExtractor(
YoutubeService.this,
trendingMusicLHF.fromUrl(url),
id),
trendingMusicLHF,
YoutubeTrendingMusicLinkHandlerFactory.KIOSK_ID
);
list.addKioskEntry(
(streamingService, url, id) -> new YoutubeTrendingExtractor(
YoutubeService.this,

Wyświetl plik

@ -0,0 +1,39 @@
package org.schabi.newpipe.extractor.services.youtube.extractors.kiosk;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import javax.annotation.Nonnull;
import java.io.IOException;
public class YoutubeTrendingMusicExtractor extends YoutubeChartsBaseKioskExtractor {
public YoutubeTrendingMusicExtractor(final StreamingService streamingService,
final ListLinkHandler linkHandler,
final String kioskId) {
super(streamingService, linkHandler, kioskId, "TRENDING_VIDEOS");
}
@Override
public void onFetchPage(@Nonnull final Downloader downloader)
throws IOException, ExtractionException {
if (!YT_CHARTS_SUPPORTED_COUNTRY_CODES.contains(
getExtractorContentCountry().getCountryCode())) {
throw new ContentNotSupportedException(
"YouTube Charts doesn't support this country for trending music videos charts");
}
super.onFetchPage(downloader);
}
@Nonnull
@Override
public String getName() throws ParsingException {
// This is the official YouTube Charts name, even if autogenerated tracks and unofficial
// contents are returned
return "Trending Music Videos";
}
}

Wyświetl plik

@ -0,0 +1,52 @@
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Locale;
public final class YoutubeTrendingMusicLinkHandlerFactory
extends ListLinkHandlerFactory {
public static final String KIOSK_ID = "trending_music";
public static final YoutubeTrendingMusicLinkHandlerFactory INSTANCE =
new YoutubeTrendingMusicLinkHandlerFactory();
private static final String PATH = "/charts/TrendingVideos";
private YoutubeTrendingMusicLinkHandlerFactory() {
}
@Override
public String getUrl(final String id,
final List<String> contentFilter,
final String sortFilter)
throws ParsingException, UnsupportedOperationException {
return "https://charts.youtube.com" + PATH + "/RightNow";
}
@Override
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
return KIOSK_ID;
}
@Override
public boolean onAcceptUrl(final String url) throws ParsingException {
final URL urlObj;
try {
urlObj = Utils.stringToURL(url);
} catch (final MalformedURLException e) {
return false;
}
return Utils.isHTTP(urlObj)
&& "charts.youtube.com".equals(urlObj.getHost().toLowerCase(Locale.ROOT))
// Accept URLs not containing the /RightNow part
&& urlObj.getPath().startsWith(PATH);
}
}