Skip to content

Commit a5155fb

Browse files
authored
Merge pull request #300 from B0pol/hls_opus_not_supported
throw ContentNotSupportedException when content is known to be unsuppo…
2 parents 094b87c + a20d53d commit a5155fb

7 files changed

Lines changed: 170 additions & 106 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.schabi.newpipe.extractor.exceptions;
2+
3+
public class ContentNotSupportedException extends ParsingException {
4+
public ContentNotSupportedException(String message) {
5+
super(message);
6+
}
7+
8+
public ContentNotSupportedException(String message, Throwable cause) {
9+
super(message, cause);
10+
}
11+
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.schabi.newpipe.extractor.StreamingService;
1111
import org.schabi.newpipe.extractor.downloader.Downloader;
1212
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
13+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
1314
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
1415
import org.schabi.newpipe.extractor.exceptions.ParsingException;
1516
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
@@ -196,6 +197,10 @@ public List<AudioStream> getAudioStreams() throws IOException, ExtractionExcepti
196197
throw new ExtractionException("Could not get SoundCloud's track audio url", e);
197198
}
198199

200+
if (audioStreams.isEmpty()) {
201+
throw new ContentNotSupportedException("HLS audio streams are not yet supported");
202+
}
203+
199204
return audioStreams;
200205
}
201206

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeChannelExtractor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.schabi.newpipe.extractor.StreamingService;
66
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
77
import org.schabi.newpipe.extractor.downloader.Downloader;
8+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
89
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
910
import org.schabi.newpipe.extractor.exceptions.ParsingException;
1011
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
@@ -310,7 +311,7 @@ private JsonObject getVideoTab() throws ParsingException {
310311
}
311312

312313
if (videoTab == null) {
313-
throw new ParsingException("Could not find Videos tab");
314+
throw new ContentNotSupportedException("This channel has no Videos tab");
314315
}
315316

