diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Danmaku.java b/app/src/main/java/com/fongmi/android/tv/bean/Danmaku.java index 17db03a96..77fdab059 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Danmaku.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Danmaku.java @@ -6,6 +6,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.fongmi.android.tv.App; +import com.fongmi.android.tv.utils.UrlUtil; import com.google.gson.annotations.SerializedName; public class Danmaku { @@ -56,6 +57,10 @@ public class Danmaku { return getUrl().isEmpty(); } + public String getRealUrl() { + return UrlUtil.convert(getUrl().startsWith("/") ? "file:/" + getUrl() : getUrl()); + } + @Override public boolean equals(@Nullable Object obj) { if (this == obj) return true; diff --git a/app/src/main/java/com/fongmi/android/tv/player/danmaku/DanPlayer.java b/app/src/main/java/com/fongmi/android/tv/player/danmaku/DanPlayer.java index 6a7cbf130..3e3b47abb 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/danmaku/DanPlayer.java +++ b/app/src/main/java/com/fongmi/android/tv/player/danmaku/DanPlayer.java @@ -91,6 +91,7 @@ public class DanPlayer implements DrawHandler.Callback { public void release() { App.execute(() -> { if (!isPrepared()) return; + loader.clear(); view.release(); }); } diff --git a/app/src/main/java/com/fongmi/android/tv/player/danmaku/Loader.java b/app/src/main/java/com/fongmi/android/tv/player/danmaku/Loader.java index cc243070b..3e709c6ae 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/danmaku/Loader.java +++ b/app/src/main/java/com/fongmi/android/tv/player/danmaku/Loader.java @@ -2,29 +2,42 @@ package com.fongmi.android.tv.player.danmaku; import com.fongmi.android.tv.Constant; import com.fongmi.android.tv.bean.Danmaku; -import com.fongmi.android.tv.utils.UrlUtil; import com.github.catvod.net.OkHttp; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; import master.flame.danmaku.danmaku.loader.ILoader; import master.flame.danmaku.danmaku.loader.IllegalDataException; import master.flame.danmaku.danmaku.parser.android.AndroidFileSource; import okhttp3.OkHttpClient; +import okhttp3.Response; public class Loader implements ILoader { + private static final int MAX_CACHE_SIZE = 10; + private final Map cache; private final OkHttpClient client; - private AndroidFileSource dataSource; + private AndroidFileSource source; public Loader() { client = OkHttp.client(Constant.TIMEOUT_DANMAKU); + cache = Collections.synchronizedMap(new LinkedHashMap<>(MAX_CACHE_SIZE, 0.75f, true) { + @Override + protected boolean removeEldestEntry(Entry eldest) { + return size() > MAX_CACHE_SIZE; + } + }); } public Loader load(Danmaku item) { try { - load(item.getUrl()); + OkHttp.cancel("danmaku"); + load(item.getRealUrl()); return this; } catch (IllegalDataException e) { return this; @@ -33,22 +46,35 @@ public class Loader implements ILoader { @Override public void load(String url) throws IllegalDataException { - try { - OkHttp.cancel(client, "danmaku"); - if (url.startsWith("/")) url = "file:/" + url; - load(OkHttp.newCall(client, UrlUtil.convert(url), "danmaku").execute().body().byteStream()); - } catch (IOException e) { - e.printStackTrace(); + if (cache.containsKey(url)) { + load(cache.get(url)); + } else try (Response res = OkHttp.newCall(client, url, "danmaku").execute()) { + byte[] data = res.body().bytes(); + if (data.length > 0) load(url, data); + } catch (IOException ignored) { } } + public void load(String key, byte[] bytes) throws IllegalDataException { + cache.put(key, bytes); + load(bytes); + } + + public void load(byte[] bytes) throws IllegalDataException { + load(new ByteArrayInputStream(bytes)); + } + @Override public void load(InputStream stream) throws IllegalDataException { - dataSource = new AndroidFileSource(stream); + source = new AndroidFileSource(stream); } @Override public AndroidFileSource getDataSource() { - return dataSource; + return source; + } + + public void clear() { + cache.clear(); } } \ No newline at end of file