From 4114be32cb7181b4a8fbc6be0a583c47837ae55e Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 10 Jun 2024 19:33:21 +0800 Subject: [PATCH 1/5] Optimize metadata --- .../android/tv/ui/activity/CastActivity.java | 11 +--- .../android/tv/ui/activity/LiveActivity.java | 20 +------- .../android/tv/ui/activity/VideoActivity.java | 22 +------- .../com/fongmi/android/tv/player/Players.java | 50 +++++++++++++++++++ .../android/tv/service/PlaybackService.java | 5 ++ .../android/tv/ui/activity/LiveActivity.java | 32 ++---------- .../android/tv/ui/activity/VideoActivity.java | 35 ++----------- .../android/tv/ui/dialog/InfoDialog.java | 19 +++---- 8 files changed, 77 insertions(+), 117 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java index 8debd5ab0..7144c47f2 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CastActivity.java @@ -350,16 +350,7 @@ public class CastActivity extends BaseActivity implements CustomKeyDownCast.List } private void setMetadata() { - String title = mBinding.widget.title.getText().toString(); - MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); - builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title); - try { - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork()); - } catch (Exception e) { - e.printStackTrace(); - } - builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration()); - mPlayers.setMetadata(builder.build()); + mPlayers.setMetadata(mBinding.widget.title.getText().toString(), "", mBinding.exo); } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java index 826c5f0dd..95ad21da3 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/LiveActivity.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; -import android.support.v4.media.MediaMetadataCompat; import android.view.KeyEvent; import android.view.View; @@ -407,13 +406,7 @@ public class LiveActivity extends BaseActivity implements Clock.Callback, GroupP private boolean onChoose() { if (mPlayers.isEmpty()) return false; - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - intent.putExtra("headers", mPlayers.getHeaderArray()); - intent.putExtra("title", mBinding.widget.name.getText()); - intent.setDataAndType(mPlayers.getUri(), "video/*"); - startActivity(Util.getChooser(intent)); + mPlayers.choose(this, mBinding.widget.title.getText()); return true; } @@ -779,16 +772,7 @@ public class LiveActivity extends BaseActivity implements Clock.Callback, GroupP private void setMetadata() { String title = mBinding.widget.name.getText().toString(); String artist = mBinding.widget.play.getText().toString(); - MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); - builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title); - builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist); - try { - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork()); - } catch (Exception e) { - e.printStackTrace(); - } - builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration()); - mPlayers.setMetadata(builder.build()); + mPlayers.setMetadata(title, artist, mBinding.exo); } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 0e085dd2b..f2fa60cf0 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -6,7 +6,6 @@ import android.app.Activity; import android.content.Intent; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.support.v4.media.MediaMetadataCompat; import android.text.Html; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -1020,15 +1019,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List private boolean onChoose() { if (mPlayers.isEmpty()) return false; - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - intent.putExtra("return_result", true); - intent.putExtra("headers", mPlayers.getHeaderArray()); - intent.putExtra("position", (int) mPlayers.getPosition()); - intent.putExtra("title", mBinding.widget.title.getText()); - intent.setDataAndType(mPlayers.getUri(), "video/*"); - startActivityForResult(Util.getChooser(intent), 1001); + mPlayers.choose(this, mBinding.widget.title.getText()); return true; } @@ -1374,16 +1365,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List String title = mHistory == null ? getName() : mHistory.getVodName(); String artist = mEpisodeAdapter.size() == 0 ? "" : getEpisode().getName(); artist = title.equals(artist) ? "" : getString(R.string.play_now, artist); - MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); - builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title); - builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist); - try { - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork()); - } catch (Exception e) { - e.printStackTrace(); - } - builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration()); - mPlayers.setMetadata(builder.build()); + mPlayers.setMetadata(title, artist, mBinding.exo); } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/com/fongmi/android/tv/player/Players.java b/app/src/main/java/com/fongmi/android/tv/player/Players.java index 23d59e26f..3cc0e9068 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/Players.java +++ b/app/src/main/java/com/fongmi/android/tv/player/Players.java @@ -3,6 +3,8 @@ package com.fongmi.android.tv.player; import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Bundle; import android.support.v4.media.MediaMetadataCompat; @@ -600,6 +602,54 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic return bundle; } + public void setMetadata(String title, String artist, PlayerView view) { + try { + Bitmap bitmap = ((BitmapDrawable) view.getDefaultArtwork()).getBitmap(); + MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); + builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title); + builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist); + builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, bitmap); + builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, getDuration()); + session.setMetadata(builder.build()); + ActionEvent.update(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void share(Activity activity, CharSequence title) { + try { + if (isEmpty()) return; + Intent intent = new Intent(Intent.ACTION_SEND); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(Intent.EXTRA_TEXT, getUrl()); + intent.putExtra("extra_headers", getHeaderBundle()); + intent.putExtra("title", title); + intent.putExtra("name", title); + intent.setType("text/plain"); + activity.startActivity(Util.getChooser(intent)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void choose(Activity activity, CharSequence title) { + try { + if (isEmpty()) return; + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.setDataAndType(getUri(), "video/*"); + intent.putExtra("title", title); + intent.putExtra("return_result", isVod()); + intent.putExtra("headers", getHeaderArray()); + if (isVod()) intent.putExtra("position", (int) getPosition()); + activity.startActivityForResult(Util.getChooser(intent), 1001); + } catch (Exception e) { + e.printStackTrace(); + } + } + public void checkData(Intent data) { try { if (data == null || data.getExtras() == null) return; diff --git a/app/src/mobile/java/com/fongmi/android/tv/service/PlaybackService.java b/app/src/mobile/java/com/fongmi/android/tv/service/PlaybackService.java index 0496309f9..e44ee9fe8 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/service/PlaybackService.java +++ b/app/src/mobile/java/com/fongmi/android/tv/service/PlaybackService.java @@ -141,6 +141,11 @@ public class PlaybackService extends Service { return START_NOT_STICKY; } + @Override + public void onTaskRemoved(Intent rootIntent) { + stopSelf(); + } + @Override public void onDestroy() { EventBus.getDefault().unregister(this); diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java index d34afa7eb..4758a4528 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/LiveActivity.java @@ -8,7 +8,6 @@ import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; -import android.support.v4.media.MediaMetadataCompat; import android.view.MotionEvent; import android.view.View; @@ -463,13 +462,7 @@ public class LiveActivity extends BaseActivity implements Clock.Callback, Custom private boolean onChoose() { if (mPlayers.isEmpty()) return false; - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - intent.putExtra("headers", mPlayers.getHeaderArray()); - intent.putExtra("title", mBinding.control.title.getText()); - intent.setDataAndType(mPlayers.getUri(), "video/*"); - startActivity(Util.getChooser(intent)); + mPlayers.choose(this, mBinding.control.title.getText()); setRedirect(true); return true; } @@ -843,17 +836,7 @@ public class LiveActivity extends BaseActivity implements Clock.Callback, Custom private void setMetadata() { String title = mBinding.widget.name.getText().toString(); String artist = mBinding.widget.play.getText().toString(); - MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); - builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title); - builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist); - try { - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork()); - } catch (Exception e) { - e.printStackTrace(); - } - builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration()); - mPlayers.setMetadata(builder.build()); - ActionEvent.update(); + mPlayers.setMetadata(title, artist, mBinding.exo); } @Subscribe(threadMode = ThreadMode.MAIN) @@ -1130,15 +1113,8 @@ public class LiveActivity extends BaseActivity implements Clock.Callback, Custom } @Override - public void onShare(CharSequence title, String url) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Intent.EXTRA_TEXT, url); - intent.putExtra("extra_headers", mPlayers.getHeaderBundle()); - intent.putExtra("title", title); - intent.putExtra("name", title); - intent.setType("text/plain"); - startActivity(Util.getChooser(intent)); + public void onShare(CharSequence title) { + mPlayers.share(this, title); setRedirect(true); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 316e9b0e1..86bd40ba5 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -12,7 +12,6 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; -import android.support.v4.media.MediaMetadataCompat; import android.text.Html; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -911,15 +910,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo private boolean onChoose() { if (mPlayers.isEmpty()) return false; - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - intent.putExtra("return_result", true); - intent.putExtra("headers", mPlayers.getHeaderArray()); - intent.putExtra("position", (int) mPlayers.getPosition()); - intent.putExtra("title", mBinding.control.title.getText()); - intent.setDataAndType(mPlayers.getUri(), "video/*"); - startActivityForResult(Util.getChooser(intent), 1001); + mPlayers.choose(this, mBinding.control.title.getText()); setRedirect(true); return true; } @@ -1319,17 +1310,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo String title = mHistory == null ? getName() : mHistory.getVodName(); String artist = mEpisodeAdapter.isEmpty() ? "" : getEpisode().getName(); artist = title.equals(artist) ? "" : getString(R.string.play_now, artist); - MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); - builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title); - builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist); - try { - builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, getIjk().getDefaultArtwork()); - } catch (Exception e) { - e.printStackTrace(); - } - builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mPlayers.getDuration()); - mPlayers.setMetadata(builder.build()); - ActionEvent.update(); + mPlayers.setMetadata(title, artist, mBinding.exo); } @Subscribe(threadMode = ThreadMode.MAIN) @@ -1682,15 +1663,9 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo } @Override - public void onShare(CharSequence title, String url) { - if (IDMUtil.downloadFile(this, url, title.toString(), mPlayers.getHeaders(), false, false)) return; - Intent intent = new Intent(Intent.ACTION_SEND); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(Intent.EXTRA_TEXT, url); - intent.putExtra("name", title); - intent.putExtra("title", title); - intent.setType("text/plain"); - startActivity(Util.getChooser(intent)); + public void onShare(CharSequence title) { + if (IDMUtil.downloadFile(this, mPlayers.getUrl(), title.toString(), mPlayers.getHeaders(), false, false)) return; + mPlayers.share(this, title); setRedirect(true); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/dialog/InfoDialog.java b/app/src/mobile/java/com/fongmi/android/tv/ui/dialog/InfoDialog.java index 0bfdeb43f..7e86f59dd 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/dialog/InfoDialog.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/dialog/InfoDialog.java @@ -1,7 +1,6 @@ package com.fongmi.android.tv.ui.dialog; import android.app.Activity; -import android.net.Uri; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -47,8 +46,7 @@ public class InfoDialog { } public InfoDialog url(String url) { - if (TextUtils.isEmpty(url)) url = ""; - this.url = url.startsWith("data") ? url.substring(0, Math.min(url.length(), 128)).concat("...") : url; + this.url = url; return this; } @@ -65,8 +63,8 @@ public class InfoDialog { } private void initView() { - binding.url.setText(url); binding.title.setText(title); + binding.url.setText(fixUrl()); binding.header.setText(header); binding.url.setVisibility(TextUtils.isEmpty(url) ? View.GONE : View.VISIBLE); binding.header.setVisibility(TextUtils.isEmpty(header) ? View.GONE : View.VISIBLE); @@ -78,8 +76,12 @@ public class InfoDialog { binding.header.setOnLongClickListener(v -> onCopy(header)); } + private String fixUrl() { + return TextUtils.isEmpty(url) ? "" : url.startsWith("data") ? url.substring(0, Math.min(url.length(), 128)).concat("...") : url; + } + private void onShare(View view) { - callback.onShare(title, convert(url)); + callback.onShare(title); dialog.dismiss(); } @@ -89,13 +91,8 @@ public class InfoDialog { return true; } - private String convert(String url) { - if (TextUtils.isEmpty(url)) url = ""; - return url.startsWith("http://127.0.0.1:7777") ? Uri.parse(url).getQueryParameter("url") : url; - } - public interface Listener { - void onShare(CharSequence title, String url); + void onShare(CharSequence title); } } From 88d228298131253ed579251979c346d84ae98851 Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 10 Jun 2024 19:38:12 +0800 Subject: [PATCH 2/5] Danmu line add or sub, fix control next focus --- .../android/tv/ui/activity/VideoActivity.java | 49 +++++++++++++++++-- .../leanback/res/layout/view_control_vod.xml | 2 +- .../com/fongmi/android/tv/player/Players.java | 4 +- .../android/tv/ui/activity/VideoActivity.java | 2 +- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index f2fa60cf0..d8a217dba 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -358,6 +358,8 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mBinding.control.opening.setDownListener(this::onOpeningSub); mBinding.control.loop.setOnClickListener(view -> onLoop()); mBinding.control.danmu.setOnClickListener(view -> onDanmu()); + mBinding.control.danmu.setUpListener(this::onDanmuAdd); + mBinding.control.danmu.setDownListener(this::onDanmuSub); mBinding.control.next.setOnClickListener(view -> checkNext()); mBinding.control.prev.setOnClickListener(view -> checkPrev()); mBinding.control.episodes.setOnClickListener(view -> onEpisodes()); @@ -452,19 +454,24 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List setSubtitle(16); } - private void setDanmuView() { - int maxLine = Setting.getDanmuLine(3); - mPlayers.setDanmuView(mBinding.danmaku); + private void setDanmuViewSettings() { float[] range = {2.4f, 1.8f, 1.2f, 0.8f}; float speed = range[Setting.getDanmuSpeed()]; float alpha = Setting.getDanmuAlpha() / 100.0f; - float sizeScale = Setting.getDanmuSize(); + float sizeScale = isFullscreen() ? 1.2f * Setting.getDanmuSize() : 0.8f * Setting.getDanmuSize(); + int maxLine = Setting.getDanmuLine(3); HashMap maxLines = new HashMap<>(); maxLines.put(BaseDanmaku.TYPE_FIX_TOP, maxLine); maxLines.put(BaseDanmaku.TYPE_SCROLL_RL, maxLine); maxLines.put(BaseDanmaku.TYPE_SCROLL_LR, maxLine); maxLines.put(BaseDanmaku.TYPE_FIX_BOTTOM, maxLine); - mDanmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN, 3).setMaximumLines(maxLines).setScrollSpeedFactor(speed).setDanmakuTransparency(alpha).setDanmakuMargin(12).setScaleTextSize(sizeScale); + mDanmakuContext.setMaximumLines(maxLines).setScrollSpeedFactor(speed).setDanmakuTransparency(alpha).setScaleTextSize(sizeScale); + } + + private void setDanmuView() { + mPlayers.setDanmuView(mBinding.danmaku); + setDanmuViewSettings(); + mDanmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN, 3).setDanmakuMargin(8); mBinding.control.danmu.setActivated(Setting.isDanmu()); } @@ -881,6 +888,22 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List showDanmu(); } + private void onDanmuAdd() { + int line = Setting.getDanmuLine(3); + line = Math.min(line + 1, 15); + Setting.putDanmuLine(line); + mBinding.control.danmu.setText(line + ResUtil.getString(R.string.lines)); + setDanmuViewSettings(); + } + + private void onDanmuSub() { + int line = Setting.getDanmuLine(3); + line = Math.max(line - 1, 1); + Setting.putDanmuLine(line); + mBinding.control.danmu.setText(line + ResUtil.getString(R.string.lines)); + setDanmuViewSettings(); + } + private void showDanmu() { if (Setting.isDanmu()) mBinding.danmaku.show(); else mBinding.danmaku.hide(); @@ -1104,11 +1127,27 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mBinding.widget.center.setVisibility(View.GONE); } + private void setControlNextFocus() { + int count = mBinding.control.actionLayout.getChildCount(); + for(int i=0; i - = 2 ? 1f : 0.1f; - speed = speed >= 5 ? 0.2f : Math.min(speed + addon, 5.0f); + float addon = speed >= 2 ? 1f : 0.25f; + speed = speed >= 5 ? 0.25f : Math.min(speed + addon, 5.0f); return setSpeed(speed); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java index 86bd40ba5..b8ab85b67 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/VideoActivity.java @@ -420,11 +420,11 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo } public void setDanmuViewSettings() { - int maxLine = Setting.getDanmuLine(2); float[] range = {2.4f, 1.8f, 1.2f, 0.8f}; float speed = range[Setting.getDanmuSpeed()]; float alpha = Setting.getDanmuAlpha() / 100.0f; float sizeScale = Setting.getDanmuSize(); + int maxLine = Setting.getDanmuLine(2); HashMap maxLines = new HashMap<>(); maxLines.put(BaseDanmaku.TYPE_FIX_TOP, maxLine); maxLines.put(BaseDanmaku.TYPE_SCROLL_RL, maxLine); From 7d581fa4f587b9fb115cfdbdfb9474db2a28f2bb Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 10 Jun 2024 19:41:01 +0800 Subject: [PATCH 3/5] Support xml.gz --- .../com/fongmi/android/tv/api/EpgParser.java | 47 ++++++++++--------- .../java/com/fongmi/android/tv/bean/Tv.java | 7 ++- .../com/fongmi/android/tv/db/AppDatabase.java | 2 +- .../android/tv/server/process/Local.java | 2 +- .../com/fongmi/android/tv/utils/FileUtil.java | 14 +++++- .../java/com/github/catvod/utils/Path.java | 8 ++++ 6 files changed, 54 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java b/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java index e57513428..5bef7c6dd 100644 --- a/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java +++ b/app/src/main/java/com/fongmi/android/tv/api/EpgParser.java @@ -9,6 +9,7 @@ import com.fongmi.android.tv.bean.Group; import com.fongmi.android.tv.bean.Live; import com.fongmi.android.tv.bean.Tv; import com.fongmi.android.tv.utils.Download; +import com.fongmi.android.tv.utils.FileUtil; import com.github.catvod.utils.Path; import com.github.catvod.utils.Trans; @@ -20,64 +21,68 @@ import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Map; import java.util.Set; public class EpgParser { - private static final SimpleDateFormat formatFull = new SimpleDateFormat("yyyyMMddHHmmss"); - private static final SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd"); - private static final SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm"); - public static void start(Live live) { try { - if (!live.getEpg().contains(".xml") || live.getEpg().contains("{")) return; - File file = Path.cache(Uri.parse(live.getEpg()).getLastPathSegment()); + if (!live.getEpg().endsWith(".xml") && !live.getEpg().endsWith(".gz")) return; + File file = Path.epg(Uri.parse(live.getEpg()).getLastPathSegment()); if (shouldDownload(file)) Download.create(live.getEpg(), file).start(); - readXml(live, Path.read(file)); + if (file.getName().endsWith(".gz")) readGzip(live, file); + else readXml(live, file); } catch (Exception e) { e.printStackTrace(); } } private static boolean shouldDownload(File file) { - return !file.exists() || !equalToday(file); + return !file.exists() || !isToday(file.lastModified()); + } + + private static boolean isToday(Date date) { + return isToday(date.getTime()); } - private static boolean equalToday(File file) { + private static boolean isToday(long millis) { Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(file.lastModified()); + calendar.setTimeInMillis(millis); return calendar.get(Calendar.DAY_OF_MONTH) == Calendar.getInstance().get(Calendar.DAY_OF_MONTH); } - private static Date parseDateTime(String text) throws Exception { - return formatFull.parse(text.substring(0, 14)); + private static void readGzip(Live live, File file) throws Exception { + File xml = Path.epg(file.getName().replace(".gz", "")); + if (!xml.exists()) FileUtil.extractGzip(file, xml); + readXml(live, xml); } - private static void readXml(Live live, String xml) throws Exception { + private static void readXml(Live live, File file) throws Exception { Set exist = new HashSet<>(); Map epgMap = new HashMap<>(); Map mapping = new HashMap<>(); + SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm", Locale.getDefault()); + SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); + SimpleDateFormat formatFull = new SimpleDateFormat("yyyyMMddHHmmss Z", Locale.getDefault()); String today = formatDate.format(new Date()); - Tv tv = new Persister().read(Tv.class, xml); + Tv tv = new Persister().read(Tv.class, Path.read(file)); for (Group group : live.getGroups()) for (Channel channel : group.getChannel()) exist.add(channel.getTvgName()); for (Tv.Channel channel : tv.getChannel()) mapping.put(channel.getId(), channel.getDisplayName()); for (Tv.Programme programme : tv.getProgramme()) { String key = mapping.get(programme.getChannel()); + Date startDate = formatFull.parse(programme.getStart()); + Date endDate = formatFull.parse(programme.getStop()); if (!exist.contains(key)) continue; - if (!programme.equals(today)) continue; + if (!isToday(startDate) && !isToday(endDate)) continue; if (!epgMap.containsKey(key)) epgMap.put(key, Epg.create(key, today)); - String title = programme.getTitle(); - String start = programme.getStart(); - String stop = programme.getStop(); - Date startDate = parseDateTime(start); - Date endDate = parseDateTime(stop); EpgData epgData = new EpgData(); + epgData.setTitle(Trans.s2t(programme.getTitle())); epgData.setStart(formatTime.format(startDate)); epgData.setEnd(formatTime.format(endDate)); epgData.setStartTime(startDate.getTime()); epgData.setEndTime(endDate.getTime()); - epgData.setTitle(Trans.s2t(title)); epgMap.get(key).getList().add(epgData); } for (Group group : live.getGroups()) { diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Tv.java b/app/src/main/java/com/fongmi/android/tv/bean/Tv.java index 2335e0046..0dbfa39f8 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Tv.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Tv.java @@ -63,6 +63,9 @@ public class Tv { @Element(name = "date", required = false) private String date; + @Element(name = "desc", required = false) + private String desc; + public String getStart() { return TextUtils.isEmpty(start) ? "" : start; } @@ -83,8 +86,8 @@ public class Tv { return TextUtils.isEmpty(date) ? "" : date; } - public boolean equals(String date) { - return getDate().isEmpty() || getDate().equals(date); + public String getDesc() { + return TextUtils.isEmpty(desc) ? "" : desc; } } } diff --git a/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java b/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java index 893899617..770fc0b91 100644 --- a/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java +++ b/app/src/main/java/com/fongmi/android/tv/db/AppDatabase.java @@ -75,7 +75,7 @@ public abstract class AppDatabase extends RoomDatabase { App.execute(() -> { File restore = Path.restore(); if (!restore.exists()) return; - FileUtil.unzip(file, restore); + FileUtil.extractZip(file, restore); File db = new File(restore, NAME); File wal = new File(restore, NAME + "-wal"); File shm = new File(restore, NAME + "-shm"); diff --git a/app/src/main/java/com/fongmi/android/tv/server/process/Local.java b/app/src/main/java/com/fongmi/android/tv/server/process/Local.java index 35c20f0fa..24ffd72f2 100644 --- a/app/src/main/java/com/fongmi/android/tv/server/process/Local.java +++ b/app/src/main/java/com/fongmi/android/tv/server/process/Local.java @@ -56,7 +56,7 @@ public class Local implements Process { for (String k : files.keySet()) { String fn = params.get(k); File temp = new File(files.get(k)); - if (fn.toLowerCase().endsWith(".zip")) FileUtil.unzip(temp, Path.root(path)); + if (fn.toLowerCase().endsWith(".zip")) FileUtil.extractZip(temp, Path.root(path)); else Path.copy(temp, Path.root(path, fn)); } return Nano.success(); diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java index 30d65036f..3a117cad7 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileUtil.java @@ -11,12 +11,15 @@ import com.fongmi.android.tv.App; import com.fongmi.android.tv.impl.Callback; import com.github.catvod.utils.Path; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.net.URLConnection; import java.text.DecimalFormat; import java.util.Enumeration; +import java.util.zip.GZIPInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @@ -63,8 +66,17 @@ public class FileUtil { in.close(); } } + public static void extractGzip(File target, File path) { + byte[] buffer = new byte[1024]; + try (GZIPInputStream is = new GZIPInputStream(new BufferedInputStream(new FileInputStream(target))); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(path))) { + int read; + while ((read = is.read(buffer)) != -1) os.write(buffer, 0, read); + } catch (Exception e) { + e.printStackTrace(); + } + } - public static void unzip(File target, File path) { + public static void extractZip(File target, File path) { try (ZipFile zip = new ZipFile(target)) { Enumeration entries = zip.entries(); while (entries.hasMoreElements()) { diff --git a/catvod/src/main/java/com/github/catvod/utils/Path.java b/catvod/src/main/java/com/github/catvod/utils/Path.java index 414da613a..908dbb5b5 100644 --- a/catvod/src/main/java/com/github/catvod/utils/Path.java +++ b/catvod/src/main/java/com/github/catvod/utils/Path.java @@ -89,6 +89,10 @@ public class Path { return mkdir(new File(cache() + File.separator + "exo")); } + public static File epg() { + return mkdir(new File(cache() + File.separator + "epg")); + } + public static File jpa() { return mkdir(new File(cache() + File.separator + "jpa")); } @@ -117,6 +121,10 @@ public class Path { return new File(files(), name); } + public static File epg(String name) { + return new File(epg(), name); + } + public static File js(String name) { return new File(js(), name); } From 344d100a09b7709203d974c569ba8dede7bbd88a Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 10 Jun 2024 19:43:41 +0800 Subject: [PATCH 4/5] Update FileChooser.java --- .../fongmi/android/tv/utils/FileChooser.java | 19 ++++++++++++++++--- .../tv/ui/fragment/SettingFragment.java | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/fongmi/android/tv/utils/FileChooser.java b/app/src/main/java/com/fongmi/android/tv/utils/FileChooser.java index f5db780ca..6a68c633c 100644 --- a/app/src/main/java/com/fongmi/android/tv/utils/FileChooser.java +++ b/app/src/main/java/com/fongmi/android/tv/utils/FileChooser.java @@ -53,21 +53,30 @@ public class FileChooser { show("*/*"); } + public void show(Uri uri) { + show(uri, "*/*"); + } + public void show(String mimeType) { - show(mimeType, new String[]{"*/*"}, REQUEST_PICK_FILE); + show(mimeType, new String[]{"*/*"}, null, REQUEST_PICK_FILE); } public void show(String[] mimeTypes) { - show("*/*", mimeTypes, REQUEST_PICK_FILE); + show("*/*", mimeTypes, null, REQUEST_PICK_FILE); + } + + public void show(Uri uri, String mimeType) { + show(mimeType, new String[]{"*/*"}, uri, REQUEST_PICK_FILE); } - public void show(String mimeType, String[] mimeTypes, int code) { + public void show(String mimeType, String[] mimeTypes, Uri uri, int code) { Intent intent = new Intent(Util.isTvBox() ? Intent.ACTION_GET_CONTENT : Intent.ACTION_OPEN_DOCUMENT); intent.setType(mimeType); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false); intent.putExtra("android.content.extra.SHOW_ADVANCED", true); + if (uri != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri); if (intent.resolveActivity(App.get().getPackageManager()) == null) return; if (fragment != null) fragment.startActivityForResult(Intent.createChooser(intent, ""), code); } @@ -192,6 +201,10 @@ public class FileChooser { } } + public static Uri getUri(String path) { + return Uri.parse("content://com.android.externalstorage.documents/document/primary:" + path); + } + private static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java index d7f93bf87..63c832845 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java @@ -353,7 +353,7 @@ public class SettingFragment extends BaseFragment implements ConfigCallback, Sit } private void onRestore(View view) { - FileChooser.from(this).type(FileChooser.TYPE_RESTORE).show(); + FileChooser.from(this).type(FileChooser.TYPE_RESTORE).show(FileChooser.getUri("TV")); } private void onTransmit(View view) { From ebe288d1d9d8b8e4fc6c9ff8ab490f36adbd4c2b Mon Sep 17 00:00:00 2001 From: okjack Date: Mon, 10 Jun 2024 19:46:39 +0800 Subject: [PATCH 5/5] build.gradle --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index c8e43568f..b24d49a95 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,7 @@ android { //noinspection ExpiredTargetSdkVersion targetSdk 28 versionCode 237 - versionName "0607" + versionName "0611" javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]