diff --git a/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractor.java b/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractor.java index c4a42414..d323a262 100644 --- a/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractor.java +++ b/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudStreamExtractor.java @@ -7,12 +7,13 @@ import org.schabi.newpipe.extractor.*; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; -import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.stream.*; -import org.schabi.newpipe.extractor.utils.Parser; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.*; public class SoundcloudStreamExtractor extends StreamExtractor { @@ -127,8 +128,8 @@ public class SoundcloudStreamExtractor extends StreamExtractor { List audioStreams = new ArrayList<>(); Downloader dl = NewPipe.getDownloader(); - String apiUrl = "https://api.soundcloud.com/i1/tracks/" + getId() + "/streams" - + "?client_id=" + SoundcloudParsingHelper.clientId(); + String apiUrl = "https://api.soundcloud.com/i1/tracks/" + urlEncode(getId()) + "/streams" + + "?client_id=" + urlEncode(SoundcloudParsingHelper.clientId()); String response = dl.download(apiUrl); JsonObject responseObject; @@ -148,6 +149,14 @@ public class SoundcloudStreamExtractor extends StreamExtractor { return audioStreams; } + private static String urlEncode(String value) { + try { + return URLEncoder.encode(value, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException(e); + } + } + @Override public List getVideoStreams() throws IOException, ExtractionException { return null; @@ -159,11 +168,13 @@ public class SoundcloudStreamExtractor extends StreamExtractor { } @Override + @Nullable public List getSubtitlesDefault() throws IOException, ExtractionException { return null; } @Override + @Nullable public List getSubtitles(SubtitlesFormat format) throws IOException, ExtractionException { return null; } @@ -182,8 +193,8 @@ public class SoundcloudStreamExtractor extends StreamExtractor { public StreamInfoItemCollector getRelatedVideos() throws IOException, ExtractionException { StreamInfoItemCollector collector = new StreamInfoItemCollector(getServiceId()); - String apiUrl = "https://api-v2.soundcloud.com/tracks/" + getId() + "/related" - + "?client_id=" + SoundcloudParsingHelper.clientId(); + String apiUrl = "https://api-v2.soundcloud.com/tracks/" + urlEncode(getId()) + "/related" + + "?client_id=" + urlEncode(SoundcloudParsingHelper.clientId()); SoundcloudParsingHelper.getStreamsFromApi(collector, apiUrl); return collector; diff --git a/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java b/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java index c7e96a2f..0f93508e 100644 --- a/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java +++ b/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java @@ -403,11 +403,13 @@ public class YoutubeStreamExtractor extends StreamExtractor { } @Override + @Nullable public List getSubtitlesDefault() throws IOException, ExtractionException { return getSubtitles(SubtitlesFormat.TTML); } @Override + @Nullable public List getSubtitles(SubtitlesFormat format) throws IOException, ExtractionException { JsonObject playerConfig = getPlayerConfig(getPageHtml()); String playerResponse = playerConfig.getObject("args").getString("player_response"); diff --git a/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java b/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java index f77fcbc8..61df951f 100644 --- a/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java +++ b/src/main/java/org/schabi/newpipe/extractor/stream/StreamExtractor.java @@ -20,17 +20,16 @@ package org.schabi.newpipe.extractor.stream; * along with NewPipe. If not, see . */ -import com.grack.nanojson.JsonParserException; import org.schabi.newpipe.extractor.Extractor; import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.Subtitles; import org.schabi.newpipe.extractor.UrlIdHandler; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; -import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.utils.Parser; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.io.IOException; import java.util.List; @@ -57,6 +56,12 @@ public abstract class StreamExtractor extends Extractor { public abstract String getThumbnailUrl() throws ParsingException; @Nonnull public abstract String getDescription() throws ParsingException; + + /** + * Get the age limit + * @return The age which limits the content or {@value NO_AGE_LIMIT} if there is no limit + * @throws ParsingException if an error occurs while parsing + */ public abstract int getAgeLimit() throws ParsingException; public abstract long getLength() throws ParsingException; @@ -126,7 +131,11 @@ public abstract class StreamExtractor extends Extractor { public abstract List getAudioStreams() throws IOException, ExtractionException; public abstract List getVideoStreams() throws IOException, ExtractionException; public abstract List getVideoOnlyStreams() throws IOException, ExtractionException; + + @Nullable public abstract List getSubtitlesDefault() throws IOException, ExtractionException; + + @Nullable public abstract List getSubtitles(SubtitlesFormat format) throws IOException, ExtractionException; public abstract StreamType getStreamType() throws ParsingException; diff --git a/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractorRestrictedTest.java b/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractorRestrictedTest.java index f914519a..1c362d5d 100644 --- a/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractorRestrictedTest.java +++ b/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractorRestrictedTest.java @@ -116,12 +116,12 @@ public class YoutubeStreamExtractorRestrictedTest { @Test public void testGetSubtitlesListDefault() throws IOException, ExtractionException { // Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null - assertTrue(extractor.getSubtitlesDefault() == null); + assertNull(extractor.getSubtitlesDefault()); } @Test public void testGetSubtitlesList() throws IOException, ExtractionException { // Video (/view?v=YQHsXMglC9A) set in the setUp() method has no captions => null - assertTrue(extractor.getSubtitles(SubtitlesFormat.VTT) == null); + assertNull(extractor.getSubtitles(SubtitlesFormat.VTT)); } }