### Build and Run MServer from Command Line Source: https://github.com/mediathekview/mserver/blob/master/README.md Navigate to the MServer directory and use Gradle to build and start the server. ```bash cd MServer ./gradlew start ``` -------------------------------- ### Clone Repository and Start MServer Source: https://context7.com/mediathekview/mserver/llms.txt Clone the MServer and MLib repositories, then build and start MServer using Gradle. Alternatively, run the compiled JAR with arguments for debug mode, a custom config path, version output, GUI, or to disable XZ compression. Docker is also supported. ```bash # Repository klonen (MLib als Subprojekt erforderlich) mkdir mediathekview && cd mediathekview git clone https://github.com/mediathekview/MServer.git git clone https://github.com/mediathekview/MLib.git cd MServer # Bauen und starten ./gradlew start # Mit Argumenten: Debug-Modus, optionaler Arbeitspfad java -jar MServer.jar /pfad/zum/konfigordner -d # Nur Version ausgeben java -jar MServer.jar -v # Grafische Oberfläche (JavaFX) java -jar MServer.jar -gui # XZ-Komprimierung deaktivieren export NOCOMPRESS=y java -jar MServer.jar # Docker docker run mediathekview/mserver:latest ``` -------------------------------- ### MServer Main Entry Point and Start Modes Source: https://context7.com/mediathekview/mserver/llms.txt The `mServer.Main` class parses command-line arguments to select the operating mode: server, version output, or GUI. In server mode, `MServer.starten()` runs in a loop, sleeping until the next midnight after each crawl cycle. Debug logging can be enabled with the '-d' argument. ```java // Startmodi: // (kein Argument) -> SERVER: läuft dauerhaft, täglicher Neustart // -d -> Debug-Logging aktivieren // -v -> Version ausgeben und beenden // -gui -> JavaFX-GUI starten public static void main(String[] args) { // Performance-Monitoring initialisieren BasicEtmConfigurator.configure(); EtmManager.getEtmMonitor().start(); // Argument "-d" setzt MserverDaten.debug = true // Argument "-gui" startet Application.launch(MSG.class, args) // Standard: runServer(args) // Im Servermodus: Schleife bis MServer.starten() false zurückgibt // Nach jedem Lauf: Thread.sleep(SekundenBisMitternacht + 120 Sekunden) } // Beispielaufruf: täglicher Dauerbetrieb // while (new MServer(args).starten()) { // long sleep = (MserverDatumZeit.getSecondsUntilNextDay() + 120) * 1000; // Thread.sleep(sleep); // schläft bis 00:02 Uhr // } ``` -------------------------------- ### Configure Global Crawler Settings with CrawlerConfig Source: https://context7.com/mediathekview/mserver/llms.txt Set global parameters for all crawlers, such as loading modes, proxy settings, and directory paths. This class should be configured before starting the crawlers. ```java // Lademodus: LOAD_SHORT (nur Update), LOAD_LONG, LOAD_MAX (alles) CrawlerConfig.senderLoadHow = CrawlerConfig.LOAD_LONG; // Filmliste aktualisieren statt neu erstellen CrawlerConfig.updateFilmliste = true; // Proxy konfigurieren CrawlerConfig.proxyUrl = "proxy.example.com"; CrawlerConfig.proxyPort = 8080; // Nur bestimmte Sender laden CrawlerConfig.nurSenderLaden = new String[]{"ARD", "ZDF"}; // Verzeichnis der Filmlisten CrawlerConfig.dirFilme = "/var/data/filmlisten/"; // Alte Liste importieren und mergen CrawlerConfig.importOld = "/pfad/zur/alte-liste.json"; // Aktuelle Liste eines anderen Crawlers importieren CrawlerConfig.importAkt = "https://res.mediathekview.de/akt.xml"; // Crawler-Auswahl einschränken (Komma-getrennt in Systemkonfiguration): // "ARD,ZDF,ARTE,DW,KIKA,3SAT,SR,SRF,SRFPOD,ORF,PHONIX" ``` -------------------------------- ### Initialize ArteCrawler Instances Source: https://context7.com/mediathekview/mserver/llms.txt Registers ArteCrawler instances for different languages with specified priorities. Priority 0 starts immediately, while priority 1 starts with a delay. ```java // Crawler für alle Sprachen werden in FilmeSuchen registriert: // new ArteCrawler(this, 0) -> ARTE.DE (Prio 0, startet sofort) // new ArteCrawler_FR(this, 1) -> ARTE.FR (Prio 1) // new ArteCrawler_EN(this, 1) -> ARTE.EN (Prio 1) // new ArteCrawler_ES(this, 1) -> ARTE.ES (Prio 1) // new ArteCrawler_PL(this, 1) -> ARTE.PL (Prio 1) // new ArteCrawler_IT(this, 1) -> ARTE.IT (Prio 1) // API-Endpunkt (paginiert): // ArteConstants.VIDEOS_URL = https://api.arte.tv/api/player/v2/config/{lang}/videos?page={page} // Authorization: ArteConstants.API_TOKEN // Maximale Seiten: 5 (Short-Modus) oder 10 (Long/Max-Modus) // Tatsächliche Seitenanzahl wird dynamisch aus meta.videos.pages gelesen // Ablauf: ArteVideoInfoTask -> ArteVideoLinkTask -> ArteDtoVideo2FilmTask // 1. Video-Übersicht laden (paginiert) // 2. Stream-Links pro Video auflösen // 3. DatenFilm-Objekte erzeugen ``` -------------------------------- ### Build and Run MServer from Command Line Source: https://github.com/mediathekview/mserver/wiki/Entwicklung Execute the Gradle wrapper to build and run the MServer application. Ensure you are in the MServer directory. ```bash cd MServer ./gradlew run ``` -------------------------------- ### MServer Main Cycle Coordination Source: https://context7.com/mediathekview/mserver/llms.txt The `MServer.starten()` method reads the configuration file, initiates a timer thread (`MserverTimer`), and orchestrates the search and upload cycle. It returns `true` if a restart is requested, indicating that the server should continue running. ```java MServer server = new MServer(new String[]{"/etc/mserver/"}); // starten() liest Konfiguration, startet Suche und Upload boolean neustart = server.starten(); // -> false: kein Neustart, Programm endet // -> true: Neustart gewünscht (MserverDaten.restart == true) // Intern: MServer.laufen() wird vom Timer aufgerufen // Ablauf pro Zyklus: // 1. aktSearchTask aus MserverDaten.listeSuchen holen // 2. mvsSearch.filmeSuchen(aktSearchTask) aufrufen // 3. Bei Erfolg: MserverUpload.upload(aktSearchTask) ``` -------------------------------- ### Clone MServer and Mlib Repositories Source: https://github.com/mediathekview/mserver/blob/master/README.md Clone the MServer and Mlib repositories into a new directory to set up the project structure. ```bash mkdir mediathekview cd mediathekview git clone https://github.com/mediathekview/MServer.git git clone https://github.com/mediathekview/Mlib.git ``` -------------------------------- ### Clone MServer and MLib Repositories Source: https://github.com/mediathekview/mserver/wiki/Entwicklung Clone the necessary MServer and MLib repositories into a new directory. Navigate into the MServer directory to prepare for building. ```bash mkdir mediathekview cd mediathekview git clone https://github.com/mediathekview/MServer.git git clone https://github.com/mediathekview/MLib.git cd MServer ``` -------------------------------- ### Run SonarCloud Analysis Source: https://context7.com/mediathekview/mserver/llms.txt Execute a SonarCloud analysis for the MServer project using Gradle. Ensure the SONAR_TOKEN environment variable is set. ```bash ./gradlew sonarqube \ -Dsonar.projectKey=mediathekview_MServer \ -Dsonar.organization=mediathekview \ -Dsonar.host.url=https://sonarcloud.io \ -Dsonar.login=$SONAR_TOKEN ``` -------------------------------- ### Manage Film Lists with ListeFilme Source: https://context7.com/mediathekview/mserver/llms.txt Shows how to initialize and manage a list of films using ListeFilme. Includes adding films, importing from saved lists, merging lists, calculating differences, sorting, writing metadata, and searching for films by URL. Use for managing collections of film data. ```java ListeFilme liste = new ListeFilme(); // Film hinzufügen (beim Crawlen vom Sender) boolean neu = liste.addFilmVomSender(film); // -> false wenn URL bereits bekannt (Duplikat) // Film aus gespeicherter Filmliste importieren liste.importFilmliste(film); // setzt Laufnummer, kein Duplikatcheck // Alte Liste mergen (neue Filme ergänzen, vorhandene behalten) ListeFilme neueListe = new ListeFilme(); // ... neueListe befüllen ... lis te.updateListe( neueListe, true, // index-basierter Vergleich (Sender+Thema+URL) false // ersetzen=false: nur neue hinzufügen ); // Diff berechnen (welche Filme sind im Vergleich zur orgListe neu?) ListeFilme orgListe = new ListeFilme(); // Basis ListeFilme diff = liste.neueFilme(orgListe); System.out.println("Neue Filme: " + diff.size()); // Filmliste nach Sender/Thema sortieren lis te.sort(); // Metadaten schreiben (Datum, Version, ID) lis te.writeMetaData(); System.out.println("ID: " + liste.getId()); System.out.println("Datum: " + liste.genDate()); System.out.println("Alter (s): " + liste.getAge()); System.out.println("Zu alt für Auto-Update: " + liste.isTooOld()); System.out.println("Zu alt für Diff: " + liste.isTooOldForDiff()); // Film per URL suchen DatenFilm gefunden = liste.getFilmByUrl("https://cdn.ard.de/tatort.mp4"); // Film per URL (inkl. Klein/HD-Varianten) suchen DatenFilm gefunden2 = liste.getFilmByUrl_klein_hoch_hd("https://cdn.ard.de/tatort-hd.mp4"); // Alle Filme eines Senders löschen lis te.deleteAllFilms("ARD"); // Neue Filme zählen long anzNeu = liste.countNewFilms(); // Themen laden (für Filter-UI) lis te.themenLaden(); String[] alleSender = liste.sender; // ["", "ARD", "ZDF", ...] String[] themenARD = liste.themenPerSender[1]; // Themen für sender[1] ``` -------------------------------- ### Execute MServer Tests Source: https://context7.com/mediathekview/mserver/llms.txt MServer utilizes three distinct test directories. Run these commands from the project root to execute unit, integration, or performance tests. ```bash # Unit-Tests (ohne Mediathek-Zugriffe, verwendet Mocks) ./gradlew developTest # Integrationstests (mit echten Mediathek-API-Zugriffen) ./gradlew integrationTest # Performance-Tests ./gradlew performanceTest # Alle Tests + Build ./gradlew check developTest build ``` -------------------------------- ### Create and Manipulate DatenFilm Object Source: https://context7.com/mediathekview/mserver/llms.txt Demonstrates how to create a new DatenFilm object, add various URLs (HD, small, subtitle), set geo-restrictions, access fields directly, and clean descriptions. Use this for representing individual film entries. ```java DatenFilm film = new DatenFilm( "ARD", // Sender "Tatort", // Thema "https://www.ardmediathek.de/video/abc123", // Website "Tatort: Der letzte Fall", // Titel "https://cdn.ard.de/tatort.mp4", // URL (Normal) "", // RTMP-URL (leer lassen) "15.05.2024", // Datum (dd.MM.yyyy) "20:15:00", // Uhrzeit (HH:mm:ss) 5400L, // Dauer in Sekunden (90 min) "Spannender Krimi aus München." // Beschreibung ); // HD- und Klein-URL setzen (komprimiertes Diff-Format) CrawlerTool.addUrlHd(film, "https://cdn.ard.de/tatort-hd.mp4"); CrawlerTool.addUrlKlein(film, "https://cdn.ard.de/tatort-klein.mp4"); CrawlerTool.addUrlSubtitle(film, "https://cdn.ard.de/tatort.ttml"); // Geo-Beschränkung setzen film.arr[DatenFilm.FILM_GEO] = DatenFilm.GEO_DE; // nur DE // Felder direkt auslesen String sender = film.arr[DatenFilm.FILM_SENDER]; // "ARD" String titel = film.arr[DatenFilm.FILM_TITEL]; // "Tatort: Der letzte Fall" String url = film.arr[DatenFilm.FILM_URL]; // "https://cdn.ard.de/tatort.mp4" String datum = film.arr[DatenFilm.FILM_DATUM]; // "15.05.2024" String dauer = film.arr[DatenFilm.FILM_DAUER]; // "01:30:00" String geo = film.arr[DatenFilm.FILM_GEO]; // "DE" boolean hatHD = film.isHD(); // true boolean hatUT = film.hasUT(); // true // URL je nach gewünschter Auflösung String urlHD = film.getUrlFuerAufloesung(DatenFilm.AUFLOESUNG_HD); String urlKlein = film.getUrlFuerAufloesung(DatenFilm.AUFLOESUNG_KLEIN); // Eindeutiger Index (für Duplikatprüfung) String index = film.getIndex(); // Sender+Thema+URL String idxOld = film.getIndexAddOld(); // Sender+Thema+Titel (für Merge) // Beschreibung bereinigen (HTML entfernen, Rechtswarnungen löschen, max. 400 Zeichen) String sauber = DatenFilm.cleanDescription("

