Don't use a regular expression to find the last segment URL and do code improvements

Apply suggestions provided in the PR and remove a redundant import.
This commit is contained in:
TiA4f8R 2021-03-14 17:53:08 +01:00
parent 0e3e420a25
commit 379d7312fa
No known key found for this signature in database
GPG key ID: E6D3E7F5949450DD

View file

@ -29,10 +29,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.schabi.newpipe.extractor.utils.Utils.HTTPS;
import static org.schabi.newpipe.extractor.utils.Utils.*; import static org.schabi.newpipe.extractor.utils.Utils.*;
public class SoundcloudStreamExtractor extends StreamExtractor { public class SoundcloudStreamExtractor extends StreamExtractor {
@ -198,7 +195,7 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
final JsonArray transcodings = track.getObject("media").getArray("transcodings"); final JsonArray transcodings = track.getObject("media").getArray("transcodings");
if (transcodings != null) { if (transcodings != null) {
// Get information about what stream formats are available // Get information about what stream formats are available
setUpAudioStreams(transcodings, checkMp3ProgressivePresence(transcodings), extractAudioStreams(transcodings, checkMp3ProgressivePresence(transcodings),
audioStreams); audioStreams);
} }
} catch (final NullPointerException e) { } catch (final NullPointerException e) {
@ -238,59 +235,61 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
if (protocol.equals("progressive")) { if (protocol.equals("progressive")) {
return urlString; return urlString;
} else if (protocol.equals("hls")) { } else if (protocol.equals("hls")) {
return getSingleUrlFromHlsManifest(urlString); try {
return getSingleUrlFromHlsManifest(urlString);
} catch (final ParsingException ignored) {
}
} }
// else, unknown protocol // else, unknown protocol
return ""; return "";
} }
private static void setUpAudioStreams(final JsonArray transcodings, private static void extractAudioStreams(final JsonArray transcodings,
final boolean mp3ProgressiveInStreams, final boolean mp3ProgressiveInStreams,
final List<AudioStream> audioStreams) { final List<AudioStream> audioStreams) {
for (final Object transcoding : transcodings) { for (final Object transcoding : transcodings) {
final JsonObject transcodingJsonObject = (JsonObject) transcoding; final JsonObject transcodingJsonObject = (JsonObject) transcoding;
final String url = transcodingJsonObject.getString("url");
if (isNullOrEmpty(url)) {
continue;
}
final String mediaUrl; final String mediaUrl;
final String preset = transcodingJsonObject.getString("preset"); final String preset = transcodingJsonObject.getString("preset");
final String protocol = transcodingJsonObject.getObject("format").getString("protocol"); final String protocol = transcodingJsonObject.getObject("format").getString("protocol");
final String url = transcodingJsonObject.getString("url"); MediaFormat mediaFormat = null;
final MediaFormat mediaFormat; int bitrate = 0;
final int bitrate; if (preset.contains("mp3")) {
// Don't add the MP3 HLS stream if there is a progressive stream present
if (!isNullOrEmpty(url)) { // because the two have the same bitrate
if (preset.contains("mp3")) { if (mp3ProgressiveInStreams && protocol.equals("hls")) {
// Don't add the MP3 HLS stream if there is a progressive stream present
// because the two have the same bitrate
if (mp3ProgressiveInStreams && protocol.equals("hls")) {
continue;
}
mediaFormat = MediaFormat.MP3;
bitrate = 128;
} else if (preset.contains("opus")) {
mediaFormat = MediaFormat.OPUS;
bitrate = 64;
} else {
// Unknown format
continue; continue;
} }
mediaFormat = MediaFormat.MP3;
bitrate = 128;
} else if (preset.contains("opus")) {
mediaFormat = MediaFormat.OPUS;
bitrate = 64;
}
if (mediaFormat != null) {
try { try {
mediaUrl = getTranscodingUrl(url, protocol); mediaUrl = getTranscodingUrl(url, protocol);
} catch (final Exception e) { if (!mediaUrl.isEmpty()) {
// something went wrong when parsing this transcoding audioStreams.add(new AudioStream(mediaUrl, mediaFormat, bitrate));
continue; }
} catch (final Exception ignored) {
// something went wrong when parsing this transcoding, don't add it to
// audioStreams
} }
audioStreams.add(new AudioStream(mediaUrl, mediaFormat, bitrate));
} }
} }
} }
private final static Pattern PATTERN_HTTPS_URLS_IN_HLS_MANIFESTS = Pattern.compile("((https?):((//)|(\\\\))+[\\w\\d:#@%/;$()~_?+-=\\\\.&]*)");
/** Parses a SoundCloud HLS manifest to get a single URL of HLS streams. /** Parses a SoundCloud HLS manifest to get a single URL of HLS streams.
* <p> * <p>
* This method downloads the provided manifest URL, find all web occurrences using a regex, get * This method downloads the provided manifest URL, find all web occurrences in the manifest,
* the last segment URL, changes its segment range to {@code 0/track-length} and return this * get the last segment URL, changes its segment range to {@code 0/track-length} and return
* string. * this string.
* @param hlsManifestUrl the URL of the manifest to be parsed * @param hlsManifestUrl the URL of the manifest to be parsed
* @return a single URL that contains a range equal to the length of the track * @return a single URL that contains a range equal to the length of the track
*/ */
@ -304,20 +303,17 @@ public class SoundcloudStreamExtractor extends StreamExtractor {
throw new ParsingException("Could not get SoundCloud HLS manifest"); throw new ParsingException("Could not get SoundCloud HLS manifest");
} }
final List<String> hlsRangesList = new ArrayList<>(); final String[] lines = hlsManifestResponse.split("\\r?\\n");
final Matcher pattern_matches = PATTERN_HTTPS_URLS_IN_HLS_MANIFESTS for (int l = lines.length - 1; l >= 0; l--) {
.matcher(hlsManifestResponse); final String line = lines[l];
// get the last URL from manifest, because it contains the range of the stream
while (pattern_matches.find()) { if (line.trim().length() != 0 && !line.startsWith("#") && line.startsWith("https")) {
hlsRangesList.add(hlsManifestResponse.substring(pattern_matches.start(0), final String[] hlsLastRangeUrlArray = line.split("/");
pattern_matches.end(0))); return HTTPS + hlsLastRangeUrlArray[2] + "/media/0/" + hlsLastRangeUrlArray[5] + "/"
+ hlsLastRangeUrlArray[6];
}
} }
throw new ParsingException("Could not get any URL from HLS manifest");
final String hlsLastRangeUrl = hlsRangesList.get(hlsRangesList.size() - 1);
final String[] hlsLastRangeUrlArray = hlsLastRangeUrl.split("/");
return HTTPS + hlsLastRangeUrlArray[2] + "/media/0/" + hlsLastRangeUrlArray[5] + "/"
+ hlsLastRangeUrlArray[6];
} }
private static String urlEncode(final String value) { private static String urlEncode(final String value) {