From 451bb1315c9171e574f5da527e58fc508fe16b43 Mon Sep 17 00:00:00 2001 From: litetex <40789489+litetex@users.noreply.github.com> Date: Sun, 9 Feb 2025 20:12:02 +0100 Subject: [PATCH] YouTube channel mixes no longer exist It looks like YT removed this around autumn 2024 Other mentions: https://www.reddit.com/r/youtube/comments/1dhuvyo/channel_mixes_disappeared/ --- .../extractor/playlist/PlaylistInfo.java | 6 -- .../youtube/YoutubeParsingHelper.java | 17 ----- .../YoutubePlaylistLinkHandlerFactory.java | 9 --- .../YoutubeMixPlaylistExtractorTest.java | 66 ------------------- 4 files changed, 98 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/playlist/PlaylistInfo.java b/extractor/src/main/java/org/schabi/newpipe/extractor/playlist/PlaylistInfo.java index bb29ca7d0..06b23375b 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/playlist/PlaylistInfo.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/playlist/PlaylistInfo.java @@ -42,12 +42,6 @@ public final class PlaylistInfo extends ListInfo { */ MIX_MUSIC, - /** - * A mix made only of streams from (or related to) the same channel, for example YouTube - * channel mixes - */ - MIX_CHANNEL, - /** * A mix made only of streams related to a particular (musical) genre, for example YouTube * genre mixes 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 da5870833..0a1c7865b 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 @@ -359,16 +359,6 @@ public final class YoutubeParsingHelper { return playlistId.startsWith("RDAMVM") || playlistId.startsWith("RDCLAK"); } - /** - * Checks if the given playlist id is a YouTube Channel Mix (auto-generated playlist) - * Ids from a YouTube channel Mix start with "RDCM" - * - * @return Whether given id belongs to a YouTube Channel Mix - */ - public static boolean isYoutubeChannelMixId(@Nonnull final String playlistId) { - return playlistId.startsWith("RDCM"); - } - /** * Checks if the given playlist id is a YouTube Genre Mix (auto-generated playlist) * Ids from a YouTube Genre Mix start with "RDGMEM" @@ -399,11 +389,6 @@ public final class YoutubeParsingHelper { } else if (isYoutubeMusicMixId(playlistId)) { return playlistId.substring(6); - } else if (isYoutubeChannelMixId(playlistId)) { - // 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: " @@ -438,8 +423,6 @@ public final class YoutubeParsingHelper { 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 diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubePlaylistLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubePlaylistLinkHandlerFactory.java index f6d2e10e9..a57ad8de1 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubePlaylistLinkHandlerFactory.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubePlaylistLinkHandlerFactory.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.extractor.services.youtube.linkHandler; -import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; @@ -57,14 +56,6 @@ public final class YoutubePlaylistLinkHandlerFactory extends ListLinkHandlerFact "the list-ID given in the URL does not match the list pattern"); } - if (YoutubeParsingHelper.isYoutubeChannelMixId(listID) - && Utils.getQueryValue(urlObj, "v") == null) { - // Video id can't be determined from the channel mix id. - // See YoutubeParsingHelper#extractVideoIdFromMixId - throw new ContentNotSupportedException( - "Channel Mix without a video id are not supported"); - } - return listID; } catch (final Exception exception) { throw new ParsingException("Error could not parse URL: " + exception.getMessage(), diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java index 1a6e596d8..e58c8731c 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeMixPlaylistExtractorTest.java @@ -336,72 +336,6 @@ public class YoutubeMixPlaylistExtractorTest { } } - public static class ChannelMix { - private static final String CHANNEL_ID = "UCXuqSBlHAE6Xw-yeJA0Tunw"; - private static final String VIDEO_ID_OF_CHANNEL = "mnk6gnOBYIo"; - private static final String CHANNEL_TITLE = "Linus Tech Tips"; - - - @BeforeAll - public static void setUp() throws Exception { - YoutubeTestsUtils.ensureStateless(); - YoutubeParsingHelper.setConsentAccepted(true); - NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "channelMix")); - extractor = (YoutubeMixPlaylistExtractor) YouTube - .getPlaylistExtractor("https://www.youtube.com/watch?v=" + VIDEO_ID_OF_CHANNEL - + "&list=RDCM" + CHANNEL_ID); - extractor.fetchPage(); - } - - @Test - void getName() throws Exception { - final String name = extractor.getName(); - ExtractorAsserts.assertContains("Mix", name); - ExtractorAsserts.assertContains(CHANNEL_TITLE, name); - } - - @Test - void getThumbnails() throws Exception { - YoutubeTestsUtils.testImages(extractor.getThumbnails()); - extractor.getThumbnails().forEach(thumbnail -> - ExtractorAsserts.assertContains(VIDEO_ID_OF_CHANNEL, thumbnail.getUrl())); - } - - @Test - void getInitialPage() throws Exception { - final InfoItemsPage streams = extractor.getInitialPage(); - assertFalse(streams.getItems().isEmpty()); - assertTrue(streams.hasNextPage()); - } - - @Test - void getPage() throws Exception { - final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder( - NewPipe.getPreferredLocalization(), NewPipe.getPreferredContentCountry()) - .value("videoId", VIDEO_ID_OF_CHANNEL) - .value("playlistId", "RDCM" + CHANNEL_ID) - .value("params", "OAE%3D") - .done()) - .getBytes(StandardCharsets.UTF_8); - - final InfoItemsPage streams = extractor.getPage(new Page( - YOUTUBEI_V1_URL + "next?" + DISABLE_PRETTY_PRINT_PARAMETER, - null, null, dummyCookie, body)); - assertFalse(streams.getItems().isEmpty()); - assertTrue(streams.hasNextPage()); - } - - @Test - void getStreamCount() { - assertEquals(ListExtractor.ITEM_COUNT_INFINITE, extractor.getStreamCount()); - } - - @Test - void getPlaylistType() throws ParsingException { - assertEquals(PlaylistInfo.PlaylistType.MIX_CHANNEL, extractor.getPlaylistType()); - } - } - public static class GenreMix { private static final String VIDEO_ID = "kINJeTNFbpg"; private static final String MIX_TITLE = "Mix – Electronic music";