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 2d8942f84..aa62875f3 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 @@ -429,7 +429,7 @@ public class CastActivity extends BaseActivity implements CustomKeyDownCast.List @Override public void seek(long time) { - App.post(() -> mPlayers.seekTo(time, true)); + App.post(() -> mPlayers.seekTo(time)); } @Override 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 f10914023..1067847b4 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 @@ -591,7 +591,7 @@ public class LiveActivity extends BaseActivity implements GroupPresenter.OnClick if (mChannel == null) return; LiveConfig.get().setKeep(mChannel); mViewModel.getUrl(mChannel); - mPlayers.clean(); + mPlayers.clear(); showProgress(); } 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 155f104df..1f6cd20b7 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 @@ -476,7 +476,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mBinding.widget.title.setText(getString(R.string.detail_title, mBinding.name.getText(), episode.getName())); mViewModel.playerContent(getKey(), flag.getFlag(), episode.getUrl()); updateHistory(episode, replay); - mPlayers.clean(); + mPlayers.clear(); showProgress(); setMetadata(); hideCenter(); @@ -1090,6 +1090,7 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List mHistory.setVodRemarks(item.getName()); mHistory.setVodFlag(getFlag().getFlag()); mHistory.setCreateTime(System.currentTimeMillis()); + mPlayers.setPosition(Math.max(mHistory.getOpening(), mHistory.getPosition())); } private void checkKeep() { @@ -1153,7 +1154,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List if (isBackground()) return; switch (event.getState()) { case 0: - setPosition(); setInitTrack(true); setTrackVisible(false); mClock.setCallback(this); @@ -1180,10 +1180,6 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List } } - private void setPosition() { - mPlayers.seekTo(Math.max(mHistory.getOpening(), mHistory.getPosition()), false); - } - private void checkEnded() { if (mBinding.control.loop.isActivated()) { onReset(true); diff --git a/app/src/main/java/com/fongmi/android/tv/bean/Result.java b/app/src/main/java/com/fongmi/android/tv/bean/Result.java index a6c30ffa1..3e2190ee0 100644 --- a/app/src/main/java/com/fongmi/android/tv/bean/Result.java +++ b/app/src/main/java/com/fongmi/android/tv/bean/Result.java @@ -49,10 +49,12 @@ public class Result implements Parcelable { @JsonAdapter(UrlAdapter.class) private Url url; - @JsonAdapter(MsgAdapter.class) @SerializedName("msg") + @JsonAdapter(MsgAdapter.class) private String msg; + @SerializedName("subs") + private List subs; @SerializedName("header") private JsonElement header; @SerializedName("playUrl") @@ -69,8 +71,6 @@ public class Result implements Parcelable { private String click; @SerializedName("key") private String key; - @SerializedName("subs") - private List subs; @SerializedName("pagecount") private Integer pagecount; @SerializedName("parse") @@ -168,6 +168,30 @@ public class Result implements Parcelable { return filters == null ? new LinkedHashMap<>() : filters; } + public Url getUrl() { + return url == null ? Url.create() : url; + } + + public void setUrl(Url url) { + this.url = url; + } + + public void setUrl(String url) { + this.url = getUrl().replace(url); + } + + public String getMsg() { + return TextUtils.isEmpty(msg) || getCode() != 0 ? "" : msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public List getSubs() { + return subs == null ? new ArrayList<>() : subs; + } + public JsonElement getHeader() { return header; } @@ -188,20 +212,12 @@ public class Result implements Parcelable { return TextUtils.isEmpty(jxFrom) ? "" : jxFrom; } - public Integer getParse() { - return getParse(0); - } - - public Integer getParse(Integer def) { - return parse == null ? def : parse; - } - - public void setParse(Integer parse) { - this.parse = parse; + public String getFlag() { + return TextUtils.isEmpty(flag) ? "" : flag; } - public Integer getJx() { - return jx == null ? 0 : jx; + public void setFlag(String flag) { + this.flag = flag; } public String getDanmaku() { @@ -224,26 +240,6 @@ public class Result implements Parcelable { this.click = click; } - public String getFlag() { - return TextUtils.isEmpty(flag) ? "" : flag; - } - - public void setFlag(String flag) { - this.flag = flag; - } - - public Url getUrl() { - return url == null ? Url.create() : url; - } - - public void setUrl(Url url) { - this.url = url; - } - - public void setUrl(String url) { - this.url = getUrl().replace(url); - } - public String getKey() { return TextUtils.isEmpty(key) ? "" : key; } @@ -252,24 +248,28 @@ public class Result implements Parcelable { this.key = key; } - public List getSubs() { - return subs == null ? new ArrayList<>() : subs; - } - public Integer getPageCount() { return pagecount == null ? 0 : pagecount; } - public Integer getCode() { - return code == null ? 0 : code; + public Integer getParse(Integer def) { + return parse == null ? def : parse; } - public String getMsg() { - return TextUtils.isEmpty(msg) || getCode() != 0 ? "" : msg; + public Integer getParse() { + return getParse(0); } - public void setMsg(String msg) { - this.msg = msg; + public void setParse(Integer parse) { + this.parse = parse; + } + + public Integer getCode() { + return code == null ? 0 : code; + } + + public Integer getJx() { + return jx == null ? 0 : jx; } public boolean hasMsg() { diff --git a/app/src/main/java/com/fongmi/android/tv/impl/SessionCallback.java b/app/src/main/java/com/fongmi/android/tv/impl/SessionCallback.java index 9c824c360..8dc9bc911 100644 --- a/app/src/main/java/com/fongmi/android/tv/impl/SessionCallback.java +++ b/app/src/main/java/com/fongmi/android/tv/impl/SessionCallback.java @@ -19,7 +19,7 @@ public class SessionCallback extends MediaSessionCompat.Callback { @Override public void onSeekTo(long pos) { - players.seekTo(pos, true); + players.seekTo(pos); } @Override 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 6f308a7fe..c9fd7a901 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 @@ -14,7 +14,6 @@ import androidx.annotation.NonNull; import androidx.media3.common.AudioAttributes; import androidx.media3.common.PlaybackException; import androidx.media3.common.Player; -import androidx.media3.common.util.Log; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.analytics.AnalyticsListener; import androidx.media3.exoplayer.util.EventLogger; @@ -79,11 +78,13 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic private Runnable runnable; private String url; private Sub sub; + + private long position; + private float speed; private int decode; private int player; private int error; private int retry; - private float speed; public static boolean isExo(int type) { return type == EXO; @@ -167,29 +168,10 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic return headers == null ? new HashMap<>() : checkUa(headers); } - public String[] getHeaderArray() { - List list = new ArrayList<>(); - for (Map.Entry entry : getHeaders().entrySet()) list.addAll(Arrays.asList(entry.getKey(), entry.getValue())); - return list.toArray(new String[0]); - } - public String getUrl() { return url; } - public Uri getUri() { - return getUrl().startsWith("file://") || getUrl().startsWith("/") ? FileUtil.getShareUri(getUrl()) : Uri.parse(getUrl()); - } - - public void clean() { - this.headers = null; - this.url = null; - } - - public boolean isEmpty() { - return TextUtils.isEmpty(getUrl()); - } - public MediaSessionCompat getSession() { return session; } @@ -215,6 +197,10 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic this.decode = decode; } + public void setPosition(long position) { + this.position = position; + } + public void reset() { removeTimeoutCheck(); this.error = 0; @@ -222,6 +208,11 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic stopParse(); } + public void clear() { + this.headers = null; + this.url = null; + } + public int addRetry() { ++retry; return retry; @@ -255,6 +246,16 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic return 0; } + private boolean haveDanmu() { + return danmuView != null && danmuView.isPrepared(); + } + + public boolean haveTrack(int type) { + if (isExo() && exoPlayer != null) return ExoUtil.haveTrack(exoPlayer.getCurrentTracks(), type); + if (isIjk() && ijkPlayer != null) return ijkPlayer.haveTrack(type); + return false; + } + public boolean isPlaying() { return isExo() ? exoPlayer != null && exoPlayer.isPlaying() : ijkPlayer != null && ijkPlayer.isPlaying(); } @@ -265,6 +266,18 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic return false; } + public boolean isRelease() { + return exoPlayer == null || ijkPlayer == null; + } + + public boolean isEmpty() { + return TextUtils.isEmpty(getUrl()); + } + + public boolean isVod() { + return getDuration() > 5 * 60 * 1000; + } + public boolean isPortrait() { return getVideoHeight() > getVideoWidth(); } @@ -343,12 +356,11 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic } public void seekTo(int time) { - seekTo(getPosition() + time, true); + seekTo(getPosition() + time); } - public void seekTo(long time, boolean force) { - if (time == 0 && !force) return; - if (hasDanmu()) danmuView.seekTo(time); + public void seekTo(long time) { + if (haveDanmu()) danmuView.seekTo(time); if (isExo() && exoPlayer != null) exoPlayer.seekTo(time); if (isIjk() && ijkPlayer != null) ijkPlayer.seekTo(time); } @@ -358,14 +370,14 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic session.setActive(true); if (isExo()) playExo(); if (isIjk()) playIjk(); - if (hasDanmu()) danmuView.resume(); + if (haveDanmu()) danmuView.resume(); setPlaybackState(PlaybackStateCompat.STATE_PLAYING); } public void pause() { if (isExo()) pauseExo(); if (isIjk()) pauseIjk(); - if (hasDanmu()) danmuView.pause(); + if (haveDanmu()) danmuView.pause(); setPlaybackState(PlaybackStateCompat.STATE_PAUSED); } @@ -374,7 +386,7 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic if (isExo()) stopExo(); if (isIjk()) stopIjk(); session.setActive(false); - if (hasDanmu()) danmuView.stop(); + if (haveDanmu()) danmuView.stop(); setPlaybackState(PlaybackStateCompat.STATE_STOPPED); } @@ -383,27 +395,7 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic session.release(); if (isExo()) releaseExo(); if (isIjk()) releaseIjk(); - if (hasDanmu()) danmuView.release(); - } - - public boolean isRelease() { - return exoPlayer == null || ijkPlayer == null; - } - - public boolean isVod() { - return getDuration() > 5 * 60 * 1000; - } - - public void setTrack(List tracks) { - for (Track track : tracks) setTrack(track); - } - - public boolean haveTrack(int type) { - if (isExo()) { - return ExoUtil.haveTrack(exoPlayer.getCurrentTracks(), type); - } else { - return ijkPlayer.haveTrack(type); - } + if (haveDanmu()) danmuView.release(); } public void start(Channel channel, int timeout) { @@ -498,8 +490,8 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic private void setMediaSource(Result result, int timeout) { Logger.t(TAG).d(error + "," + result.getRealUrl()); - if (isIjk() && ijkPlayer != null) ijkPlayer.setMediaSource(IjkUtil.getSource(result)); - if (isExo() && exoPlayer != null) exoPlayer.setMediaSource(ExoUtil.getSource(result, sub, error)); + if (isIjk() && ijkPlayer != null) ijkPlayer.setMediaSource(IjkUtil.getSource(result), position); + if (isExo() && exoPlayer != null) exoPlayer.setMediaSource(ExoUtil.getSource(result, sub, error), position); if (isExo() && exoPlayer != null) exoPlayer.prepare(); setTimeoutCheck(result.getHeaders(), result.getRealUrl(), timeout); } @@ -514,8 +506,8 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic private void setMediaSource(Map headers, String url) { Logger.t(TAG).d(error + "," + url); - if (isIjk() && ijkPlayer != null) ijkPlayer.setMediaSource(IjkUtil.getSource(headers, url)); - if (isExo() && exoPlayer != null) exoPlayer.setMediaSource(ExoUtil.getSource(headers, url, sub, error)); + if (isIjk() && ijkPlayer != null) ijkPlayer.setMediaSource(IjkUtil.getSource(headers, url), position); + if (isExo() && exoPlayer != null) exoPlayer.setMediaSource(ExoUtil.getSource(headers, url, sub, error), position); if (isExo() && exoPlayer != null) exoPlayer.prepare(); setTimeoutCheck(headers, url, Constant.TIMEOUT_PLAY); } @@ -531,6 +523,10 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic App.removeCallbacks(runnable); } + public void setTrack(List tracks) { + for (Track track : tracks) setTrack(track); + } + private void setTrack(Track item) { if (item.isExo(player)) setTrackExo(item); if (item.isIjk(player)) setTrackIjk(item); @@ -557,10 +553,6 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic session.setPlaybackState(new PlaybackStateCompat.Builder().setActions(actions).setState(state, getPosition(), getSpeed()).build()); } - private boolean hasDanmu() { - return danmuView != null && danmuView.isPrepared(); - } - private boolean isIllegal(String url) { Uri uri = UrlUtil.uri(url); String host = UrlUtil.host(uri); @@ -576,13 +568,23 @@ public class Players implements Player.Listener, IMediaPlayer.Listener, Analytic return headers; } + public Uri getUri() { + return getUrl().startsWith("file://") || getUrl().startsWith("/") ? FileUtil.getShareUri(getUrl()) : Uri.parse(getUrl()); + } + + public String[] getHeaderArray() { + List list = new ArrayList<>(); + for (Map.Entry entry : getHeaders().entrySet()) list.addAll(Arrays.asList(entry.getKey(), entry.getValue())); + return list.toArray(new String[0]); + } + public void checkData(Intent data) { try { if (data == null || data.getExtras() == null) return; int position = data.getExtras().getInt("position", 0); String endBy = data.getExtras().getString("end_by", ""); if (endBy.equals("playback_completion")) ActionEvent.next(); - if (endBy.equals("user")) seekTo(position, true); + if (endBy.equals("user")) seekTo(position); } catch (Exception e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java index f4f2ca3ef..af8bacc2b 100644 --- a/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java +++ b/app/src/main/java/com/fongmi/android/tv/ui/custom/CustomSeekView.java @@ -66,7 +66,7 @@ public class CustomSeekView extends FrameLayout implements TimeBar.OnScrubListen } private void seekToTimeBarPosition(long positionMs) { - player.seekTo(positionMs, true); + player.seekTo(positionMs); updateProgress(); } 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 e372b4eac..1b51295ba 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 @@ -640,7 +640,7 @@ public class LiveActivity extends BaseActivity implements CustomKeyDownLive.List if (mChannel == null) return; LiveConfig.get().setKeep(mChannel); mViewModel.getUrl(mChannel); - mPlayers.clean(); + mPlayers.clear(); showProgress(); } 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 32b6eacaa..8858fe0f7 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 @@ -568,7 +568,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo mViewModel.playerContent(getKey(), flag.getFlag(), episode.getUrl()); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); updateHistory(episode, replay); - mPlayers.clean(); + mPlayers.clear(); showProgress(); setMetadata(); } @@ -1094,6 +1094,7 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo mHistory.setVodRemarks(item.getName()); mHistory.setVodFlag(getFlag().getFlag()); mHistory.setCreateTime(System.currentTimeMillis()); + mPlayers.setPosition(Math.max(mHistory.getOpening(), mHistory.getPosition())); } private void checkPlayImg(boolean playing) { @@ -1181,7 +1182,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo if (isRedirect()) return; switch (event.getState()) { case 0: - setPosition(); setInitTrack(true); setTrackVisible(false); mClock.setCallback(this); @@ -1211,10 +1211,6 @@ public class VideoActivity extends BaseActivity implements Clock.Callback, Custo } } - private void setPosition() { - mPlayers.seekTo(Math.max(mHistory.getOpening(), mHistory.getPosition()), false); - } - private void checkRotate() { if (isFullscreen() && !isRotate() && mPlayers.isPortrait()) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT); diff --git a/ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java b/ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java index eb671aade..7df9778be 100644 --- a/ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java +++ b/ijkplayer/src/main/java/tv/danmaku/ijk/media/player/ui/IjkVideoView.java @@ -63,7 +63,7 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl private int mCurrentRender; private int mCurrentPlayer; private int mCurrentAspectRatio; - private int mStartPosition; + private long mStartPosition; private int mCurrentBufferPercentage; private long mCurrentBufferPosition; @@ -193,7 +193,12 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl } public void setMediaSource(MediaSource source) { + setMediaSource(source, 0); + } + + public void setMediaSource(MediaSource source, long position) { setVideoURI(source.getUri(), source.getHeaders()); + mStartPosition = position; } private void setVideoURI(Uri uri, Map headers) { @@ -283,15 +288,12 @@ public class IjkVideoView extends FrameLayout implements MediaController.MediaPl @Override public void seekTo(int positionMs) { - if (!isInPlaybackState()) return; - onInfo(mPlayer, IMediaPlayer.MEDIA_INFO_BUFFERING_START, 0); - mPlayer.seekTo(positionMs); - mStartPosition = 0; + seekTo((long) positionMs); } public void seekTo(long positionMs) { - mStartPosition = (int) positionMs; - seekTo(mStartPosition); + onInfo(mPlayer, IMediaPlayer.MEDIA_INFO_BUFFERING_START, 0); + mPlayer.seekTo(positionMs); } public void setSpeed(float speed) {