|
12 | 12 |
|
13 | 13 | import javax.annotation.Nonnull; |
14 | 14 | import java.io.IOException; |
15 | | -import java.util.ArrayList; |
16 | 15 | import java.util.Collections; |
17 | 16 | import java.util.List; |
18 | | -import java.util.stream.IntStream; |
| 17 | +import java.util.function.Function; |
| 18 | +import java.util.stream.Collectors; |
19 | 19 |
|
20 | 20 | import static org.schabi.newpipe.extractor.stream.AudioStream.UNKNOWN_BITRATE; |
21 | 21 | import static org.schabi.newpipe.extractor.stream.Stream.ID_UNKNOWN; |
@@ -50,9 +50,9 @@ public void onFetchPage(@Nonnull final Downloader downloader) |
50 | 50 | final JsonObject roomObject = rooms.getObject(r); |
51 | 51 | if (getId().equals(conferenceObject.getString("slug") + "/" |
52 | 52 | + roomObject.getString("slug"))) { |
53 | | - this.conference = conferenceObject; |
54 | | - this.group = groupObject; |
55 | | - this.room = roomObject; |
| 53 | + conference = conferenceObject; |
| 54 | + group = groupObject; |
| 55 | + room = roomObject; |
56 | 56 | return; |
57 | 57 | } |
58 | 58 | } |
@@ -100,122 +100,120 @@ public String getUploaderName() throws ParsingException { |
100 | 100 | * Get the URL of the first DASH stream found. |
101 | 101 | * |
102 | 102 | * <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. |
104 | 105 | * </p> |
105 | 106 | * |
106 | 107 | * <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()} |
108 | 109 | * </p> |
109 | 110 | */ |
110 | 111 | @Nonnull |
111 | 112 | @Override |
112 | 113 | 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"); |
123 | 115 | } |
124 | 116 |
|
125 | 117 | /** |
126 | 118 | * Get the URL of the first HLS stream found. |
127 | 119 | * |
128 | 120 | * <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. |
130 | 123 | * </p> |
131 | 124 | * |
132 | 125 | * <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()} |
134 | 127 | * </p> |
135 | 128 | */ |
136 | 129 | @Nonnull |
137 | 130 | @Override |
138 | 131 | 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); |
147 | 145 | } |
148 | 146 |
|
149 | 147 | @Override |
150 | 148 | 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 | + }); |
180 | 168 | } |
181 | 169 |
|
182 | 170 | @Override |
183 | 171 | 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()); |
219 | 217 | } |
220 | 218 |
|
221 | 219 | @Override |
|
0 commit comments