/** DR Radio 2 is developed by Jacob Nordfalk, Hanafi Mughrabi and Frederik Aagaard. Some parts of the code are loosely based on Sveriges Radio Play for Android. DR Radio 2 for Android is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. DR Radio 2 for Android is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DR Radio 2 for Android. If not, see <http://www.gnu.org/licenses/>. */ package dk.dr.radio.data; import android.os.Build; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import dk.dr.radio.diverse.App; import dk.dr.radio.diverse.Log; public class Grunddata { /** * Grunddata */ public JSONObject android_json; public JSONObject json; public List<String> p4koder = new ArrayList<String>(); public List<Kanal> kanaler = new ArrayList<Kanal>(); public Kanal forvalgtKanal; public ArrayList<Runnable> observatører = new ArrayList<Runnable>(); // Om grunddata/stamdata ændrer sig /** find en kanal ud fra kode, f.eks. P1D, P2D, P3, P4F, RØ4, ES4, OD4, KH4, HO4, ÅL4, NV4, ÅB4, TR4, ÅR4, P5D, P6B, P7M, P8J, RAM, DRN */ public HashMap<String, Kanal> kanalFraKode = new HashMap<String, Kanal>(); public HashMap<String, Kanal> kanalFraSlug = new LinkedHashMap<String, Kanal>(); public static final Kanal ukendtKanal = new Kanal(); public long opdaterPlaylisteEfterMs = 30 * 1000; public long opdaterGrunddataEfterMs = 30 * 60 * 1000; /** Om Http Live Streaming skal udelukkes fra mulige lydformater. Gælder på Android 2 og visse Android 4-enheder */ public boolean udelukHLS; public boolean tving_exoplayer; public boolean tving_mediaplayer; public boolean tving_emaplayer; public boolean serverapi_ret_forkerte_offsets_i_playliste; public Grunddata() { ukendtKanal.navn = ""; ukendtKanal.slug = ""; ukendtKanal.kode = ""; ukendtKanal.urn = ""; kanalFraKode.put(null, ukendtKanal); kanalFraKode.put("", ukendtKanal); kanalFraSlug.put(null, ukendtKanal); kanalFraSlug.put("", ukendtKanal); } private void fjernKanalMedFejl(Kanal k) { kanaler.remove(k); p4koder.remove(k.kode); kanalFraKode.remove(k.kode); kanalFraSlug.remove(k.slug); } private void parseKanaler(JSONArray jsonArray, boolean parserP4underkanaler) throws JSONException { int antal = jsonArray.length(); for (int i = 0; i < antal; i++) { JSONObject j = jsonArray.getJSONObject(i); String kanalkode = j.optString("scheduleIdent", Kanal.P4kode); Kanal k = kanalFraKode.get(kanalkode); if (k == null) { k = new Kanal(); k.kode = j.optString("scheduleIdent", Kanal.P4kode); kanalFraKode.put(k.kode, k); } k.navn = j.getString("title"); k.urn = j.getString("urn"); k.slug = j.optString("slug", "p4"); k.ingenPlaylister = j.optBoolean("hideLatestTrack", false); k.p4underkanal = parserP4underkanaler; kanaler.add(k); if (parserP4underkanaler) p4koder.add(k.kode); kanalFraSlug.put(k.slug, k); if (j.optBoolean("isDefault")) forvalgtKanal = k; JSONArray underkanaler = j.optJSONArray("channels"); if (underkanaler != null) { if (!Kanal.P4kode.equals(k.kode)) Log.rapporterFejl(new IllegalStateException("Forkert P4-kode: "), k.kode); parseKanaler(underkanaler, true); } } } /** * Henter grunddata (faste data) * @throws java.io.IOException hvis der er et problem med netværk * eller parsning (dvs interne fejl af forskellig art som bør rapporteres til udvikler) */ public void parseFællesGrunddata(String str) throws JSONException { json = new JSONObject(str); try { opdaterGrunddataEfterMs = json.getJSONObject("intervals").getInt("settings") * 1000; opdaterPlaylisteEfterMs = json.getJSONObject("intervals").getInt("playlist") * 1000; } catch (Exception e) { Log.e(e); } // Ikke kritisk kanaler.clear(); p4koder.clear(); parseKanaler(json.getJSONArray("channels"), false); Log.d("parseKanaler " + kanaler + " - P4:" + p4koder); android_json = json.getJSONObject("android"); tjekUdelukFraHLS(Build.MODEL + " " + Build.PRODUCT + "/" + Build.VERSION.SDK_INT); DRBackendTidsformater.servertidsformatAndre = parseDRBackendTidsformater(android_json.optJSONArray("servertidsformatAndre"), DRBackendTidsformater.servertidsformatAndre); DRBackendTidsformater.servertidsformatPlaylisteAndre2 = parseDRBackendTidsformater(android_json.optJSONArray("servertidsformatPlaylisteAndre2"), DRBackendTidsformater.servertidsformatPlaylisteAndre2); if (forvalgtKanal == null) forvalgtKanal = kanaler.get(2); // Det er nok P3 :-) for (Runnable r : new ArrayList<Runnable>(observatører)) r.run(); } /** * Sætter flaget udelukHLS, som slår HLS fra på Android-enheder, der ikke understøtter det * @param model_og_version */ public void tjekUdelukFraHLS(String model_og_version) { Log.d("tjekUdelukFraHLS(" + model_og_version); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH && !App.testFraMain()) { Log.d("tjekUdelukFraHLS() - Android 2 (og 3) understøtter ikke HLS"); udelukHLS = true; return; } udelukHLS = søgEfterMatch(model_og_version, android_json.optString("udeluk_HLS2")); tving_exoplayer = søgEfterMatch(model_og_version, android_json.optString("tving_exoplayer")); tving_mediaplayer = søgEfterMatch(model_og_version, android_json.optString("tving_mediaplayer")); tving_emaplayer = søgEfterMatch(model_og_version, android_json.optString("tving_emaplayer")); serverapi_ret_forkerte_offsets_i_playliste = android_json.optBoolean("serverapi_ret_forkerte_offsets_i_playliste", true); } private static boolean søgEfterMatch(String model_og_version, String søgestreng) { try { for (String lin : søgestreng.split(",")) { if (model_og_version.matches(lin.trim())) { Log.d("tjek " + søgestreng + " linjen " + lin + " MATCHER " + model_og_version); return true; } } } catch (Exception e) { Log.e(e); } // Ikke kritisk return false; } private DateFormat[] parseDRBackendTidsformater(JSONArray servertidsformatAndreJson, DateFormat[] servertidsformatAndre) throws JSONException { if (servertidsformatAndreJson==null) return servertidsformatAndre; DateFormat[] res = new DateFormat[servertidsformatAndreJson.length()]; for (int i=0; i<res.length; i++) { res[i] = new SimpleDateFormat(servertidsformatAndreJson.getString(i), Locale.US); } return res; } }