316317
try {

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/linkHandler/YoutubePlaylistLinkHandlerFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.schabi.newpipe.extractor.services.youtube.linkHandler;
22

3+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
34
import org.schabi.newpipe.extractor.exceptions.ParsingException;
45
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
56
import org.schabi.newpipe.extractor.utils.Utils;
@@ -47,7 +48,7 @@ public String getId(String url) throws ParsingException {
4748

4849
// Don't accept auto-generated "Mix" playlists but auto-generated YouTube Music playlists
4950
if (listID.startsWith("RD") && !listID.startsWith("RDCLAK")) {
50-
throw new ParsingException("YouTube Mix playlists are not yet supported");
51+
throw new ContentNotSupportedException("YouTube Mix playlists are not yet supported");
5152
}
5253

5354
return listID;

extractor/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfo.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.schabi.newpipe.extractor.NewPipe;
66
import org.schabi.newpipe.extractor.StreamingService;
77
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
8+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
89
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
910
import org.schabi.newpipe.extractor.localization.DateWrapper;
1011
import org.schabi.newpipe.extractor.utils.DashMpdParser;
@@ -47,7 +48,7 @@ public static class StreamExtractException extends ExtractionException {
4748
}
4849

4950
public StreamInfo(int serviceId, String url, String originalUrl, StreamType streamType, String id, String name,
50-
int ageLimit) {
51+
int ageLimit) {
5152
super(serviceId, id, url, originalUrl, name);
5253
this.streamType = streamType;
5354
this.ageLimit = ageLimit;
@@ -131,6 +132,8 @@ private static StreamInfo extractStreams(StreamInfo streamInfo, StreamExtractor
131132
/* Load and extract audio */
132133
try {
133134
streamInfo.setAudioStreams(extractor.getAudioStreams());
135+
} catch (ContentNotSupportedException e) {
136+
throw e;
134137
} catch (Exception e) {
135138
streamInfo.addError(new ExtractionException("Couldn't get audio streams", e));
136139
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractorDefaultTest.java

Lines changed: 129 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.junit.Test;
66
import org.schabi.newpipe.DownloaderTestImpl;
77
import org.schabi.newpipe.extractor.NewPipe;
8+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
89
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
910
import org.schabi.newpipe.extractor.exceptions.ParsingException;
1011
import org.schabi.newpipe.extractor.stream.StreamExtractor;
@@ -25,107 +26,134 @@
2526
* Test for {@link StreamExtractor}
2627
*/
2728
public class SoundcloudStreamExtractorDefaultTest {
28-
private static SoundcloudStreamExtractor extractor;
2929

30-
@BeforeClass
31-
public static void setUp() throws Exception {
32-
NewPipe.init(DownloaderTestImpl.getInstance());
33-
extractor = (SoundcloudStreamExtractor) SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon");
34-
extractor.fetchPage();
35-
}
36-
37-
@Test
38-
public void testGetInvalidTimeStamp() throws ParsingException {
39-
assertTrue(extractor.getTimeStamp() + "",
40-
extractor.getTimeStamp() <= 0);
41-
}
42-
43-
@Test
44-
public void testGetValidTimeStamp() throws IOException, ExtractionException {
45-
StreamExtractor extractor = SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon#t=69");
46-
assertEquals("69", extractor.getTimeStamp() + "");
47-
}
48-
49-
@Test
50-
public void testGetTitle() throws ParsingException {
51-
assertEquals("Do What I Want [Produced By Maaly Raw + Don Cannon]", extractor.getName());
52-
}
53-
54-
@Test
55-
public void testGetDescription() throws ParsingException {
56-
assertEquals("The Perfect LUV Tape®️", extractor.getDescription().getContent());
57-
}
58-
59-
@Test
60-
public void testGetUploaderName() throws ParsingException {
61-
assertEquals("LIL UZI VERT", extractor.getUploaderName());
62-
}
63-
64-
@Test
65-
public void testGetLength() throws ParsingException {
66-
assertEquals(175, extractor.getLength());
67-
}
68-
69-
@Test
70-
public void testGetViewCount() throws ParsingException {
71-
assertTrue(Long.toString(extractor.getViewCount()),
72-
extractor.getViewCount() > 44227978);
73-
}
74-
75-
@Test
76-
public void testGetTextualUploadDate() throws ParsingException {
77-
Assert.assertEquals("2016-07-31 18:18:07", extractor.getTextualUploadDate());
78-
}
79-
80-
@Test
81-
public void testGetUploadDate() throws ParsingException, ParseException {
82-
final Calendar instance = Calendar.getInstance();
83-
instance.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse("2016/07/31 18:18:07 +0000"));
84-
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
85-
}
86-
87-
@Test
88-
public void testGetUploaderUrl() throws ParsingException {
89-
assertIsSecureUrl(extractor.getUploaderUrl());
90-
assertEquals("https://soundcloud.com/liluzivert", extractor.getUploaderUrl());
91-
}
92-
93-
@Test
94-
public void testGetThumbnailUrl() throws ParsingException {
95-
assertIsSecureUrl(extractor.getThumbnailUrl());
96-
}
97-
98-
@Test
99-
public void testGetUploaderAvatarUrl() throws ParsingException {
100-
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
101-
}
102-
103-
@Test
104-
public void testGetAudioStreams() throws IOException, ExtractionException {
105-
assertFalse(extractor.getAudioStreams().isEmpty());
106-
}
107-
108-
@Test
109-
public void testStreamType() throws ParsingException {
110-
assertTrue(extractor.getStreamType() == StreamType.AUDIO_STREAM);
111-
}
112-
113-
@Test
114-
public void testGetRelatedVideos() throws ExtractionException, IOException {
115-
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
116-
assertFalse(relatedVideos.getItems().isEmpty());
117-
assertTrue(relatedVideos.getErrors().isEmpty());
118-
}
119-
120-
@Test
121-
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
122-
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
123-
assertTrue(extractor.getSubtitlesDefault().isEmpty());
124-
}
125-
126-
@Test
127-
public void testGetSubtitlesList() throws IOException, ExtractionException {
128-
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
129-
assertTrue(extractor.getSubtitlesDefault().isEmpty());
30+
public static class LilUziVertDoWhatIWant {
31+
private static SoundcloudStreamExtractor extractor;
32+
33+
@BeforeClass
34+
public static void setUp() throws Exception {
35+
NewPipe.init(DownloaderTestImpl.getInstance());
36+
extractor = (SoundcloudStreamExtractor) SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon");
37+
extractor.fetchPage();
38+
}
39+
40+
@Test
41+
public void testGetInvalidTimeStamp() throws ParsingException {
42+
assertTrue(extractor.getTimeStamp() + "",
43+
extractor.getTimeStamp() <= 0);
44+
}
45+
46+
@Test
47+
public void testGetValidTimeStamp() throws IOException, ExtractionException {
48+
StreamExtractor extractor = SoundCloud.getStreamExtractor("https://soundcloud.com/liluzivert/do-what-i-want-produced-by-maaly-raw-don-cannon#t=69");
49+
assertEquals("69", extractor.getTimeStamp() + "");
50+
}
51+
52+
@Test
53+
public void testGetTitle() throws ParsingException {
54+
assertEquals("Do What I Want [Produced By Maaly Raw + Don Cannon]", extractor.getName());
55+
}
56+
57+
@Test
58+
public void testGetDescription() throws ParsingException {
59+
assertEquals("The Perfect LUV Tape®️", extractor.getDescription().getContent());
60+
}
61+
62+
@Test
63+
public void testGetUploaderName() throws ParsingException {
64+
assertEquals("LIL UZI VERT", extractor.getUploaderName());
65+
}
66+
67+
@Test
68+
public void testGetLength() throws ParsingException {
69+
assertEquals(175, extractor.getLength());
70+
}
71+
72+
@Test
73+
public void testGetViewCount() throws ParsingException {
74+
assertTrue(Long.toString(extractor.getViewCount()),
75+
extractor.getViewCount() > 44227978);
76+
}
77+
78+
@Test
79+
public void testGetTextualUploadDate() throws ParsingException {
80+
Assert.assertEquals("2016-07-31 18:18:07", extractor.getTextualUploadDate());
81+
}
82+
83+
@Test
84+
public void testGetUploadDate() throws ParsingException, ParseException {
85+
final Calendar instance = Calendar.getInstance();
86+
instance.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss +0000").parse("2016/07/31 18:18:07 +0000"));
87+
assertEquals(instance, requireNonNull(extractor.getUploadDate()).date());
88+
}
89+
90+
@Test
91+
public void testGetUploaderUrl() throws ParsingException {
92+
assertIsSecureUrl(extractor.getUploaderUrl());
93+
assertEquals("https://soundcloud.com/liluzivert", extractor.getUploaderUrl());
94+
}
95+
96+
@Test
97+
public void testGetThumbnailUrl() throws ParsingException {
98+
assertIsSecureUrl(extractor.getThumbnailUrl());
99+
}
100+
101+
@Test
102+
public void testGetUploaderAvatarUrl() throws ParsingException {
103+
assertIsSecureUrl(extractor.getUploaderAvatarUrl());
104+
}
105+
106+
@Test
107+
public void testGetAudioStreams() throws IOException, ExtractionException {
108+
assertFalse(extractor.getAudioStreams().isEmpty());
109+
}
110+
111+
@Test
112+
public void testStreamType() throws ParsingException {
113+
assertTrue(extractor.getStreamType() == StreamType.AUDIO_STREAM);
114+
}
115+
116+
@Test
117+
public void testGetRelatedVideos() throws ExtractionException, IOException {
118+
StreamInfoItemsCollector relatedVideos = extractor.getRelatedStreams();
119+
assertFalse(relatedVideos.getItems().isEmpty());
120+
assertTrue(relatedVideos.getErrors().isEmpty());
121+
}
122+
123+
@Test
124+
public void testGetSubtitlesListDefault() throws IOException, ExtractionException {
125+
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
126+
assertTrue(extractor.getSubtitlesDefault().isEmpty());
127+
}
128+
129+
@Test
130+
public void testGetSubtitlesList() throws IOException, ExtractionException {
131+
// Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null
132+
assertTrue(extractor.getSubtitlesDefault().isEmpty());
133+
}
134+
}
135+
136+
public static class ContentNotSupported {
137+
@BeforeClass
138+
public static void setUp() {
139+
NewPipe.init(DownloaderTestImpl.getInstance());
140+
}
141+
142+
@Test(expected = ContentNotSupportedException.class)
143+
public void hlsAudioStream() throws Exception {
144+
final StreamExtractor extractor =
145+
SoundCloud.getStreamExtractor("https://soundcloud.com/dualipa/cool");
146+
extractor.fetchPage();
147+
extractor.getAudioStreams();
148+
}
149+
150+
@Test(expected = ContentNotSupportedException.class)
151+
public void bothHlsAndOpusAudioStreams() throws Exception {
152+
final StreamExtractor extractor =
153+
SoundCloud.getStreamExtractor("https://soundcloud.com/lil-baby-4pf/no-sucker");
154+
extractor.fetchPage();
155+
extractor.getAudioStreams();
156+
}
130157
}
131158
}
159+

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeChannelExtractorTest.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
import org.schabi.newpipe.DownloaderTestImpl;
66
import org.schabi.newpipe.extractor.NewPipe;
77
import org.schabi.newpipe.extractor.channel.ChannelExtractor;
8-
import org.schabi.newpipe.extractor.channel.ChannelInfo;
98
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
9+
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
10+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
1011
import org.schabi.newpipe.extractor.exceptions.ParsingException;
1112
import org.schabi.newpipe.extractor.services.BaseChannelExtractorTest;
1213
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeChannelExtractor;
1314

14-
import java.util.List;
15+
import java.io.IOException;
1516

1617
import static org.junit.Assert.*;
1718
import static org.schabi.newpipe.extractor.ExtractorAsserts.assertEmpty;
@@ -45,6 +46,20 @@ public void nonExistentFetch() throws Exception {
4546
}
4647
}
4748

49+
public static class NotSupported {
50+
@BeforeClass
51+
public static void setUp() {
52+
NewPipe.init(DownloaderTestImpl.getInstance());
53+
}
54+
55+
@Test(expected = ContentNotSupportedException.class)
56+
public void noVideoTab() throws Exception {
57+
final ChannelExtractor extractor = YouTube.getChannelExtractor("https://invidio.us/channel/UC-9-kyTW8ZkZNDHQJ6FgpwQ");
58+
extractor.fetchPage();
59+
extractor.getInitialPage();
60+
}
61+
}
62+
4863
public static class Gronkh implements BaseChannelExtractorTest {
4964
private static YoutubeChannelExtractor extractor;
5065

0 commit comments

Comments
 (0)