diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java index 7fc0aabb9..59f386de6 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java @@ -339,6 +339,51 @@ public class YoutubeParsingHelper { } } + /** + * @param playlistId the playlist id to parse + * @return the {@link PlaylistInfo.PlaylistType} extracted from the playlistId (mix playlist + * types included) + * @throws ParsingException if the playlistId is null or empty + */ + @Nonnull + public static PlaylistInfo.PlaylistType extractPlaylistTypeFromPlaylistId( + final String playlistId) throws ParsingException { + if (isNullOrEmpty(playlistId)) { + throw new ParsingException("Could not extract playlist type from empty playlist id"); + } else if (isYoutubeMusicMixId(playlistId)) { + return PlaylistInfo.PlaylistType.MIX_MUSIC; + } else if (isYoutubeChannelMixId(playlistId)) { + return PlaylistInfo.PlaylistType.MIX_CHANNEL; + } else if (isYoutubeGenreMixId(playlistId)) { + return PlaylistInfo.PlaylistType.MIX_GENRE; + } else if (isYoutubeMixId(playlistId)) { // normal mix + // Either a normal mix based on a stream, or a "my mix" (still based on a stream). + // NOTE: if YouTube introduces even more types of mixes that still start with RD, + // they will default to this, even though they might not be based on a stream. + return PlaylistInfo.PlaylistType.MIX_STREAM; + } else { + // not a known type of mix: just consider it a normal playlist + return PlaylistInfo.PlaylistType.NORMAL; + } + } + + /** + * @param playlistUrl the playlist url to parse + * @return the {@link PlaylistInfo.PlaylistType} extracted from the playlistUrl's list param + * (mix playlist types included) + * @throws ParsingException if the playlistUrl is malformed, if has no list param or if the list + * param is empty + */ + public static PlaylistInfo.PlaylistType extractPlaylistTypeFromPlaylistUrl( + final String playlistUrl) throws ParsingException { + try { + return extractPlaylistTypeFromPlaylistId( + Utils.getQueryValue(Utils.stringToURL(playlistUrl), "list")); + } catch (final MalformedURLException e) { + throw new ParsingException("Could not extract playlist type from malformed url", e); + } + } + public static JsonObject getInitialData(final String html) throws ParsingException { try { try { diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java index 66500160d..b1f3e28c1 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistExtractor.java @@ -16,6 +16,7 @@ import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; +import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; @@ -241,4 +242,10 @@ public class YoutubeMixPlaylistExtractor extends PlaylistExtractor { private String getThumbnailUrlFromVideoId(final String videoId) { return "https://i.ytimg.com/vi/" + videoId + "/hqdefault.jpg"; } + + @Nonnull + @Override + public PlaylistInfo.PlaylistType getPlaylistType() throws ParsingException { + return extractPlaylistTypeFromPlaylistId(playlistData.getString("playlistId")); + } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistInfoItemExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistInfoItemExtractor.java index f9d11efb7..24df25690 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistInfoItemExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeMixPlaylistInfoItemExtractor.java @@ -1,10 +1,8 @@ package org.schabi.newpipe.extractor.services.youtube.extractors; +import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.extractPlaylistTypeFromPlaylistUrl; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getThumbnailUrlFromInfoItem; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isYoutubeChannelMixId; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isYoutubeGenreMixId; -import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isYoutubeMusicMixId; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import com.grack.nanojson.JsonObject; @@ -13,9 +11,6 @@ import org.schabi.newpipe.extractor.ListExtractor; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor; -import org.schabi.newpipe.extractor.utils.Utils; - -import java.net.MalformedURLException; import javax.annotation.Nonnull; @@ -64,26 +59,6 @@ public class YoutubeMixPlaylistInfoItemExtractor implements PlaylistInfoItemExtr @Nonnull @Override public PlaylistInfo.PlaylistType getPlaylistType() throws ParsingException { - try { - final String url = getUrl(); - final String mixPlaylistId = Utils.getQueryValue(Utils.stringToURL(url), "list"); - if (isNullOrEmpty(mixPlaylistId)) { - throw new ParsingException("Mix playlist id was null or empty for url " + url); - } - - if (isYoutubeMusicMixId(mixPlaylistId)) { - return PlaylistInfo.PlaylistType.MIX_MUSIC; - } else if (isYoutubeChannelMixId(mixPlaylistId)) { - return PlaylistInfo.PlaylistType.MIX_CHANNEL; - } else if (isYoutubeGenreMixId(mixPlaylistId)) { - return PlaylistInfo.PlaylistType.MIX_GENRE; - } else { - // either a normal mix based on a stream, or a "my mix" (still based on a stream) - // note: if YouTube introduces even more types of mixes, they will default to this - return PlaylistInfo.PlaylistType.MIX_STREAM; - } - } catch (final MalformedURLException e) { - throw new ParsingException("Could not obtain mix playlist id", e); - } + return extractPlaylistTypeFromPlaylistUrl(getUrl()); } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java index 11ffa1d57..c3ffd17dd 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubePlaylistExtractor.java @@ -14,6 +14,7 @@ import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.TimeAgoParser; import org.schabi.newpipe.extractor.playlist.PlaylistExtractor; +import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; @@ -329,4 +330,10 @@ public class YoutubePlaylistExtractor extends PlaylistExtractor { }) .forEachOrdered(collector::commit); } + + @Nonnull + @Override + public PlaylistInfo.PlaylistType getPlaylistType() throws ParsingException { + return extractPlaylistTypeFromPlaylistUrl(getUrl()); + } }