[YouTube] Differentiate genre mixes from normal mixes

Note: genre mixes already worked, now they are just considered as such in various video id extraction and in related items
Note 2: now extracting a mix id from a *normal* youtube mix id will fail if the video id wouldn't be exactly 11 characters long
This commit is contained in:
Stypox 2022-02-17 17:19:54 +01:00
parent f19660e7d9
commit 63ed06a710
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
2 changed files with 43 additions and 8 deletions

View File

@ -13,6 +13,7 @@ import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.*;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.utils.JsonUtils;
import org.schabi.newpipe.extractor.utils.Parser;
@ -246,7 +247,8 @@ public class YoutubeParsingHelper {
* @return Whether given id belongs to a YouTube Mix
*/
public static boolean isYoutubeMixId(@Nonnull final String playlistId) {
return playlistId.startsWith("RD") && !isYoutubeMusicMixId(playlistId);
return playlistId.startsWith("RD")
&& !isYoutubeMusicMixId(playlistId);
}
/**
@ -282,28 +284,57 @@ public class YoutubeParsingHelper {
}
/**
* @return the video id extracted from the playlist id for Mixes
* @throws ParsingException If the playlistId is a Channel Mix or not a mix.
* Checks if the given playlist id is a YouTube Genre Mix (auto-generated playlist)
* Ids from a YouTube Genre Mix start with "RDGMEM"
*
* @return Whether given id belongs to a YouTube Genre Mix
*/
public static boolean isYoutubeGenreMixId(@Nonnull final String playlistId) {
return playlistId.startsWith("RDGMEM");
}
/**
* @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, if the playlistId is not a mix,
* if it is a mix but it's not based on a specific stream (this is the
* case for channel or genre mixes)
*/
@Nonnull
public static String extractVideoIdFromMixId(@Nonnull final String playlistId)
public static String extractVideoIdFromMixId(final String playlistId)
throws ParsingException {
if (isYoutubeMyMixId(playlistId)) {
if (isNullOrEmpty(playlistId)) {
throw new ParsingException("Video id could not be determined from empty playlist id");
} else if (isYoutubeMyMixId(playlistId)) {
return playlistId.substring(4);
} else if (isYoutubeMusicMixId(playlistId)) {
return playlistId.substring(6);
} else if (isYoutubeChannelMixId(playlistId)) {
// Channel mix are build with RMCM{channelId}, so videoId can't be determined
throw new ParsingException("Video id could not be determined from mix id: "
// Channel mixes are of the form RMCM{channelId}, so videoId can't be determined
throw new ParsingException("Video id could not be determined from channel mix id: "
+ playlistId);
} else if (isYoutubeGenreMixId(playlistId)) {
// Genre mixes are of the form RDGMEM{garbage}, so videoId can't be determined
throw new ParsingException("Video id could not be determined from genre mix id: "
+ playlistId);
} else if (isYoutubeMixId(playlistId)) { // normal mix
if (playlistId.length() != 13) {
// Stream YouTube mixes are of the form RD{videoId}, but if videoId is not exactly
// 11 characters then it can't be a video id, hence we are dealing with a different
// type of mix (e.g. genre mixes handled above, of the form RDGMEM{garbage})
throw new ParsingException("Video id could not be determined from mix id: "
+ playlistId);
}
return playlistId.substring(2);
} else { // not a mix
throw new ParsingException("Video id could not be determined from mix id: "
throw new ParsingException("Video id could not be determined from playlist id: "
+ playlistId);
}
}

View File

@ -3,6 +3,7 @@ package org.schabi.newpipe.extractor.services.youtube.extractors;
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;
@ -74,8 +75,11 @@ public class YoutubeMixPlaylistInfoItemExtractor implements PlaylistInfoItemExtr
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) {