33import com .grack .nanojson .JsonArray ;
44import com .grack .nanojson .JsonObject ;
55
6- import org .schabi .newpipe .extractor .MediaFormat ;
76import org .schabi .newpipe .extractor .StreamingService ;
87import org .schabi .newpipe .extractor .downloader .Downloader ;
98import org .schabi .newpipe .extractor .exceptions .ExtractionException ;
109import org .schabi .newpipe .extractor .exceptions .ParsingException ;
1110import org .schabi .newpipe .extractor .linkhandler .LinkHandler ;
12- import org .schabi .newpipe .extractor .stream .AudioStream ;
13- import org .schabi .newpipe .extractor .stream .DeliveryMethod ;
1411import org .schabi .newpipe .extractor .stream .Description ;
15- import org .schabi .newpipe .extractor .stream .Stream ;
1612import org .schabi .newpipe .extractor .stream .StreamExtractor ;
1713import org .schabi .newpipe .extractor .stream .StreamType ;
18- import org .schabi .newpipe .extractor .stream .VideoStream ;
14+ import org .schabi .newpipe .extractor .streamdata .delivery .DeliveryData ;
15+ import org .schabi .newpipe .extractor .streamdata .delivery .simpleimpl .SimpleDASHUrlDeliveryDataImpl ;
16+ import org .schabi .newpipe .extractor .streamdata .delivery .simpleimpl .SimpleHLSDeliveryDataImpl ;
17+ import org .schabi .newpipe .extractor .streamdata .delivery .simpleimpl .SimpleProgressiveHTTPDeliveryDataImpl ;
18+ import org .schabi .newpipe .extractor .streamdata .format .registry .AudioFormatRegistry ;
19+ import org .schabi .newpipe .extractor .streamdata .format .registry .VideoAudioFormatRegistry ;
20+ import org .schabi .newpipe .extractor .streamdata .stream .AudioStream ;
21+ import org .schabi .newpipe .extractor .streamdata .stream .VideoAudioStream ;
22+ import org .schabi .newpipe .extractor .streamdata .stream .simpleimpl .SimpleAudioStreamImpl ;
23+ import org .schabi .newpipe .extractor .streamdata .stream .simpleimpl .SimpleVideoAudioStreamImpl ;
1924
2025import java .io .IOException ;
21- import java .util .Collections ;
2226import java .util .List ;
23- import java .util .function .Function ;
2427import java .util .stream .Collectors ;
28+ import java .util .stream .Stream ;
2529
2630import javax .annotation .Nonnull ;
2731
28- import static org .schabi .newpipe .extractor .stream .AudioStream .UNKNOWN_BITRATE ;
29- import static org .schabi .newpipe .extractor .stream .Stream .ID_UNKNOWN ;
30- import static org .schabi .newpipe .extractor .utils .Utils .EMPTY_STRING ;
31-
3232public class MediaCCCLiveStreamExtractor extends StreamExtractor {
3333 private static final String STREAMS = "streams" ;
3434 private static final String URLS = "urls" ;
@@ -46,7 +46,8 @@ public MediaCCCLiveStreamExtractor(final StreamingService service,
4646 @ Override
4747 public void onFetchPage (@ Nonnull final Downloader downloader )
4848 throws IOException , ExtractionException {
49- final JsonArray doc = MediaCCCParsingHelper .getLiveStreams (downloader ,
49+ final JsonArray doc = MediaCCCParsingHelper .getLiveStreams (
50+ downloader ,
5051 getExtractorLocalization ());
5152 // Find the correct room
5253 for (int c = 0 ; c < doc .size (); c ++) {
@@ -138,7 +139,7 @@ public String getDashMpdUrl() throws ParsingException {
138139 */
139140 @ Nonnull
140141 @ Override
141- public String getHlsUrl () {
142+ public String getHlsMasterPlaylistUrl () {
142143 return getManifestOfDeliveryMethodWanted ("hls" );
143144 }
144145
@@ -149,84 +150,61 @@ private String getManifestOfDeliveryMethodWanted(@Nonnull final String deliveryM
149150 .map (JsonObject .class ::cast )
150151 .map (streamObject -> streamObject .getObject (URLS ))
151152 .filter (urls -> urls .has (deliveryMethod ))
152- .map (urls -> urls .getObject (deliveryMethod ).getString (URL , EMPTY_STRING ))
153+ .map (urls -> urls .getObject (deliveryMethod ).getString (URL , "" ))
153154 .findFirst ()
154- .orElse (EMPTY_STRING );
155+ .orElse ("" );
155156 }
156157
157158 @ Override
158159 public List <AudioStream > getAudioStreams () throws IOException , ExtractionException {
159- return getStreams ("audio" ,
160- dto -> {
161- final AudioStream .Builder builder = new AudioStream .Builder ()
162- .setId (dto .urlValue .getString ("tech" , ID_UNKNOWN ))
163- .setContent (dto .urlValue .getString (URL ), true )
164- .setAverageBitrate (UNKNOWN_BITRATE );
165-
166- if ("hls" .equals (dto .urlKey )) {
167- // We don't know with the type string what media format will
168- // have HLS streams.
169- // However, the tech string may contain some information
170- // about the media format used.
171- return builder .setDeliveryMethod (DeliveryMethod .HLS )
172- .build ();
160+ return getStreamDTOs ("audio" )
161+ .map (dto -> {
162+ final String url = dto .getUrlValue ().getString (URL );
163+ final DeliveryData deliveryData ;
164+ if ("hls" .equals (dto .getUrlKey ())) {
165+ deliveryData = new SimpleHLSDeliveryDataImpl (url );
166+ } else if ("dash" .equals (dto .getUrlKey ())) {
167+ deliveryData = new SimpleDASHUrlDeliveryDataImpl (url );
168+ } else {
169+ deliveryData = new SimpleProgressiveHTTPDeliveryDataImpl (url );
173170 }
174171
175- return builder .setMediaFormat (MediaFormat .getFromSuffix (dto .urlKey ))
176- .build ();
177- });
172+ return new SimpleAudioStreamImpl (
173+ deliveryData ,
174+ // TODO: This looks wrong
175+ new AudioFormatRegistry ().getFromSuffix (dto .getUrlKey ())
176+ );
177+ })
178+ .collect (Collectors .toList ());
178179 }
179180
180181 @ Override
181- public List <VideoStream > getVideoStreams () throws IOException , ExtractionException {
182- return getStreams ("video" ,
183- dto -> {
184- final JsonArray videoSize = dto .streamJsonObj .getArray ("videoSize" );
185-
186- final VideoStream .Builder builder = new VideoStream .Builder ()
187- .setId (dto .urlValue .getString ("tech" , ID_UNKNOWN ))
188- .setContent (dto .urlValue .getString (URL ), true )
189- .setIsVideoOnly (false )
190- .setResolution (videoSize .getInt (0 ) + "x" + videoSize .getInt (1 ));
191-
192- if ("hls" .equals (dto .urlKey )) {
193- // We don't know with the type string what media format will
194- // have HLS streams.
195- // However, the tech string may contain some information
196- // about the media format used.
197- return builder .setDeliveryMethod (DeliveryMethod .HLS )
198- .build ();
182+ public List <VideoAudioStream > getVideoStreams () throws IOException , ExtractionException {
183+ return getStreamDTOs ("video" )
184+ .map (dto -> {
185+ final String url = dto .getUrlValue ().getString (URL );
186+ final DeliveryData deliveryData ;
187+ if ("hls" .equals (dto .getUrlKey ())) {
188+ deliveryData = new SimpleHLSDeliveryDataImpl (url );
189+ } else if ("dash" .equals (dto .getUrlKey ())) {
190+ deliveryData = new SimpleDASHUrlDeliveryDataImpl (url );
191+ } else {
192+ deliveryData = new SimpleProgressiveHTTPDeliveryDataImpl (url );
199193 }
200194
201- return builder .setMediaFormat (MediaFormat .getFromSuffix (dto .urlKey ))
202- .build ();
203- });
204- }
205-
195+ final JsonArray videoSize = dto .getStreamJsonObj ().getArray ("videoSize" );
206196
207- /**
208- * This is just an internal class used in {@link #getStreams(String, Function)} to tie together
209- * the stream json object, its URL key and its URL value. An object of this class would be
210- * temporary and the three values it holds would be <b>convert</b>ed to a proper {@link Stream}
211- * object based on the wanted stream type.
212- */
213- private static final class MediaCCCLiveStreamMapperDTO {
214- final JsonObject streamJsonObj ;
215- final String urlKey ;
216- final JsonObject urlValue ;
217-
218- MediaCCCLiveStreamMapperDTO (final JsonObject streamJsonObj ,
219- final String urlKey ,
220- final JsonObject urlValue ) {
221- this .streamJsonObj = streamJsonObj ;
222- this .urlKey = urlKey ;
223- this .urlValue = urlValue ;
224- }
197+ return new SimpleVideoAudioStreamImpl (
198+ deliveryData ,
199+ // TODO: This looks wrong
200+ new VideoAudioFormatRegistry ().getFromSuffix (dto .getUrlKey ()),
201+ videoSize .getInt (0 ) + "x" + videoSize .getInt (1 )
202+ );
203+ })
204+ .collect (Collectors .toList ());
225205 }
226206
227- private <T extends Stream > List <T > getStreams (
228- @ Nonnull final String streamType ,
229- @ Nonnull final Function <MediaCCCLiveStreamMapperDTO , T > converter ) {
207+ private Stream <MediaCCCLiveStreamMapperDTO > getStreamDTOs (@ Nonnull final String streamType ) {
230208 return room .getArray (STREAMS ).stream ()
231209 // Ensure that we use only process JsonObjects
232210 .filter (JsonObject .class ::isInstance )
@@ -239,22 +217,17 @@ private <T extends Stream> List<T> getStreams(
239217 .map (e -> new MediaCCCLiveStreamMapperDTO (
240218 streamJsonObj ,
241219 e .getKey (),
242- (JsonObject ) e .getValue ())))
243- // The DASH manifest will be extracted with getDashMpdUrl
244- .filter (dto -> !"dash" .equals (dto .urlKey ))
245- // Convert
246- .map (converter )
247- .collect (Collectors .toList ());
220+ (JsonObject ) e .getValue ())));
248221 }
249222
250223 @ Override
251- public List < VideoStream > getVideoOnlyStreams () {
252- return Collections . emptyList () ;
224+ public StreamType getStreamType () throws ParsingException {
225+ return StreamType . LIVE_STREAM ;
253226 }
254227
255228 @ Override
256- public StreamType getStreamType () throws ParsingException {
257- return StreamType . LIVE_STREAM ;
229+ public boolean isLive () {
230+ return true ;
258231 }
259232
260233 @ Nonnull
0 commit comments