diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubeStreamLinkHandlerFactory.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubeStreamLinkHandlerFactory.java index 6ff6175b..bff9d827 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubeStreamLinkHandlerFactory.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubeStreamLinkHandlerFactory.java @@ -11,6 +11,8 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.Arrays; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -38,6 +40,7 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory { private static final Pattern YOUTUBE_VIDEO_ID_REGEX_PATTERN = Pattern.compile("^([a-zA-Z0-9_-]{11})"); private static final YoutubeStreamLinkHandlerFactory instance = new YoutubeStreamLinkHandlerFactory(); + private static final List SUBPATHS = Arrays.asList("embed/", "shorts/", "watch/", "v/", "w/"); private YoutubeStreamLinkHandlerFactory() { } @@ -124,7 +127,7 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory { switch (host.toUpperCase()) { case "WWW.YOUTUBE-NOCOOKIE.COM": { if (path.startsWith("embed/")) { - String id = path.split("/")[1]; + String id = path.substring(6); // embed/ return assertIsId(id); } @@ -150,11 +153,8 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory { return assertIsId(viewQueryValue); } - if (path.startsWith("embed/") || path.startsWith("shorts/")) { - String id = path.split("/")[1]; - - return assertIsId(id); - } + String maybeId = getIdFromSubpathsInPath(path); + if (maybeId != null) return maybeId; String viewQueryValue = Utils.getQueryValue(url, "v"); return assertIsId(viewQueryValue); @@ -169,20 +169,7 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory { return assertIsId(path); } - case "HOOKTUBE.COM": { - if (path.startsWith("v/")) { - String id = path.substring("v/".length()); - - return assertIsId(id); - } - if (path.startsWith("watch/")) { - String id = path.substring("watch/".length()); - - return assertIsId(id); - } - // there is no break-statement here on purpose so the next code-block gets also run for hooktube - } - + case "HOOKTUBE.COM": case "INVIDIO.US": case "DEV.INVIDIO.US": case "WWW.INVIDIO.US": @@ -208,11 +195,8 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory { return assertIsId(viewQueryValue); } } - if (path.startsWith("embed/")) { - String id = path.substring("embed/".length()); - - return assertIsId(id); - } + String maybeId = getIdFromSubpathsInPath(path); + if (maybeId != null) return maybeId; String viewQueryValue = Utils.getQueryValue(url, "v"); if (viewQueryValue != null) { @@ -237,4 +221,14 @@ public class YoutubeStreamLinkHandlerFactory extends LinkHandlerFactory { return false; } } + + private String getIdFromSubpathsInPath(String path) throws ParsingException { + for (final String subpath : SUBPATHS) { + if (path.startsWith(subpath)) { + String id = path.substring(subpath.length()); + return assertIsId(id); + } + } + return null; + } } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamLinkHandlerFactoryTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamLinkHandlerFactoryTest.java index b156e70c..37266bd4 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamLinkHandlerFactoryTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamLinkHandlerFactoryTest.java @@ -92,6 +92,9 @@ public class YoutubeStreamLinkHandlerFactoryTest { assertEquals("-cdveCh1kQk", linkHandler.fromUrl("HTTPS://youtu.be/-cdveCh1kQk)").getId()); assertEquals("IOS2fqxwYbA", linkHandler.fromUrl("https://www.youtube.com/shorts/IOS2fqxwYbAhi").getId()); assertEquals("IOS2fqxwYbA", linkHandler.fromUrl("http://www.youtube.com/shorts/IOS2fqxwYbA").getId()); + assertEquals("IOS2fqxwYbA", linkHandler.fromUrl("http://www.youtube.com/v/IOS2fqxwYbA").getId()); + assertEquals("IOS2fqxwYbA", linkHandler.fromUrl("http://www.youtube.com/w/IOS2fqxwYbA").getId()); + assertEquals("IOS2fqxwYbA", linkHandler.fromUrl("http://www.youtube.com/watch/IOS2fqxwYbA").getId()); } @Test @@ -113,6 +116,9 @@ public class YoutubeStreamLinkHandlerFactoryTest { assertTrue(linkHandler.acceptUrl("vnd.youtube.launch:jZViOEv90dI")); assertTrue(linkHandler.acceptUrl("https://music.youtube.com/watch?v=O0EDx9WAelc")); assertTrue(linkHandler.acceptUrl("https://www.youtube.com/shorts/IOS2fqxwYbA")); + assertTrue(linkHandler.acceptUrl("https://www.youtube.com/v/IOS2fqxwYbA")); + assertTrue(linkHandler.acceptUrl("https://www.youtube.com/w/IOS2fqxwYbA")); + assertTrue(linkHandler.acceptUrl("https://www.youtube.com/watch/IOS2fqxwYbA")); } @Test @@ -134,26 +140,33 @@ public class YoutubeStreamLinkHandlerFactoryTest { assertEquals("ocH3oSnZG3c", linkHandler.fromUrl("https://hooktube.com/watch?v=ocH3oSnZG3c&list=PLS2VU1j4vzuZwooPjV26XM9UEBY2CPNn2").getId()); assertEquals("3msbfr6pBNE", linkHandler.fromUrl("hooktube.com/watch/3msbfr6pBNE").getId()); assertEquals("3msbfr6pBNE", linkHandler.fromUrl("hooktube.com/v/3msbfr6pBNE").getId()); + assertEquals("3msbfr6pBNE", linkHandler.fromUrl("hooktube.com/w/3msbfr6pBNE").getId()); assertEquals("3msbfr6pBNE", linkHandler.fromUrl("hooktube.com/embed/3msbfr6pBNE").getId()); } @Test - public void testAcceptInvidioUrl() throws ParsingException { + public void testAcceptInvidiousUrl() throws ParsingException { assertTrue(linkHandler.acceptUrl("https://invidio.us/watch?v=TglNG-yjabU")); assertTrue(linkHandler.acceptUrl("http://www.invidio.us/watch?v=TglNG-yjabU")); assertTrue(linkHandler.acceptUrl("http://invidio.us/watch?v=TglNG-yjabU")); assertTrue(linkHandler.acceptUrl("invidio.us/watch?v=3msbfr6pBNE")); assertTrue(linkHandler.acceptUrl("https://invidio.us/watch?v=ocH3oSnZG3c&test=PLS2VU1j4vzuZwooPjV26XM9UEBY2CPNn2")); assertTrue(linkHandler.acceptUrl("invidio.us/embed/3msbfr6pBNE")); + assertTrue(linkHandler.acceptUrl("invidio.us/watch/3msbfr6pBNE")); + assertTrue(linkHandler.acceptUrl("invidio.us/v/3msbfr6pBNE")); + assertTrue(linkHandler.acceptUrl("invidio.us/w/3msbfr6pBNE")); } @Test - public void testGetInvidioIdfromUrl() throws ParsingException { + public void testGetInvidiousIdfromUrl() throws ParsingException { assertEquals("TglNG-yjabU", linkHandler.fromUrl("https://invidio.us/watch?v=TglNG-yjabU").getId()); assertEquals("TglNG-yjabU", linkHandler.fromUrl("http://www.invidio.us/watch?v=TglNG-yjabU").getId()); assertEquals("TglNG-yjabU", linkHandler.fromUrl("http://invidio.us/watch?v=TglNG-yjabU").getId()); assertEquals("3msbfr6pBNE", linkHandler.fromUrl("invidio.us/watch?v=3msbfr6pBNE").getId()); assertEquals("ocH3oSnZG3c", linkHandler.fromUrl("https://invidio.us/watch?v=ocH3oSnZG3c&test=PLS2VU1j4vzuZwooPjV26XM9UEBY2CPNn2").getId()); assertEquals("3msbfr6pBNE", linkHandler.fromUrl("invidio.us/embed/3msbfr6pBNE").getId()); + assertEquals("3msbfr6pBNE", linkHandler.fromUrl("invidio.us/v/3msbfr6pBNE").getId()); + assertEquals("3msbfr6pBNE", linkHandler.fromUrl("invidio.us/w/3msbfr6pBNE").getId()); + assertEquals("3msbfr6pBNE", linkHandler.fromUrl("invidio.us/watch/3msbfr6pBNE").getId()); } } \ No newline at end of file