Text mit HTML...

"); ``` -------------------------------- ### Run MServer with Compression Disabled Source: https://github.com/mediathekview/mserver/blob/master/README.md To disable xz compression when running MServer, set the NOCOMPRESS environment variable to 'y' before executing the jar file. ```bash export NOCOMPRESS=y java -jar MServer.jar ``` -------------------------------- ### Implement Custom Senders with MediathekCrawler Source: https://context7.com/mediathekview/mserver/llms.txt Extend the abstract MediathekCrawler class to create custom crawlers for specific media sources. This involves defining how to fetch topic URLs and process individual films. ```java // Eigenen Crawler implementieren: public class MeinSenderCrawler extends MediathekCrawler { public MeinSenderCrawler(FilmeSuchen suchen, int prio) { super(suchen, "MeinSender", /* maxThreads */ 4, /* warteMs */ 500, /* startPrio */ 0); } @Override protected RecursiveTask> createCrawlerTask() { // Gibt eine ForkJoinTask zurück, die alle Filme sammelt ConcurrentLinkedQueue urls = ladeThemenUrls(); meldungAddMax(urls.size()); // Fortschrittsanzeige return new MeinFilmTask(this, urls); } @Override protected void prepareFilm(DatenFilm film) { // Optional: Film nachbearbeiten (z.B. HD-URL setzen) CrawlerTool.addUrlHd(film, ermittleHdUrl(film)); CrawlerTool.addUrlKlein(film, ermittleKleinUrl(film)); CrawlerTool.addUrlSubtitle(film, ermittleUntertitelUrl(film)); } } // ForkJoinPool direkt nutzen (statische Hilfsmethode): ForkJoinPool pool = MediathekCrawler.createForkJoinPool("MeinSender"); // -> Threadnamen: "MeinSender-worker-0", "MeinSender-worker-1", ... ``` -------------------------------- ### CrawlerTool for URL Manipulation and File Paths Source: https://context7.com/mediathekview/mserver/llms.txt This static utility class provides functions for checking load modes, manipulating film URLs using a compressed diff format for efficiency, and generating file paths for film lists. ```java // Lademodus prüfen boolean kurzLaden = CrawlerTool.loadShort(); // LOAD_SHORT boolean langLaden = CrawlerTool.loadLong(); // LOAD_LONG boolean maxLaden = CrawlerTool.loadMax(); // LOAD_MAX boolean minLang = CrawlerTool.loadLongMax(); // LOAD_LONG oder LOAD_MAX // Film-URLs setzen (komprimiertes Diff-Format: "n|suffix" spart Speicher) DatenFilm film = new DatenFilm("ZDF", "Krimi", "...", "Titel", "https://zdf.de/video.l.mp4", "", "14.05.2024", "21:45:00", 3600, ""); CrawlerTool.addUrlHd(film, "https://zdf.de/video.hd.mp4"); // -> FILM_URL_HD = "14|hd.mp4" (nur die Abweichung ab Position 14) CrawlerTool.addUrlKlein(film, "https://zdf.de/video.s.mp4"); // -> FILM_URL_KLEIN = "14|s.mp4" CrawlerTool.addUrlSubtitle(film, "https://zdf.de/video.ttml"); // -> FILM_URL_SUBTITLE = "https://zdf.de/video.ttml" // Dateipfade der Filmlisten String aktuelleJson = CrawlerTool.getPathFilmlist_json_akt(false); // -> /pfad/filmlisten/filme.json String mitDatum = CrawlerTool.getPathFilmlist_json_akt(true); // -> /pfad/filmlisten/2024.05.15__03.30.00__filme.json String orgJson = CrawlerTool.getPathFilmlist_json_org(); // filme-org.json String diffJson = CrawlerTool.getPathFilmlist_json_diff(); // filme-diff.json String aktXz = CrawlerTool.getPathFilmlist_json_akt_xz(); // filme.xz String orgXz = CrawlerTool.getPathFilmlist_json_org_xz(); // filme-org.xz String diffXz = CrawlerTool.getPathFilmlist_json_diff_xz(); // filme-diff.xz ``` -------------------------------- ### Configure ZDF Crawler Loading Mode Source: https://context7.com/mediathekview/mserver/llms.txt Controls the data retrieval mode for the ZDF Mediathek crawler. LOAD_SHORT fetches daily programs, while LOAD_MAX retrieves all content including archives and A-Z listings. ```java // Short-Modus: Tagesprogramm per API // URL_DAY: ZdfConstants.URL_DAY (formatiert mit Datum) // Auth-Key: wird dynamisch von der ZDF-Startseite geladen (ZdfIndexPageTask) // Long/Max-Modus: A-Z Buchstabenindex (27 Seiten) // ZdfLetterPageTask + ZdfTopicSeasonTask + ZdfPubFormTask für Sondersammlungen // Interner Auth-Key für Long-Modus (fest kodiert): // private static final String AUTH_KEY = "aa3noh4ohz9eeboo8shiesheec9ciequ9Quah7el"; // Sub-Sender die ZdfCrawler beendet: // ZDF-tivi, ZDFinfo, ZDFneo // Lademodus steuern: CrawlerConfig.senderLoadHow = CrawlerConfig.LOAD_SHORT; // nur Tagesprogramm CrawlerConfig.senderLoadHow = CrawlerConfig.LOAD_MAX; // alles inkl. Archiv ``` -------------------------------- ### Configure Banned Film List Path Source: https://context7.com/mediathekview/mserver/llms.txt Sets the location of the banned film titles list. Supports file, HTTP/HTTPS, and classpath resources. Matching is case-insensitive. ```java // Sperrliste konfigurieren in Systemkonfiguration: // MserverDaten.system[MserverKonstanten.SYSTEM_BANNEDFILMLIST_NR] = "file:///etc/mserver/banned.txt" // oder: "https://example.com/banned-titles.txt" // oder: "classpath:banned-titles.txt" // Dateiformat: eine gesperrte Teilzeichenkette pro Zeile // Beispiel banned.txt: // Dauerwerbesendung // Tele-Shopping // Glücksspiel // Automatische Anwendung in MediathekReader.addFilm(): BannedFilmFilter filter = new BannedFilmFilter(); DatenFilm film = new DatenFilm("ARD", "Werbung", "...", "Dauerwerbesendung 123", "...", "", "", "", 0, ""); boolean gesperrt = filter.isBanned(film); // -> true (Titel enthält "Dauerwerbesendung") // InputStream-Helper unterstützt verschiedene Protokolle: InputStream is = BannedFilmFilter.getInputStreamFromPath("https://cdn.example.com/banned.txt.gz"); // -> Erkennt GZIP-Kodierung automatisch (Content-Encoding: gzip) InputStream is2 = BannedFilmFilter.getInputStreamFromPath("file:///etc/mserver/banned.txt"); InputStream is3 = BannedFilmFilter.getInputStreamFromPath("classpath:banned-default.txt"); ``` -------------------------------- ### Orchestrate Film Searches with FilmeSuchen Source: https://context7.com/mediathekview/mserver/llms.txt Manage and initiate crawls for various media libraries. Supports full searches and specific channel updates. Register listeners to track progress. ```java FilmeSuchen filmeSuchen = new FilmeSuchen(); // Alle konfigurierten Sender crawlen ListeFilme alteListe = new ListeFilme(); // vorhandene Liste filmeSuchen.filmeBeimSenderLaden(alteListe); // -> Prio-0-Crawler (ARD, ZDF, ARTE, DW, KIKA, 3SAT, PHOENIX) starten sofort // -> Prio-1-Crawler (SR, SRF, ORF) starten nach 4 Minuten // -> Ergebnis in filmeSuchen.listeFilmeNeu (neue Filme) // -> Merge mit alteListe wenn CrawlerConfig.updateFilmliste == true // Einzelnen Sender aktualisieren filmeSuchen.updateSender(new String[]{"ARD", "ZDF"}, alteListe); // Fortschritts-Listener registrieren filmeSuchen.addAdListener(new ListenerFilmeLaden() { @Override public void start(ListenerFilmeLadenEvent e) { System.out.println("Start: " + e.sender); } @Override public void progress(ListenerFilmeLadenEvent e) { System.out.println("Fortschritt: " + e.progress + "/" + e.max + " Filme: " + e.count); } @Override public void fertig(ListenerFilmeLadenEvent e) { System.out.println("Fertig. Gesamt-Filme: " + e.count); } }); // Senderliste abrufen String[] allesSender = FilmeSuchen.getNamenSender(); // -> ["3Sat", "ARD", "ARTE.DE", "ARTE.FR", "BR", "DW", "HR", ...] ``` -------------------------------- ### Configure ArdCrawler Loading Mode Source: https://context7.com/mediathekview/mserver/llms.txt Determines the data scope for the ARD Mediathek crawler. Set to true for extended data (past/future days and topics), false for only past program data. ```java // ArdCrawler intern: crawlt Tages-Programm der letzten 7 Tage // API-Endpunkt: https://programm-api.ard.de/program/api/program?day=YYYY-MM-DD&channelIds=daserste&mode=channel // Kanäle: daserste, br, hr, mdr, ndr, radiobremen, rbb, sr, swr, wdr, one, alpha, tagesschau24, phoenix, funk // Im LOAD_MAX-Modus zusätzlich: Themen-Übersicht (A–Z) // API: https://api.ardmediathek.de/page-gateway/pages/ard/editorial/experiment-a-z // Themen-Details: https://api.ardmediathek.de/page-gateway/widgets/ard/asset/{topicId}?pageSize=50 // Film-Details: https://api.ardmediathek.de/page-gateway/pages/ard/item/{itemId}?embedded=true&mcV6=true // Konfiguration prüfen boolean langLaden = CrawlerTool.loadLongMax(); // true bei LOAD_LONG oder LOAD_MAX // -> true: 7 Tage Vergangenheit + 7 Tage Zukunft + alle Themen // -> false: nur 7 Tage Vergangenheit // ArdCrawler erzeugt am Ende alle Sub-Sender als "fertig": // ARD, RBB, SWR, MDR, NDR, WDR, HR, BR, rbtv, ONE, ARD-alpha, Funk.net, tagesschau24, SR, PHOENIX ``` -------------------------------- ### RunSender for Crawler Runtime Statistics Source: https://context7.com/mediathekview/mserver/llms.txt This thread-safe class tracks counters for active crawler runs, including films found, errors, and traffic. It's evaluated after a sender completes and statistics are transferred. ```java RunSender run = new RunSender("ARD", /* max */ 500, /* progress */ 0); // Zähler inkrementieren (thread-sicher mit AtomicLong) // In MediathekReader.addFilm() automatisch aufgerufen: FilmeSuchen.listeSenderLaufen.inc("Ard-ARD", RunSender.Count.FILME); FilmeSuchen.listeSenderLaufen.inc("Ard-ARD", RunSender.Count.ANZAHL); // Seiten FilmeSuchen.listeSenderLaufen.inc("Ard-ARD", RunSender.Count.FEHLER); // Fehler FilmeSuchen.listeSenderLaufen.inc("Ard-ARD", RunSender.Count.SUM_TRAFFIC_BYTE); // Nach Abschluss: int sekunden = run.getLaufzeitSekunden(); // Gesamtdauer String minSek = run.getLaufzeitMinuten(); // "12:34" long anzFilme = run.counter.get(RunSender.Count.FILME).get(); long traffic = run.counter.get(RunSender.Count.SUM_TRAFFIC_BYTE).get(); String trafficMB = RunSender.getStringZaehler(traffic); // Megabyte als String // Alle Zähler-Typen: // ANZAHL -> Anzahl abgerufener Seiten/API-Aufrufe // FILME -> Anzahl gefundener Filme // FEHLER -> HTTP/Parse-Fehler // FEHLVERSUCHE -> Wiederholungsversuche // WARTEZEIT_FEHLVERSUCHE -> Wartezeit durch Wiederholungen (Sekunden) // PROXY -> Seiten über Proxy geladen // SUM_DATA_BYTE -> Entpackte Datenmenge (Bytes) // SUM_TRAFFIC_BYTE -> Übertragene Datenmenge (Bytes) ``` -------------------------------- ### GeoLocations Enum for Geo-Blocking Source: https://context7.com/mediathekview/mserver/llms.txt Use this enum to manage and identify supported geo-restrictions for media. The `find()` method allows searching by string, including aliases. Descriptions are used for storage in `DatenFilm.arr[FILM_GEO]`. ```java // Alle verfügbaren Geo-Werte: // GEO_NONE -> "" (weltweit verfügbar) // GEO_DE -> "DE" // GEO_AT -> "AT" // GEO_CH -> "CH" // GEO_EU -> "EU" // GEO_DE_FR -> "DE-FR" // GEO_DE_AT_CH -> "DE-AT-CH" (DACH) // GEO_DE_AT_CH_EU -> "DE-AT-CH-EU" // GEO_DE_AT_CH_FR -> "DE-AT-CH-FR" // Geo-Wert per String suchen (inkl. Alias-Erkennung): Optional geo = GeoLocations.find("dach"); // -> Optional[GEO_DE_AT_CH] Optional geo2 = GeoLocations.find("EBU"); // -> Optional[GEO_DE_AT_CH_EU] Optional geo3 = GeoLocations.find("WELT"); // -> Optional[GEO_NONE] // Beschreibung abrufen (wird in DatenFilm.arr[FILM_GEO] gespeichert): String beschreibung = GeoLocations.GEO_DE_AT_CH.getDescription(); // "DE-AT-CH" // Manuell am Film setzen: film.arr[DatenFilm.FILM_GEO] = GeoLocations.GEO_DE.getDescription(); // "DE" film.arr[DatenFilm.FILM_GEO] = GeoLocations.GEO_DE_AT_CH.getDescription(); // "DE-AT-CH" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.