Extract stream and search meta info for YouTube
Add method to extract Google webcache URLs.
This commit is contained in:
@@ -1,12 +1,20 @@
|
||||
package org.schabi.newpipe.extractor.services;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.extractor.MetaInfo;
|
||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
|
||||
|
||||
@@ -20,6 +28,10 @@ public abstract class DefaultSearchExtractorTest extends DefaultListExtractorTes
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<MetaInfo> expectedMetaInfo() throws MalformedURLException {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testSearchString() throws Exception {
|
||||
@@ -41,4 +53,34 @@ public abstract class DefaultSearchExtractorTest extends DefaultListExtractorTes
|
||||
public void testSearchCorrected() throws Exception {
|
||||
assertEquals(isCorrectedSearch(), extractor().isCorrectedSearch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DefaultStreamExtractorTest#testMetaInfo()
|
||||
*/
|
||||
@Test
|
||||
public void testMetaInfo() throws Exception {
|
||||
final List<MetaInfo> metaInfoList = extractor().getMetaInfo();
|
||||
final List<MetaInfo> expectedMetaInfoList = expectedMetaInfo();
|
||||
|
||||
for (final MetaInfo expectedMetaInfo : expectedMetaInfoList) {
|
||||
final List<String> texts = metaInfoList.stream()
|
||||
.map(metaInfo -> metaInfo.getContent().getContent())
|
||||
.collect(Collectors.toList());
|
||||
final List<String> titles = metaInfoList.stream().map(MetaInfo::getTitle).collect(Collectors.toList());
|
||||
final List<URL> urls = metaInfoList.stream().flatMap(info -> info.getUrls().stream())
|
||||
.collect(Collectors.toList());
|
||||
final List<String> urlTexts = metaInfoList.stream().flatMap(info -> info.getUrlTexts().stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertTrue(texts.contains(expectedMetaInfo.getContent().getContent()));
|
||||
assertTrue(titles.contains(expectedMetaInfo.getTitle()));
|
||||
|
||||
for (final String expectedUrlText : expectedMetaInfo.getUrlTexts()) {
|
||||
assertTrue(urlTexts.contains(expectedUrlText));
|
||||
}
|
||||
for (final URL expectedUrl : expectedMetaInfo.getUrls()) {
|
||||
assertTrue(urls.contains(expectedUrl));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.schabi.newpipe.extractor.services;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.extractor.MediaFormat;
|
||||
import org.schabi.newpipe.extractor.MetaInfo;
|
||||
import org.schabi.newpipe.extractor.localization.DateWrapper;
|
||||
import org.schabi.newpipe.extractor.stream.AudioStream;
|
||||
import org.schabi.newpipe.extractor.stream.Description;
|
||||
@@ -15,9 +16,12 @@ import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import javax.annotation.Nullable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
@@ -67,6 +71,7 @@ public abstract class DefaultStreamExtractorTest extends DefaultExtractorTest<St
|
||||
public List<String> expectedTags() { return Collections.emptyList(); } // default: no tags
|
||||
public String expectedSupportInfo() { return ""; } // default: no support info available
|
||||
public int expectedStreamSegmentsCount() { return -1; } // return 0 or greater to test (default is -1 to ignore)
|
||||
public List<MetaInfo> expectedMetaInfo() throws MalformedURLException { return Collections.emptyList(); } // default: no metadata info available
|
||||
|
||||
@Test
|
||||
@Override
|
||||
@@ -387,4 +392,35 @@ public abstract class DefaultStreamExtractorTest extends DefaultExtractorTest<St
|
||||
assertEquals(expectedStreamSegmentsCount(), extractor().getStreamSegments().size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DefaultSearchExtractorTest#testMetaInfo()
|
||||
*/
|
||||
@Test
|
||||
public void testMetaInfo() throws Exception {
|
||||
final List<MetaInfo> metaInfoList = extractor().getMetaInfo();
|
||||
final List<MetaInfo> expectedMetaInfoList = expectedMetaInfo();
|
||||
|
||||
for (final MetaInfo expectedMetaInfo : expectedMetaInfoList) {
|
||||
final List<String> texts = metaInfoList.stream()
|
||||
.map((metaInfo) -> metaInfo.getContent().getContent())
|
||||
.collect(Collectors.toList());
|
||||
final List<String> titles = metaInfoList.stream().map(MetaInfo::getTitle).collect(Collectors.toList());
|
||||
final List<URL> urls = metaInfoList.stream().flatMap(info -> info.getUrls().stream())
|
||||
.collect(Collectors.toList());
|
||||
final List<String> urlTexts = metaInfoList.stream().flatMap(info -> info.getUrlTexts().stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertTrue(texts.contains(expectedMetaInfo.getContent().getContent()));
|
||||
assertTrue(titles.contains(expectedMetaInfo.getTitle()));
|
||||
|
||||
for (final String expectedUrlText : expectedMetaInfo.getUrlTexts()) {
|
||||
assertTrue(urlTexts.contains(expectedUrlText));
|
||||
}
|
||||
for (final URL expectedUrl : expectedMetaInfo.getUrls()) {
|
||||
assertTrue(urls.contains(expectedUrl));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,12 @@ public class YoutubeParsingHelperTest {
|
||||
assertEquals(4445767, YoutubeParsingHelper.parseDurationString("1,234:56:07"));
|
||||
assertEquals(754, YoutubeParsingHelper.parseDurationString("12:34 "));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertFromGoogleCacheUrl() throws ParsingException {
|
||||
assertEquals("https://mohfw.gov.in/",
|
||||
YoutubeParsingHelper.extractCachedUrlIfNeeded("https://webcache.googleusercontent.com/search?q=cache:https://mohfw.gov.in/"));
|
||||
assertEquals("https://www.infektionsschutz.de/coronavirus-sars-cov-2.html",
|
||||
YoutubeParsingHelper.extractCachedUrlIfNeeded("https://www.infektionsschutz.de/coronavirus-sars-cov-2.html"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,21 @@ package org.schabi.newpipe.extractor.services.youtube.search;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.DownloaderTestImpl;
|
||||
import org.schabi.newpipe.extractor.InfoItem;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.*;
|
||||
import org.schabi.newpipe.extractor.search.SearchExtractor;
|
||||
import org.schabi.newpipe.extractor.services.DefaultSearchExtractorTest;
|
||||
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
|
||||
import org.schabi.newpipe.extractor.stream.Description;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -211,4 +217,39 @@ public class YoutubeSearchExtractorTest {
|
||||
assertNoDuplicatedItems(YouTube, page1, page2);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MetaInfoTest extends DefaultSearchExtractorTest {
|
||||
private static SearchExtractor extractor;
|
||||
private static final String QUERY = "Covid";
|
||||
|
||||
@Test
|
||||
public void clarificationTest() throws Exception {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = YouTube.getSearchExtractor(QUERY, singletonList(VIDEOS), "");
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Override public String expectedSearchString() { return QUERY; }
|
||||
@Override public String expectedSearchSuggestion() { return null; }
|
||||
@Override public List<MetaInfo> expectedMetaInfo() throws MalformedURLException {
|
||||
final List<URL> urls = new ArrayList<>();
|
||||
urls.add(new URL("https://www.who.int/emergencies/diseases/novel-coronavirus-2019"));
|
||||
urls.add(new URL("https://www.who.int/emergencies/diseases/novel-coronavirus-2019/covid-19-vaccines"));
|
||||
final List<String> urlTexts = new ArrayList<>();
|
||||
urlTexts.add("LEARN MORE");
|
||||
urlTexts.add("Learn about vaccine progress from the WHO");
|
||||
return Collections.singletonList(new MetaInfo(
|
||||
"COVID-19",
|
||||
new Description("Get the latest information from the WHO about coronavirus.", Description.PLAIN_TEXT),
|
||||
urls,
|
||||
urlTexts
|
||||
));
|
||||
}
|
||||
@Override public SearchExtractor extractor() { return extractor; }
|
||||
@Override public StreamingService expectedService() { return YouTube; }
|
||||
@Override public String expectedName() { return QUERY; }
|
||||
@Override public String expectedId() { return QUERY; }
|
||||
@Override public String expectedUrlContains() { return "youtube.com/results?search_query=" + QUERY; }
|
||||
@Override public String expectedOriginalUrlContains() throws Exception { return "youtube.com/results?search_query=" + QUERY; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,22 @@ package org.schabi.newpipe.extractor.services.youtube.stream;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.schabi.newpipe.DownloaderTestImpl;
|
||||
import org.schabi.newpipe.extractor.MetaInfo;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.StreamingService;
|
||||
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.services.DefaultStreamExtractorTest;
|
||||
import org.schabi.newpipe.extractor.stream.Description;
|
||||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamSegment;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -258,4 +264,46 @@ public class YoutubeStreamExtractorDefaultTest {
|
||||
assertNotNull(segment.getPreviewUrl());
|
||||
}
|
||||
}
|
||||
|
||||
public static class PublicBroadcasterTest extends DefaultStreamExtractorTest {
|
||||
private static final String ID = "q6fgbYWsMgw";
|
||||
private static final int TIMESTAMP = 0;
|
||||
private static final String URL = BASE_URL + ID;
|
||||
private static StreamExtractor extractor;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
NewPipe.init(DownloaderTestImpl.getInstance());
|
||||
extractor = YouTube.getStreamExtractor(URL);
|
||||
extractor.fetchPage();
|
||||
}
|
||||
|
||||
@Override public StreamExtractor extractor() { return extractor; }
|
||||
@Override public StreamingService expectedService() { return YouTube; }
|
||||
@Override public String expectedName() { return "Was verbirgt sich am tiefsten Punkt des Ozeans?"; }
|
||||
@Override public String expectedId() { return ID; }
|
||||
@Override public String expectedUrlContains() { return BASE_URL + ID; }
|
||||
@Override public String expectedOriginalUrlContains() { return URL; }
|
||||
|
||||
@Override public StreamType expectedStreamType() { return StreamType.VIDEO_STREAM; }
|
||||
@Override public String expectedUploaderName() { return "Dinge Erklärt – Kurzgesagt"; }
|
||||
@Override public String expectedUploaderUrl() { return "https://www.youtube.com/channel/UCwRH985XgMYXQ6NxXDo8npw"; }
|
||||
@Override public List<String> expectedDescriptionContains() { return Arrays.asList("Lasst uns abtauchen!", "Angebot von funk", "Dinge"); }
|
||||
@Override public long expectedLength() { return 631; }
|
||||
@Override public long expectedTimestamp() { return TIMESTAMP; }
|
||||
@Override public long expectedViewCountAtLeast() { return 1_600_000; }
|
||||
@Nullable @Override public String expectedUploadDate() { return "2019-06-12 00:00:00.000"; }
|
||||
@Nullable @Override public String expectedTextualUploadDate() { return "2019-06-12"; }
|
||||
@Override public long expectedLikeCountAtLeast() { return 70000; }
|
||||
@Override public long expectedDislikeCountAtLeast() { return 500; }
|
||||
@Override public List<MetaInfo> expectedMetaInfo() throws MalformedURLException {
|
||||
return Collections.singletonList(new MetaInfo(
|
||||
"",
|
||||
new Description("Funk is a German public broadcast service.", Description.PLAIN_TEXT),
|
||||
Collections.singletonList(new URL("https://de.wikipedia.org/wiki/Funk_(Medienangebot)?wprov=yicw1")),
|
||||
Collections.singletonList("Wikipedia (German)")
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user