Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly support other delivery methods #367

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ public List<AudioStream> getAudioStreams() throws ExtractionException {
throw new ExtractionException("Unknown media format: " + mimeType);
}

audioStreams.add(new AudioStream(recording.getString("recording_url"),
mediaFormat, -1));
audioStreams.add(new AudioStream(recording.getString("filename"),
recording.getString("recording_url"), mediaFormat, -1));
}
}
return audioStreams;
Expand All @@ -185,8 +185,9 @@ public List<VideoStream> getVideoStreams() throws ExtractionException {
throw new ExtractionException("Unknown media format: " + mimeType);
}

videoStreams.add(new VideoStream(recording.getString("recording_url"),
mediaFormat, recording.getInt("height") + "p"));
videoStreams.add(new VideoStream(recording.getString("filename"),
recording.getString("recording_url"), mediaFormat,
recording.getInt("height") + "p", false));
}
}
return videoStreams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import org.schabi.newpipe.extractor.services.peertube.PeertubeParsingHelper;
import org.schabi.newpipe.extractor.services.peertube.linkHandler.PeertubeSearchQueryHandlerFactory;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.DeliveryMethod;
import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.stream.Stream;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
import org.schabi.newpipe.extractor.stream.StreamType;
Expand Down Expand Up @@ -202,10 +202,9 @@ public List<VideoStream> getVideoStreams() throws ExtractionException {
final String resolution = JsonUtils.getString(stream, "resolution.label");
final String extension = url.substring(url.lastIndexOf(".") + 1);
final MediaFormat format = MediaFormat.getFromSuffix(extension);
final VideoStream videoStream = new VideoStream(url, torrentUrl, format, resolution);
if (!Stream.containSimilarStream(videoStream, videoStreams)) {
videoStreams.add(videoStream);
}
final String id = resolution + "." + extension;
videoStreams.add(new VideoStream(id, url, true, format, DeliveryMethod.PROGRESSIVE_HTTP, resolution, false));
videoStreams.add(new VideoStream(id, torrentUrl, true, format, DeliveryMethod.TORRENT, resolution, false));
}
} catch (Exception e) {
throw new ParsingException("Could not get video streams", e);
Expand Down Expand Up @@ -360,8 +359,10 @@ private void loadSubtitles() {
final String languageCode = JsonUtils.getString(caption, "language.id");
final String ext = url.substring(url.lastIndexOf(".") + 1);
final MediaFormat fmt = MediaFormat.getFromSuffix(ext);
if (fmt != null && languageCode != null)
subtitles.add(new SubtitlesStream(fmt, languageCode, url, false));
if (fmt != null && languageCode != null) {
final String id = languageCode + "." + fmt.suffix;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make a constructor of SubtitlesStream without id, so that it can be automatically set to this. I see this is being used also in YoutubeStreamExtractor

subtitles.add(new SubtitlesStream(id, url, fmt, languageCode, false));
}
}
}
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader;
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.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.DeliveryMethod;
import org.schabi.newpipe.extractor.stream.Description;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
Expand Down Expand Up @@ -174,52 +174,56 @@ public String getHlsUrl() throws ParsingException {

@Override
public List<AudioStream> getAudioStreams() throws IOException, ExtractionException {
List<AudioStream> audioStreams = new ArrayList<>();
Downloader dl = NewPipe.getDownloader();
final List<AudioStream> audioStreams = new ArrayList<>();
final Downloader dl = NewPipe.getDownloader();

// Streams can be streamable and downloadable - or explicitly not.
// For playing the track, it is only necessary to have a streamable track.
// If this is not the case, this track might not be published yet.
if (!track.getBoolean("streamable")) return audioStreams;
if (!track.getBoolean("streamable")) {
return audioStreams;
}

try {
JsonArray transcodings = track.getObject("media").getArray("transcodings");

// get information about what stream formats are available
for (Object transcoding : transcodings) {

JsonObject t = (JsonObject) transcoding;
String url = t.getString("url");

if (!isNullOrEmpty(url)) {

// We can only play the mp3 format, but not handle m3u playlists / streams.
// what about Opus?
if (t.getString("preset").contains("mp3")
&& t.getObject("format").getString("protocol").equals("progressive")) {
// This url points to the endpoint which generates a unique and short living url to the stream.
// TODO: move this to a separate method to generate valid urls when needed (e.g. resuming a paused stream)
url += "?client_id=" + SoundcloudParsingHelper.clientId();
String res = dl.get(url).responseBody();

try {
JsonObject mp3UrlObject = JsonParser.object().from(res);
// Links in this file are also only valid for a short period.
audioStreams.add(new AudioStream(mp3UrlObject.getString("url"),
MediaFormat.MP3, 128));
} catch (JsonParserException e) {
throw new ParsingException("Could not parse streamable url", e);
}
}
final JsonArray transcodings = track.getObject("media").getArray("transcodings");

// get information about what stream formats are available
for (final Object transcoding : transcodings) {
final JsonObject t = (JsonObject) transcoding;
String url = t.getString("url");

if (!isNullOrEmpty(url)) {
final MediaFormat mediaFormat;
if (t.getString("preset").contains("mp3")) {
mediaFormat = MediaFormat.MP3;
} else if (t.getString("preset").contains("opus")) {
mediaFormat = MediaFormat.OPUS;
} else {
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why break and not continue? Also below.

}
}

} catch (NullPointerException e) {
throw new ExtractionException("Could not get SoundCloud's track audio url", e);
}
final DeliveryMethod deliveryMethod;
if (t.getObject("format").getString("protocol").equals("progressive")) {
deliveryMethod = DeliveryMethod.PROGRESSIVE_HTTP;
} else if (t.getObject("format").getString("protocol").equals("hls")) {
deliveryMethod = DeliveryMethod.HLS;
} else {
break;
}

if (audioStreams.isEmpty()) {
throw new ContentNotSupportedException("HLS audio streams are not yet supported");
// This url points to the endpoint which generates a unique and short living url to the stream.
// TODO: move this to a separate method to generate valid urls when needed (e.g. resuming a paused stream)
url += "?client_id=" + SoundcloudParsingHelper.clientId();
final String res = dl.get(url).responseBody();

try {
final JsonObject urlObject = JsonParser.object().from(res);
// Links in this file are also only valid for a short period.
audioStreams.add(new AudioStream(t.getString("preset"),
urlObject.getString("url"), true, mediaFormat, deliveryMethod, 128));
} catch (JsonParserException e) {
throw new ParsingException("Could not parse streamable url", e);
}
}
}

return audioStreams;
Expand Down
Loading