From fb4a2171948a914a49df5f7eec1cc0771dc44fa1 Mon Sep 17 00:00:00 2001 From: FongMi Date: Fri, 15 Sep 2023 16:38:54 +0800 Subject: [PATCH] Fix quality bug --- .../android/tv/ui/activity/VideoActivity.java | 20 +++--- .../java/com/fongmi/android/tv/bean/Url.java | 4 +- .../com/fongmi/android/tv/player/Players.java | 64 +++++++++++++------ .../android/tv/ui/activity/VideoActivity.java | 14 ++-- 4 files changed, 66 insertions(+), 36 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 f297fbe72..7a1f40216 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 @@ -449,14 +449,10 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List result.getUrl().set(mQualityAdapter.getPosition()); setUseParse(ApiConfig.hasParse() && ((result.getPlayUrl().isEmpty() && ApiConfig.get().getFlags().contains(result.getFlag())) || result.getJx() == 1)); mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1); - mFlagPresenter.setNextFocusDown(result.getUrl().isOnly() ? R.id.episode : R.id.quality); - mEpisodePresenter.setNextFocusUp(result.getUrl().isOnly() ? R.id.flag : R.id.quality); - mBinding.quality.setVisibility(result.getUrl().isOnly() ? View.GONE : View.VISIBLE); mBinding.control.parse.setVisibility(isUseParse() ? View.VISIBLE : View.GONE); - notifyItemChanged(mBinding.episode, mEpisodeAdapter); - notifyItemChanged(mBinding.flag, mFlagAdapter); - mQualityAdapter.addAll(result); + setQualityVisible(result.getUrl().isMulti()); checkDanmu(result.getDanmaku()); + mQualityAdapter.addAll(result); } private void checkDanmu(String danmu) { @@ -523,10 +519,9 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List if (mFlagAdapter.size() == 0 || item.isActivated()) return; for (int i = 0; i < mFlagAdapter.size(); i++) ((Flag) mFlagAdapter.get(i)).setActivated(item); mBinding.flag.setSelectedPosition(mFlagAdapter.indexOf(item)); - mFlagPresenter.setNextFocusDown(R.id.episode); notifyItemChanged(mBinding.flag, mFlagAdapter); - mBinding.quality.setVisibility(View.GONE); setEpisodeAdapter(item.getEpisodes()); + setQualityVisible(false); seamless(item, force); } @@ -540,6 +535,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List private void seamless(Flag flag, boolean force) { if (Setting.getFlag() == 1 && (mHistory.isNew() || !force)) return; Episode episode = flag.find(mHistory.getVodRemarks(), getMark().isEmpty()); + setQualityVisible(episode != null && episode.isActivated() && mQualityAdapter.getItemCount() > 0); if (episode == null || episode.isActivated()) return; mHistory.setVodRemarks(episode.getName()); setEpisodeActivated(episode); @@ -557,6 +553,14 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List onRefresh(); } + private void setQualityVisible(boolean visible) { + mFlagPresenter.setNextFocusDown(visible ? R.id.quality : R.id.episode); + mEpisodePresenter.setNextFocusUp(visible ? R.id.quality : R.id.flag); + mBinding.quality.setVisibility(visible?View.VISIBLE:View.GONE); + notifyItemChanged(mBinding.episode, mEpisodeAdapter); + notifyItemChanged(mBinding.flag, mFlagAdapter); + } + private void setQualityActivated(Result result) { mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1); } diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Url.java b/app/src/main/java/com/fongmi/android/tv/bean/Url.java index aa289d3a1..448ff3e1b 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Url.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Url.java @@ -58,7 +58,7 @@ public class Url { return getValues().isEmpty() || TextUtils.isEmpty(v()); } - public boolean isOnly() { - return getValues().size() <= 1; + public boolean isMulti() { + return getValues().size() > 1; } } 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 496018ee4..8b346b4f9 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 @@ -1,8 +1,6 @@ package com.fongmi.android.tv.player; import android.app.Activity; -import android.app.PendingIntent; -import android.content.Intent; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; @@ -23,13 +21,11 @@ import com.fongmi.android.tv.Setting; import com.fongmi.android.tv.bean.Channel; import com.fongmi.android.tv.bean.Result; import com.fongmi.android.tv.bean.Track; -import com.fongmi.android.tv.event.ActionEvent; import com.fongmi.android.tv.event.ErrorEvent; import com.fongmi.android.tv.event.PlayerEvent; import com.fongmi.android.tv.impl.ParseCallback; import com.fongmi.android.tv.utils.Notify; import com.fongmi.android.tv.utils.ResUtil; -import com.fongmi.android.tv.utils.Utils; import com.github.catvod.crawler.SpiderDebug; import java.util.Formatter; @@ -37,10 +33,12 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import master.flame.danmaku.controller.DrawHandler; +import master.flame.danmaku.ui.widget.DanmakuView; import tv.danmaku.ijk.media.player.IMediaPlayer; import tv.danmaku.ijk.media.player.ui.IjkVideoView; -public class Players implements Player.Listener, IMediaPlayer.Listener, AnalyticsListener, ParseCallback { +public class Players implements Player.Listener, IMediaPlayer.Listener, AnalyticsListener, ParseCallback, DrawHandler.Callback { public static final int SYS = 0; public static final int IJK = 1; @@ -51,6 +49,7 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic private MediaSessionCompat session; private IjkVideoView ijkPlayer; + private DanmakuView danmuView; private StringBuilder builder; private Formatter formatter; private ExoPlayer exoPlayer; @@ -90,13 +89,6 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic private void createSession(Activity activity) { session = new MediaSessionCompat(activity, "TV"); - session.setSessionActivity(PendingIntent.getActivity(App.get(), 99, new Intent(App.get(), activity.getClass()), Utils.getPendingFlag())); - session.setCallback(new MediaSessionCompat.Callback() { - @Override - public void onSeekTo(long pos) { - seekTo(pos, true); - } - }); } public void set(PlayerView exo, IjkVideoView ijk) { @@ -121,6 +113,10 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic ijkPlayer.setPlayer(player); } + public void setDanmuView(DanmakuView view) { + danmuView = view.setCallback(this); + } + public ExoPlayer exo() { return exoPlayer; } @@ -134,7 +130,7 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic } public void setMetadata(MediaMetadataCompat metadata) { - ActionEvent.update(); + session.setMetadata(metadata); } public int getPlayer() { @@ -198,6 +194,12 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic return isExo() ? exoPlayer != null && exoPlayer.isPlaying() : ijkPlayer != null && ijkPlayer.isPlaying(); } + public boolean isEnd() { + if (isExo() && exoPlayer != null) return exoPlayer.getPlaybackState() == Player.STATE_ENDED; + if (isIjk() && ijkPlayer != null) return ijkPlayer.getPlaybackState() == IjkVideoView.STATE_ENDED; + return false; + } + public boolean isPortrait() { return getVideoHeight() > getVideoWidth(); } @@ -219,8 +221,9 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic } public String setSpeed(float speed) { - exoPlayer.setPlaybackSpeed(speed); - ijkPlayer.setSpeed(speed); + if (exoPlayer != null) exoPlayer.setPlaybackSpeed(speed); + if (ijkPlayer != null) ijkPlayer.setSpeed(speed); + if (hasDanmu()) danmuView.setSpeed(speed); return getSpeedText(); } @@ -276,34 +279,38 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic } public void seekTo(int time) { - if (isExo() && exoPlayer != null) exoPlayer.seekTo(getPosition() + time); - if (isIjk() && ijkPlayer != null) ijkPlayer.seekTo(getPosition() + time); + seekTo(getPosition() + time, true); } public void seekTo(long time, boolean force) { if (time == 0 && !force) return; + if (hasDanmu()) danmuView.seekTo(time); if (isExo() && exoPlayer != null) exoPlayer.seekTo(time); if (isIjk() && ijkPlayer != null) ijkPlayer.seekTo(time); } public void play() { + if (isEnd()) return; session.setActive(true); if (isExo()) exoPlayer.play(); - else if (isIjk()) ijkPlayer.start(); + if (isIjk()) ijkPlayer.start(); + if (hasDanmu()) danmuView.resume(); setPlaybackState(PlaybackStateCompat.STATE_PLAYING); } public void pause() { if (isExo()) pauseExo(); - else if (isIjk()) pauseIjk(); + if (isIjk()) pauseIjk(); + if (hasDanmu()) danmuView.pause(); setPlaybackState(PlaybackStateCompat.STATE_PAUSED); } public void stop() { reset(); if (isExo()) stopExo(); - else if (isIjk()) stopIjk(); + if (isIjk()) stopIjk(); session.setActive(false); + if (hasDanmu()) danmuView.stop(); setPlaybackState(PlaybackStateCompat.STATE_STOPPED); } @@ -311,7 +318,8 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic stopParse(); session.release(); if (isExo()) releaseExo(); - else if (isIjk()) releaseIjk(); + if (isIjk()) releaseIjk(); + if (hasDanmu()) danmuView.release(); } public boolean isRelease() { @@ -458,6 +466,10 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic session.setPlaybackState(new PlaybackStateCompat.Builder().setState(state, getPosition(), getSpeed()).build()); } + private boolean hasDanmu() { + return danmuView != null && danmuView.isPrepared(); + } + @Override public void onParseSuccess(Map headers, String url, String from) { setMediaSource(headers, url); @@ -472,6 +484,7 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic @Override public void onEvents(@NonNull Player player, @NonNull Player.Events events) { + if (!events.containsAny(EVENT_PLAYBACK_STATE_CHANGED, EVENT_PLAY_WHEN_READY_CHANGED, EVENT_IS_PLAYING_CHANGED, EVENT_TIMELINE_CHANGED, EVENT_PLAYBACK_PARAMETERS_CHANGED, EVENT_POSITION_DISCONTINUITY, EVENT_REPEAT_MODE_CHANGED, EVENT_SHUFFLE_MODE_ENABLED_CHANGED, EVENT_MEDIA_METADATA_CHANGED)) return; setPlaybackState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED); } @@ -531,4 +544,13 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic public void onCompletion(IMediaPlayer mp) { PlayerEvent.state(Player.STATE_ENDED); } + + @Override + public void prepared() { + App.post(() -> { + if (danmuView == null) return; + if (!Setting.isDanmu()) danmuView.hide(); + if (isPlaying() && danmuView.isPrepared()) danmuView.start(getPosition()); + }); + } } 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 58b88f92c..73b5d2d87 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 @@ -523,11 +523,10 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo if (mControlDialog != null && mControlDialog.isVisible()) mControlDialog.setParseVisible(isUseParse()); mBinding.control.parse.setVisibility(isFullscreen() && isUseParse() ? View.VISIBLE : View.GONE); mPlayers.start(result, isUseParse(), getSite().isChangeable() ? getSite().getTimeout() : -1); - mBinding.qualityText.setVisibility(result.getUrl().isOnly() ? View.GONE : View.VISIBLE); - mBinding.quality.setVisibility(result.getUrl().isOnly() ? View.GONE : View.VISIBLE); + setQualityVisible(result.getUrl().isMulti()); mBinding.swipeLayout.setRefreshing(false); - mQualityAdapter.addAll(result); checkDanmu(result.getDanmaku()); + mQualityAdapter.addAll(result); } private void checkDanmu(String danmu) { @@ -541,9 +540,8 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo if (item.isActivated()) return; mFlagAdapter.setActivated(item); mBinding.flag.scrollToPosition(mFlagAdapter.getPosition()); - mBinding.qualityText.setVisibility(View.GONE); - mBinding.quality.setVisibility(View.GONE); setEpisodeAdapter(item.getEpisodes()); + setQualityVisible(false); seamless(item, force); } @@ -592,12 +590,18 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo private void seamless(Flag flag, boolean force) { if (Setting.getFlag() == 1 && (mHistory.isNew() || !force)) return; Episode episode = flag.find(mHistory.getVodRemarks(), getMark().isEmpty()); + setQualityVisible(episode != null && episode.isActivated() && mQualityAdapter.getItemCount() > 0); if (episode == null || episode.isActivated()) return; mHistory.setVodRemarks(episode.getName()); onItemClick(episode); hidePreview(); } + private void setQualityVisible(boolean visible) { + mBinding.qualityText.setVisibility(visible ? View.VISIBLE : View.GONE); + mBinding.quality.setVisibility(visible ? View.VISIBLE : View.GONE); + } + private void reverseEpisode(boolean scroll) { mFlagAdapter.reverse(); setEpisodeAdapter(getFlag().getEpisodes());