diff --git a/src/main/java/de/mediathekview/mserver/crawler/livestream/LivestreamConstants.java b/src/main/java/de/mediathekview/mserver/crawler/livestream/LivestreamConstants.java new file mode 100644 index 000000000..0f27f2139 --- /dev/null +++ b/src/main/java/de/mediathekview/mserver/crawler/livestream/LivestreamConstants.java @@ -0,0 +1,58 @@ +package de.mediathekview.mserver.crawler.livestream; + +import java.util.HashMap; +import java.util.Map; + +import de.mediathekview.mlib.daten.Sender; + +public final class LivestreamConstants { + + /** Livestreams */ + public static final String URL_LIVESTREAMS = "http://bit.ly/kn-kodi-tv"; + + public static final Map sender = new HashMap<>(); + + static { + sender.put("3sat", Sender.DREISAT); + sender.put("Das Erste HD", Sender.ARD); + sender.put("one HD", Sender.ARD); + sender.put("ARD-alpha", Sender.ARD); + sender.put("tagesschau24", Sender.ARD); + sender.put("ARTE HD", Sender.ARTE_DE); + sender.put("ARTE HD (FR)", Sender.ARTE_FR); + sender.put("WDR HD", Sender.WDR); + sender.put("SWR Baden-Württemberg HD", Sender.SWR); + sender.put("SWR Rheinland-Pfalz HD", Sender.SWR); + sender.put("NDR Niedersachsen HD", Sender.NDR); + sender.put("NDR Schleswig-Holstein HD", Sender.NDR); + sender.put("NDR Mecklenburg-Vorpommern HD", Sender.NDR); + sender.put("NDR Hamburg HD", Sender.NDR); + sender.put("BR Fernsehen Nord HD", Sender.BR); + sender.put("BR Fernsehen Süd HD", Sender.BR); + sender.put("MDR Sachsen HD", Sender.MDR); + sender.put("MDR Sachsen-Anhalt HD", Sender.MDR); + sender.put("MDR Thüringen HD", Sender.MDR); + sender.put("hr-fernsehen", Sender.HR); + sender.put("rbb Berlin HD", Sender.RBB); + sender.put("rbb Brandenburg HD", Sender.RBB); + sender.put("SR Fernsehen HD", Sender.SR); + sender.put("Deutsche Welle", Sender.DW); + sender.put("Deutsche Welle+", Sender.DW); + sender.put("Deutsche Welle (EN)", Sender.DW); + sender.put("Deutsche Welle (ES)", Sender.DW); + sender.put("phoenix HD", Sender.PHOENIX); + sender.put("Radio Bremen TV", Sender.RBTV); + sender.put("rbb Berlin", Sender.RBB); + sender.put("rbb Brandenburg", Sender.RBB); + sender.put("KiKA", Sender.KIKA); + sender.put("ZDF HD", Sender.ZDF); + sender.put("ZDFneo HD", Sender.ZDF); + sender.put("ZDFinfo HD", Sender.ZDF); + sender.put("ORF eins HD", Sender.ORF); + sender.put("ORF 2 HD", Sender.ORF); + sender.put("ORF III HD", Sender.ORF); + sender.put("ORF SPORT +", Sender.ORF); + }; + + private LivestreamConstants() {} +} diff --git a/src/main/java/de/mediathekview/mserver/crawler/livestream/LivestreamCrawler.java b/src/main/java/de/mediathekview/mserver/crawler/livestream/LivestreamCrawler.java new file mode 100644 index 000000000..ea9fd55a1 --- /dev/null +++ b/src/main/java/de/mediathekview/mserver/crawler/livestream/LivestreamCrawler.java @@ -0,0 +1,135 @@ +package de.mediathekview.mserver.crawler.livestream; + +import de.mediathekview.mlib.daten.Film; +import de.mediathekview.mlib.daten.FilmUrl; +import de.mediathekview.mlib.daten.Resolution; +import de.mediathekview.mlib.daten.Sender; +import de.mediathekview.mlib.messages.listener.MessageListener; +import de.mediathekview.mserver.base.config.MServerConfigManager; +import de.mediathekview.mserver.base.messages.ServerMessages; +import de.mediathekview.mserver.crawler.basic.AbstractCrawler; +import de.mediathekview.mserver.progress.listeners.SenderProgressListener; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.RecursiveTask; + +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class LivestreamCrawler extends AbstractCrawler { + private static final Logger LOG = LogManager.getLogger(LivestreamCrawler.class); + + public LivestreamCrawler( + final ForkJoinPool aForkJoinPool, + final Collection aMessageListeners, + final Collection aProgressListeners, + final MServerConfigManager rootConfig) { + super(aForkJoinPool, aMessageListeners, aProgressListeners, rootConfig); + } + + @Override + public Sender getSender() { + return Sender.WDR3; + } + + @Override + protected RecursiveTask> createCrawlerTask() { + + KodiM3UParser m3uparser = new KodiM3UParser(); + String data = ""; + Set channels = new HashSet<>(); + try { + data = this.getConnection().requestBodyAsString(LivestreamConstants.URL_LIVESTREAMS); + List> streamInfo = m3uparser.parse(data); + for (HashMap stream : streamInfo) { + if (LivestreamConstants.sender.containsKey(stream.get("tvg-name"))) { + Film f = new Film( + UUID.randomUUID(), + LivestreamConstants.sender.get(stream.get("tvg-name")), + stream.get("name") + " Livestream", + "Livestream", + null, null); + f.addUrl(Resolution.NORMAL, new FilmUrl(new URL(stream.get("url")), 0L)); + channels.add(f); + } + } + //System.out.println("################################"); + //for (HashMap stream : streamInfo) { + // System.out.println(stream.get("tvg-name") + "#" + stream.get("name") + "#" + stream.get("url")); + //} + } catch (final IOException e) { + LOG.fatal("Exception in {} crawler.", getSender().getName(), e); + } + printMessage( + ServerMessages.DEBUG_ALL_SENDUNG_FOLGEN_COUNT, getSender().getName(), channels.size()); + getAndSetMaxCount(channels.size()); + return new LivestreamToFilm(channels); + } + + // TODO: move to class when stable + class LivestreamToFilm extends RecursiveTask> { + private static final long serialVersionUID = 1L; + Set setOfFilm; + LivestreamToFilm (Set setOfFilm) { + this.setOfFilm = setOfFilm; + } + + @Override + protected Set compute() { + return setOfFilm; + } + + } + + // TODO: move to class when stable + class KodiM3UParser { + //#EXTM3U + //#EXTINF:-1 tvg-name="Das Erste HD" tvg-id="DasErste.de" group-title="IPTV-DE" tvg-logo="https://raw.githubusercontent.com/jnk22/kodinerds-iptv/master/logos/tv/daserstehd.png",Das Erste HD + //https://mcdn.daserste.de/daserste/de/master.m3u8 + List> parse(String aM3U8Data) { + String[] lines = StringUtils.split(aM3U8Data, '\n'); + ArrayList> data = new ArrayList<>(); + HashMap information = new HashMap<>(); + for (String line : lines) { + if (!line.isBlank() && !line.equalsIgnoreCase("#EXTM3U") && !line.equalsIgnoreCase("#")) { + if (line.startsWith("#EXTINF")) { + // remove extint + line = line.substring(8); + // read name (last position after ,) + information.put("name", line.substring(line.lastIndexOf(",")+1)); + // remove name but add space for parsing + line = line.substring(0,line.lastIndexOf(",")) + " "; + // remove length (first position) + information.put("length", line.substring(0,line.indexOf(" "))); + line = line.substring(line.indexOf(" ")+1); + // bag + String[] dictList = line.split("\" "); + for (String valueKeyPair : dictList) { + String key = valueKeyPair.substring(0,valueKeyPair.indexOf("=")); + String value = valueKeyPair.substring(valueKeyPair.indexOf("=")+1); + value = value.replace("\"", ""); + information.put(key.trim(),value.trim()); + } + } else { + information.put("url", line); + data.add(information); + information = new HashMap<>(); + } + } + } + return data; + } + + + } +}