Skip to content

Commit

Permalink
[media.ccc.de] Fix live streams extraction
Browse files Browse the repository at this point in the history
The API was slightly changed and only HLS streams are provided anymore.

Add a basic test for to check whether the required streamInfo fields are available.

Closes #766
  • Loading branch information
TobiGr committed Dec 27, 2021
1 parent 10f6cc7 commit 752825c
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,12 @@ public String getUploaderName() throws ParsingException {
@Override
public String getHlsUrl() {
// TODO: There are multiple HLS streams.
// Make getHlsUrl() and getDashMpdUrl() return lists of VideoStreams, so the user can choose a resolution.
// Make getHlsUrl() and getDashMpdUrl() return lists of VideoStreams
// to allow selecting a resolution.
for (int s = 0; s < room.getArray("streams").size(); s++) {
final JsonObject stream = room.getArray("streams").getObject(s);
if (stream.getString("type").equals("video")) {
final String resolution = stream.getArray("videoSize").getInt(0) + "x"
+ stream.getArray("videoSize").getInt(1);
if (stream.has("hls")) {
return stream.getObject("urls").getObject("hls").getString("url");
}
if (stream.getString("type").equals("video") && stream.getObject("urls").has("hls")) {
return stream.getObject("urls").getObject("hls").getString("url");
}
}
return "";
Expand All @@ -114,8 +111,11 @@ public List<AudioStream> getAudioStreams() throws IOException, ExtractionExcepti
final JsonObject stream = room.getArray("streams").getObject(s);
if (stream.getString("type").equals("audio")) {
for (final String type : stream.getObject("urls").keySet()) {
final JsonObject url = stream.getObject("urls").getObject(type);
audioStreams.add(new AudioStream(url.getString("url"), MediaFormat.getFromSuffix(type), -1));
if (!type.equals("hls")) {
final JsonObject url = stream.getObject("urls").getObject(type);
audioStreams.add(new AudioStream(
url.getString("url"), MediaFormat.getFromSuffix(type), -1));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,13 @@ private static StreamInfo extractStreams(StreamInfo streamInfo, StreamExtractor
} catch (Exception e) {
streamInfo.addError(new ExtractionException("Couldn't get audio streams", e));
}
/* Extract video stream url */
/* Extract video streams */
try {
streamInfo.setVideoStreams(extractor.getVideoStreams());
} catch (Exception e) {
streamInfo.addError(new ExtractionException("Couldn't get video streams", e));
}
/* Extract video only stream url */
/* Extract video only streams */
try {
streamInfo.setVideoOnlyStreams(extractor.getVideoOnlyStreams());
} catch (Exception e) {
Expand Down Expand Up @@ -181,13 +181,16 @@ private static StreamInfo extractStreams(StreamInfo streamInfo, StreamExtractor

// Either audio or video has to be available, otherwise we didn't get a stream
// (since videoOnly are optional, they don't count).
if ((streamInfo.videoStreams.isEmpty()) && (streamInfo.audioStreams.isEmpty())) {
if (streamInfo.videoStreams.isEmpty()
&& streamInfo.audioStreams.isEmpty()
&& isNullOrEmpty(streamInfo.getHlsUrl())
&& isNullOrEmpty(streamInfo.getDashMpdUrl())) {

if (dashMpdError != null) {
// If we don't have any video or audio and the dashMpd 'errored', add it to the
// error list
// (it's optional and it don't get added automatically, but it's good to have
// some additional error context)
// (It's optional, and it is not added automatically,
// but it's good to have some additional error context).
streamInfo.addError(dashMpdError);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.schabi.newpipe.extractor.services.media_ccc;

import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test;
import org.schabi.newpipe.downloader.DownloaderTestImpl;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.kiosk.KioskExtractor;
import org.schabi.newpipe.extractor.stream.StreamExtractor;
import org.schabi.newpipe.extractor.stream.StreamInfo;

import java.io.IOException;
import java.util.List;

import static org.schabi.newpipe.extractor.ServiceList.MediaCCC;

public class MediaCCCLiveStreamExtractorTest {

private static KioskExtractor liveKiosk;
private static StreamExtractor extractor;

private static List<InfoItem> liveItems;

@BeforeClass
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
liveKiosk = MediaCCC.getKioskList().getExtractorById("live", null);
liveKiosk.fetchPage();
liveItems = liveKiosk.getInitialPage().getItems();
Assume.assumeFalse(
"Received an empty list of live streams. Skipping MediaCCCLiveStreamExtractorTest",
liveItems.isEmpty());
}

@Test
public void testRequiredStreamInfo() {
// Try to get the StreamInfo for each live stream.
// If some required info is not present an exception will be thrown.
try {
for (final InfoItem item : liveItems) {
StreamInfo.getInfo(item.getUrl());
}
} catch (ExtractionException | IOException e) {
e.printStackTrace();
Assert.fail("An exception was thrown while getting a StreamInfo for a livestream.");
}
}

}

0 comments on commit 752825c

Please sign in to comment.