Merge pull request #300 from B0pol/hls_opus_not_supported

throw ContentNotSupportedException when content is known to be unsuppo…
This commit is contained in:
wb9688 2020-04-08 19:54:16 +02:00 committed by GitHub
commit a5155fb562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 166 additions and 102 deletions

View File

@ -0,0 +1,11 @@
package org.schabi.newpipe.extractor.exceptions;
public class ContentNotSupportedException extends ParsingException {
public ContentNotSupportedException(String message) {
super(message);
}
public ContentNotSupportedException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -10,6 +10,7 @@ import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
@ -196,6 +197,10 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
throw new ExtractionException("Could not get SoundCloud's track audio url", e); throw new ExtractionException("Could not get SoundCloud's track audio url", e);
} }
if (audioStreams.isEmpty()) {
throw new ContentNotSupportedException("HLS audio streams are not yet supported");
}
return audioStreams; return audioStreams;
} }

View File

@ -5,6 +5,7 @@ import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.channel.ChannelExtractor; import org.schabi.newpipe.extractor.channel.ChannelExtractor;
import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
@ -310,7 +311,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
} }
if (videoTab == null) { if (videoTab == null) {
throw new ParsingException("Could not find Videos tab"); throw new ContentNotSupportedException("This channel has no Videos tab");
} }
try { try {

View File

@ -1,5 +1,6 @@
package org.schabi.newpipe.extractor.services.youtube.linkHandler; 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.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils; import org.schabi.newpipe.extractor.utils.Utils;
@ -47,7 +48,7 @@ public class YoutubePlaylistLinkHandlerFactory extends ListLinkHandlerFactory {
// Don't accept auto-generated "Mix" playlists but auto-generated YouTube Music playlists // Don't accept auto-generated "Mix" playlists but auto-generated YouTube Music playlists
if (listID.startsWith("RD") && !listID.startsWith("RDCLAK")) { if (listID.startsWith("RD") && !listID.startsWith("RDCLAK")) {
throw new ParsingException("YouTube Mix playlists are not yet supported"); throw new ContentNotSupportedException("YouTube Mix playlists are not yet supported");
} }
return listID; return listID;

View File

@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.utils.DashMpdParser; import org.schabi.newpipe.extractor.utils.DashMpdParser;
@ -47,7 +48,7 @@ public class StreamInfo extends Info {
} }
public StreamInfo(int serviceId, String url, String originalUrl, StreamType streamType, String id, String name, public StreamInfo(int serviceId, String url, String originalUrl, StreamType streamType, String id, String name,
int ageLimit) { int ageLimit) {
super(serviceId, id, url, originalUrl, name); super(serviceId, id, url, originalUrl, name);
this.streamType = streamType; this.streamType = streamType;
this.ageLimit = ageLimit; this.ageLimit = ageLimit;
@ -131,6 +132,8 @@ public class StreamInfo extends Info {
/* Load and extract audio */ /* Load and extract audio */
try { try {
streamInfo.setAudioStreams(extractor.getAudioStreams()); streamInfo.setAudioStreams(extractor.getAudioStreams());
} catch (ContentNotSupportedException e) {
throw e;
} catch (Exception e) { } catch (Exception e) {
streamInfo.addError(new ExtractionException("Couldn't get audio streams", e)); streamInfo.addError(new ExtractionException("Couldn't get audio streams", e));
} }

View File

@ -5,6 +5,7 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.stream.StreamExtractor;
@ -25,107 +26,134 @@ import static org.schabi.newpipe.extractor.ServiceList.SoundCloud;
* Test for {@link StreamExtractor} * Test for {@link StreamExtractor}
*/ */
public class SoundcloudStreamExtractorDefaultTest { public class SoundcloudStreamExtractorDefaultTest {
private static SoundcloudStreamExtractor extractor;
@BeforeClass public static class LilUziVertDoWhatIWant {
public static void setUp() throws Exception { private static SoundcloudStreamExtractor extractor;
NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (SoundcloudStreamExtractor) SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon"); @BeforeClass
extractor.fetchPage(); public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
extractor = (SoundcloudStreamExtractor) SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon");
extractor.fetchPage();
}
@Test
public void testGetInvalidTimeStamp() throws ParsingException {
assertTrue(extractor.getTimeStamp() + "",
extractor.getTimeStamp() <= 0);
}
@Test
public void testGetValidTimeStamp() throws IOException, ExtractionException {
StreamExtractor extractor = SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon#t=69");
assertEquals("69", extractor.getTimeStamp() + "");
}
@Test
public void testGetTitle() throws ParsingException {
assertEquals("Do What I Want [Produced By Maaly Raw + Don Cannon]", extractor.getName());
}
@Test
public void testGetDescription() throws ParsingException {
assertEquals("The Perfect LUV Tape®", extractor.getDescription().getContent());
}
@Test
public void testGetUploaderName() throws ParsingException {
assertEquals("LIL UZI VERT", extractor.getUploaderName());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(175, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
assertTrue(Long.toString(extractor.getViewCount()),
extractor.getViewCount() > 44227978);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2016-07-31 18:18:07", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse("2016/07/31 18:18:07 +0000"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderUrl());
assertEquals("https://soundcloud.com/liluzivert", extractor.getUploaderUrl());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws IOException, ExtractionException {
assertFalse(extractor.getAudioStreams().isEmpty());
}
@Test
public void testStreamType() throws ParsingException {
assertTrue(extractor.getStreamType() == StreamType.AUDIO_STREAM);
}
@Test
public void testGetRelatedVideos() throws ExtractionException, IOException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
} }
@Test public static class ContentNotSupported {
public void testGetInvalidTimeStamp() throws ParsingException { @BeforeClass
assertTrue(extractor.getTimeStamp() + "", public static void setUp() {
extractor.getTimeStamp() <= 0); NewPipe.init(DownloaderTestImpl.getInstance());
} }
@Test @Test(expected = ContentNotSupportedException.class)
public void testGetValidTimeStamp() throws IOException, ExtractionException { public void hlsAudioStream() throws Exception {
StreamExtractor extractor = SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon#t=69"); final StreamExtractor extractor =
assertEquals("69", extractor.getTimeStamp() + ""); SoundCloud.getStreamExtractor("https://soundcloud.com/dualipa/cool");
} extractor.fetchPage();
extractor.getAudioStreams();
}
@Test @Test(expected = ContentNotSupportedException.class)
public void testGetTitle() throws ParsingException { public void bothHlsAndOpusAudioStreams() throws Exception {
assertEquals("Do What I Want [Produced By Maaly Raw + Don Cannon]", extractor.getName()); final StreamExtractor extractor =
} SoundCloud.getStreamExtractor("https://soundcloud.com/lil-baby-4pf/no-sucker");
extractor.fetchPage();
@Test extractor.getAudioStreams();
public void testGetDescription() throws ParsingException { }
assertEquals("The Perfect LUV Tape®", extractor.getDescription().getContent());
}
@Test
public void testGetUploaderName() throws ParsingException {
assertEquals("LIL UZI VERT", extractor.getUploaderName());
}
@Test
public void testGetLength() throws ParsingException {
assertEquals(175, extractor.getLength());
}
@Test
public void testGetViewCount() throws ParsingException {
assertTrue(Long.toString(extractor.getViewCount()),
extractor.getViewCount() > 44227978);
}
@Test
public void testGetTextualUploadDate() throws ParsingException {
Assert.assertEquals("2016-07-31 18:18:07", extractor.getTextualUploadDate());
}
@Test
public void testGetUploadDate() throws ParsingException, ParseException {
final Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse("2016/07/31 18:18:07 +0000"));
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
}
@Test
public void testGetUploaderUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderUrl());
assertEquals("https://soundcloud.com/liluzivert", extractor.getUploaderUrl());
}
@Test
public void testGetThumbnailUrl() throws ParsingException {
assertIsSecureUrl(extractor.getThumbnailUrl());
}
@Test
public void testGetUploaderAvatarUrl() throws ParsingException {
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
}
@Test
public void testGetAudioStreams() throws IOException, ExtractionException {
assertFalse(extractor.getAudioStreams().isEmpty());
}
@Test
public void testStreamType() throws ParsingException {
assertTrue(extractor.getStreamType() == StreamType.AUDIO_STREAM);
}
@Test
public void testGetRelatedVideos() throws ExtractionException, IOException {
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
assertFalse(relatedVideos.getItems().isEmpty());
assertTrue(relatedVideos.getErrors().isEmpty());
}
@Test
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
}
@Test
public void testGetSubtitlesList() throws IOException, ExtractionException {
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
assertTrue(extractor.getSubtitlesDefault().isEmpty());
} }
} }

View File

@ -5,13 +5,14 @@ import org.junit.Test;
import org.schabi.newpipe.DownloaderTestImpl; import org.schabi.newpipe.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.channel.ChannelExtractor; import org.schabi.newpipe.extractor.channel.ChannelExtractor;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.services.BaseChannelExtractorTest; import org.schabi.newpipe.extractor.services.BaseChannelExtractorTest;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelExtractor; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelExtractor;
import java.util.List; import java.io.IOException;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty; import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty;
@ -45,6 +46,20 @@ public class YoutubeChannelExtractorTest {
} }
} }
public static class NotSupported {
@BeforeClass
public static void setUp() {
NewPipe.init(DownloaderTestImpl.getInstance());
}
@Test(expected = ContentNotSupportedException.class)
public void noVideoTab() throws Exception {
final ChannelExtractor extractor = YouTube.getChannelExtractor("https://invidio.us/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ");
extractor.fetchPage();
extractor.getInitialPage();
}
}
public static class Gronkh implements BaseChannelExtractorTest { public static class Gronkh implements BaseChannelExtractorTest {
private static YoutubeChannelExtractor extractor; private static YoutubeChannelExtractor extractor;