Skip to content

Commit 5dfa3bc

Browse files
committed
Improve documentation and adress most of the requested changes
Also fix some issues in several places, in the code and the documentation.
1 parent 53dee9b commit 5dfa3bc

20 files changed

Lines changed: 791 additions & 552 deletions

extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ public DateWrapper getUploadDate() throws ParsingException {
114114
public String getThumbnailUrl() throws ParsingException {
115115
if (albumJson.isNull("art_id")) {
116116
return EMPTY_STRING;
117-
} else {
118-
return getImageUrl(albumJson.getLong("art_id"), true);
119117
}
118+
119+
return getImageUrl(albumJson.getLong("art_id"), true);
120120
}
121121

122122
@Nonnull

extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java

Lines changed: 89 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
import javax.annotation.Nonnull;
1414
import java.io.IOException;
15-
import java.util.ArrayList;
1615
import java.util.Collections;
1716
import java.util.List;
18-
import java.util.stream.IntStream;
17+
import java.util.function.Function;
18+
import java.util.stream.Collectors;
1919

2020
import static org.schabi.newpipe.extractor.stream.AudioStream.UNKNOWN_BITRATE;
2121
import static org.schabi.newpipe.extractor.stream.Stream.ID_UNKNOWN;
@@ -50,9 +50,9 @@ public void onFetchPage(@Nonnull final Downloader downloader)
5050
final JsonObject roomObject = rooms.getObject(r);
5151
if (getId().equals(conferenceObject.getString("slug") + "/"
5252
+ roomObject.getString("slug"))) {
53-
this.conference = conferenceObject;
54-
this.group = groupObject;
55-
this.room = roomObject;
53+
conference = conferenceObject;
54+
group = groupObject;
55+
room = roomObject;
5656
return;
5757
}
5858
}
@@ -100,122 +100,120 @@ public String getUploaderName() throws ParsingException {
100100
* Get the URL of the first DASH stream found.
101101
*
102102
* <p>
103-
* There can be several DASH streams, so the URL of the first found is returned by this method.
103+
* There can be several DASH streams, so the URL of the first one found is returned by this
104+
* method.
104105
* </p>
105106
*
106107
* <p>
107-
* You can find the other video DASH streams by using {@link #getVideoStreams()}
108+
* You can find the other DASH video streams by using {@link #getVideoStreams()}
108109
* </p>
109110
*/
110111
@Nonnull
111112
@Override
112113
public String getDashMpdUrl() throws ParsingException {
113-
114-
for (int s = 0; s < room.getArray(STREAMS).size(); s++) {
115-
final JsonObject stream = room.getArray(STREAMS).getObject(s);
116-
final JsonObject urls = stream.getObject(URLS);
117-
if (urls.has("dash")) {
118-
return urls.getObject("dash").getString(URL, EMPTY_STRING);
119-
}
120-
}
121-
122-
return EMPTY_STRING;
114+
return getManifestOfDeliveryMethodWanted("dash");
123115
}
124116

125117
/**
126118
* Get the URL of the first HLS stream found.
127119
*
128120
* <p>
129-
* There can be several HLS streams, so the URL of the first found is returned by this method.
121+
* There can be several HLS streams, so the URL of the first one found is returned by this
122+
* method.
130123
* </p>
131124
*
132125
* <p>
133-
* You can find the other video HLS streams by using {@link #getVideoStreams()}
126+
* You can find the other HLS video streams by using {@link #getVideoStreams()}
134127
* </p>
135128
*/
136129
@Nonnull
137130
@Override
138131
public String getHlsUrl() {
139-
for (int s = 0; s < room.getArray(STREAMS).size(); s++) {
140-
final JsonObject stream = room.getArray(STREAMS).getObject(s);
141-
final JsonObject urls = stream.getObject(URLS);
142-
if (urls.has("hls")) {
143-
return urls.getObject("hls").getString(URL, EMPTY_STRING);
144-
}
145-
}
146-
return EMPTY_STRING;
132+
return getManifestOfDeliveryMethodWanted("hls");
133+
}
134+
135+
@Nonnull
136+
private String getManifestOfDeliveryMethodWanted(@Nonnull final String deliveryMethod) {
137+
return room.getArray(STREAMS).stream()
138+
.filter(JsonObject.class::isInstance)
139+
.map(JsonObject.class::cast)
140+
.map(streamObject -> streamObject.getObject(URLS))
141+
.filter(urls -> urls.has(deliveryMethod))
142+
.map(urls -> urls.getObject(deliveryMethod).getString(URL, EMPTY_STRING))
143+
.findFirst()
144+
.orElse(EMPTY_STRING);
147145
}
148146

149147
@Override
150148
public List<AudioStream> getAudioStreams() throws IOException, ExtractionException {
151-
final List<AudioStream> audioStreams = new ArrayList<>();
152-
IntStream.range(0, room.getArray(STREAMS).size())
153-
.mapToObj(s -> room.getArray(STREAMS).getObject(s))
154-
.filter(streamJsonObject -> streamJsonObject.getString("type").equals("audio"))
155-
.forEachOrdered(streamJsonObject -> streamJsonObject.getObject(URLS).keySet()
156-
.forEach(type -> {
157-
final JsonObject urlObject = streamJsonObject.getObject(URLS)
158-
.getObject(type);
159-
// The DASH manifest will be extracted with getDashMpdUrl
160-
if (!type.equals("dash")) {
161-
final AudioStream.Builder builder = new AudioStream.Builder()
162-
.setId(urlObject.getString("tech", ID_UNKNOWN))
163-
.setContent(urlObject.getString(URL), true)
164-
.setAverageBitrate(UNKNOWN_BITRATE);
165-
if (type.equals("hls")) {
166-
// We don't know with the type string what media format will
167-
// have HLS streams.
168-
// However, the tech string may contain some information
169-
// about the media format used.
170-
builder.setDeliveryMethod(DeliveryMethod.HLS);
171-
} else {
172-
builder.setMediaFormat(MediaFormat.getFromSuffix(type));
173-
}
174-
175-
audioStreams.add(builder.build());
176-
}
177-
}));
178-
179-
return audioStreams;
149+
return getStreams("audio",
150+
dto -> {
151+
final AudioStream.Builder builder = new AudioStream.Builder()
152+
.setId(dto.getUrlValue().getString("tech", ID_UNKNOWN))
153+
.setContent(dto.getUrlValue().getString(URL), true)
154+
.setAverageBitrate(UNKNOWN_BITRATE);
155+
156+
if ("hls".equals(dto.getUrlKey())) {
157+
// We don't know with the type string what media format will
158+
// have HLS streams.
159+
// However, the tech string may contain some information
160+
// about the media format used.
161+
return builder.setDeliveryMethod(DeliveryMethod.HLS)
162+
.build();
163+
}
164+
165+
return builder.setMediaFormat(MediaFormat.getFromSuffix(dto.getUrlKey()))
166+
.build();
167+
});
180168
}
181169

182170
@Override
183171
public List<VideoStream> getVideoStreams() throws IOException, ExtractionException {
184-
final List<VideoStream> videoStreams = new ArrayList<>();
185-
IntStream.range(0, room.getArray(STREAMS).size())
186-
.mapToObj(s -> room.getArray(STREAMS).getObject(s))
187-
.filter(stream -> stream.getString("type").equals("video"))
188-
.forEachOrdered(streamJsonObject -> streamJsonObject.getObject(URLS).keySet()
189-
.forEach(type -> {
190-
final String resolution =
191-
streamJsonObject.getArray("videoSize").getInt(0)
192-
+ "x"
193-
+ streamJsonObject.getArray("videoSize").getInt(1);
194-
final JsonObject urlObject = streamJsonObject.getObject(URLS)
195-
.getObject(type);
196-
// The DASH manifest will be extracted with getDashMpdUrl
197-
if (!type.equals("dash")) {
198-
final VideoStream.Builder builder = new VideoStream.Builder()
199-
.setId(urlObject.getString("tech", ID_UNKNOWN))
200-
.setContent(urlObject.getString(URL), true)
201-
.setIsVideoOnly(false)
202-
.setResolution(resolution);
203-
204-
if (type.equals("hls")) {
205-
// We don't know with the type string what media format will
206-
// have HLS streams.
207-
// However, the tech string may contain some information
208-
// about the media format used.
209-
builder.setDeliveryMethod(DeliveryMethod.HLS);
210-
} else {
211-
builder.setMediaFormat(MediaFormat.getFromSuffix(type));
212-
}
213-
214-
videoStreams.add(builder.build());
215-
}
216-
}));
217-
218-
return videoStreams;
172+
return getStreams("video",
173+
dto -> {
174+
final JsonArray videoSize = dto.getStreamJsonObj().getArray("videoSize");
175+
176+
final VideoStream.Builder builder = new VideoStream.Builder()
177+
.setId(dto.getUrlValue().getString("tech", ID_UNKNOWN))
178+
.setContent(dto.getUrlValue().getString(URL), true)
179+
.setIsVideoOnly(false)
180+
.setResolution(videoSize.getInt(0) + "x" + videoSize.getInt(1));
181+
182+
if ("hls".equals(dto.getUrlKey())) {
183+
// We don't know with the type string what media format will
184+
// have HLS streams.
185+
// However, the tech string may contain some information
186+
// about the media format used.
187+
return builder.setDeliveryMethod(DeliveryMethod.HLS)
188+
.build();
189+
}
190+
191+
return builder.setMediaFormat(MediaFormat.getFromSuffix(dto.getUrlKey()))
192+
.build();
193+
});
194+
}
195+
196+
private <T extends Stream> List<T> getStreams(
197+
@Nonnull final String streamType,
198+
@Nonnull final Function<MediaCCCLiveStreamMapperDTO, T> converter) {
199+
return room.getArray(STREAMS).stream()
200+
// Ensure that we use only process JsonObjects
201+
.filter(JsonObject.class::isInstance)
202+
.map(JsonObject.class::cast)
203+
// Only process audio streams
204+
.filter(streamJsonObj -> streamType.equals(streamJsonObj.getString("type")))
205+
// Flatmap Urls and ensure that we use only process JsonObjects
206+
.flatMap(streamJsonObj -> streamJsonObj.getObject(URLS).entrySet().stream()
207+
.filter(e -> e.getValue() instanceof JsonObject)
208+
.map(e -> new MediaCCCLiveStreamMapperDTO(
209+
streamJsonObj,
210+
e.getKey(),
211+
(JsonObject) e.getValue())))
212+
// The DASH manifest will be extracted with getDashMpdUrl
213+
.filter(dto -> !"dash".equals(dto.getUrlKey()))
214+
// Convert
215+
.map(converter)
216+
.collect(Collectors.toList());
219217
}
220218

221219
@Override
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.schabi.newpipe.extractor.services.media_ccc.extractors;
2+
3+
import com.grack.nanojson.JsonObject;
4+
5+
final class MediaCCCLiveStreamMapperDTO {
6+
private final JsonObject streamJsonObj;
7+
private final String urlKey;
8+
private final JsonObject urlValue;
9+
10+
MediaCCCLiveStreamMapperDTO(final JsonObject streamJsonObj,
11+
final String urlKey,
12+
final JsonObject urlValue) {
13+
this.streamJsonObj = streamJsonObj;
14+
this.urlKey = urlKey;
15+
this.urlValue = urlValue;
16+
}
17+
18+
JsonObject getStreamJsonObj() {
19+
return streamJsonObj;
20+
}
21+
22+
String getUrlKey() {
23+
return urlKey;
24+
}
25+
26+
JsonObject getUrlValue() {
27+
return urlValue;
28+
}
29+
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCStreamExtractor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public List<AudioStream> getAudioStreams() throws ExtractionException {
9696
final JsonObject recording = recordings.getObject(i);
9797
final String mimeType = recording.getString("mime_type");
9898
if (mimeType.startsWith("audio")) {
99-
// First we need to resolve the actual video data from CDN
99+
// First we need to resolve the actual video data from the CDN
100100
final MediaFormat mediaFormat;
101101
if (mimeType.endsWith("opus")) {
102102
mediaFormat = MediaFormat.OPUS;
@@ -109,7 +109,7 @@ public List<AudioStream> getAudioStreams() throws ExtractionException {
109109
}
110110

111111
// Don't use the containsSimilarStream method because it will always return
112-
// false so if there are multiples audio streams available, only the first will
112+
// false. So if there are multiple audio streams available, only the first one will
113113
// be extracted in this case.
114114
audioStreams.add(new AudioStream.Builder()
115115
.setId(recording.getString("filename", ID_UNKNOWN))
@@ -130,7 +130,7 @@ public List<VideoStream> getVideoStreams() throws ExtractionException {
130130
final JsonObject recording = recordings.getObject(i);
131131
final String mimeType = recording.getString("mime_type");
132132
if (mimeType.startsWith("video")) {
133-
// First we need to resolve the actual video data from CDN
133+
// First we need to resolve the actual video data from the CDN
134134

135135
final MediaFormat mediaFormat;
136136
if (mimeType.endsWith("webm")) {
@@ -142,7 +142,8 @@ public List<VideoStream> getVideoStreams() throws ExtractionException {
142142
}
143143

144144
// Don't use the containsSimilarStream method because it will remove the
145-
// extraction of some video versions (mostly languages)
145+
// extraction of some video versions (mostly languages). So if there are multiple
146+
// video streams available, only the first one will be extracted in this case.
146147
videoStreams.add(new VideoStream.Builder()
147148
.setId(recording.getString("filename", ID_UNKNOWN))
148149
.setContent(recording.getString("recording_url"), true)

0 commit comments

Comments
 (0)