Skip to content

Commit 668198c

Browse files
committed
Revert "Use Exo playlist for seamless switching demo"
This reverts commit db2a397.
1 parent db2a397 commit 668198c

9 files changed

Lines changed: 94 additions & 212 deletions

File tree

app/src/main/java/com/example/gsyvideoplayer/MainActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public void onClick(View view) {
182182
JumpUtils.gotoFilter(this);
183183
break;
184184
case R.id.open_btn_pick:
185-
//Exo playlist 无缝切换
185+
//无缝切换
186186
JumpUtils.goToVideoPickPlayer(this, binding.openBtnPick);
187187
break;
188188
case R.id.open_btn_auto:

app/src/main/java/com/example/gsyvideoplayer/exo/DetailExoListPlayer.java

Lines changed: 7 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import android.view.View;
88
import android.widget.ImageView;
9-
import android.widget.Toast;
109

1110
import com.example.gsyvideoplayer.R;
1211
import com.example.gsyvideoplayer.databinding.ActivityDeatilExoListPlayerBinding;
@@ -50,10 +49,9 @@ protected void onCreate(Bundle savedInstanceState) {
5049

5150
List<GSYVideoModel> urls = new ArrayList<>();
5251

53-
String rawPrefix = "android.resource://" + getPackageName() + "/";
54-
urls.add(new GSYVideoModel(rawPrefix + R.raw.test, "本地片段 1"));
55-
urls.add(new GSYVideoModel(rawPrefix + R.raw.test1, "本地片段 2"));
56-
urls.add(new GSYVideoModel(rawPrefix + R.raw.test4, "本地片段 3"));
52+
urls.add(new GSYVideoModel("https://flipfit-cdn.akamaized.net/flip_hls/6656423247ffe600199e8363-15125d/video_h1.m3u8", "标题1"));
53+
urls.add(new GSYVideoModel("https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8", "标题3"));
54+
urls.add(new GSYVideoModel("https://www.w3schools.com/html/mov_bbb.mp4", "标题2"));
5755
//binding.detailPlayer.setUp(urls, 1);
5856
binding.detailPlayer.setUp(urls, 0);
5957

@@ -90,32 +88,13 @@ public void onClick(View view, boolean lock) {
9088
}
9189
});
9290

93-
binding.previous.setOnClickListener(new View.OnClickListener() {
94-
@Override
95-
public void onClick(View v) {
96-
if (GSYExoVideoManager.instance().hasPrevious()) {
97-
GSYExoVideoManager.instance().previous();
98-
getCurPlay().onPlaylistSeek();
99-
updatePlaylistInfoSoon();
100-
} else {
101-
Toast.makeText(DetailExoListPlayer.this, "已经是第一集", Toast.LENGTH_SHORT).show();
102-
}
103-
}
104-
});
105-
10691
binding.next.setOnClickListener(new View.OnClickListener() {
10792
@Override
10893
public void onClick(View v) {
109-
if (GSYExoVideoManager.instance().hasNext()) {
110-
GSYExoVideoManager.instance().next();
111-
getCurPlay().onPlaylistSeek();
112-
updatePlaylistInfoSoon();
113-
} else {
114-
Toast.makeText(DetailExoListPlayer.this, "已经是最后一集", Toast.LENGTH_SHORT).show();
115-
}
94+
GSYExoVideoManager.instance().next();
95+
((GSYExo2PlayerView) binding.detailPlayer.getCurrentPlayer()).nextUI();
11696
}
11797
});
118-
updatePlaylistInfo();
11998

12099
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
121100
@Override
@@ -172,46 +151,19 @@ public void onEnterFullscreen(String url, Object... objects) {
172151
gsyVideoPlayer.getBackButton().setVisibility(View.GONE);
173152
}
174153

175-
@Override
176-
public void onPrepared(String url, Object... objects) {
177-
super.onPrepared(url, objects);
178-
updatePlaylistInfo();
179-
}
180-
181154

182155
private void resolveNormalVideoUI() {
183156
//增加title
184157
binding.detailPlayer.getTitleTextView().setVisibility(View.VISIBLE);
185158
binding.detailPlayer.getBackButton().setVisibility(View.VISIBLE);
186159
}
187160

188-
private GSYExo2PlayerView getCurPlay() {
161+
private GSYVideoPlayer getCurPlay() {
189162
if (binding.detailPlayer.getFullWindowPlayer() != null) {
190-
return (GSYExo2PlayerView) binding.detailPlayer.getFullWindowPlayer();
163+
return binding.detailPlayer.getFullWindowPlayer();
191164
}
192165
return binding.detailPlayer;
193166
}
194167

195-
private void updatePlaylistInfo() {
196-
GSYExo2PlayerView player = getCurPlay();
197-
int count = player.getMediaItemCount();
198-
int position = player.getPlayPosition();
199-
if (count <= 0) {
200-
binding.playlistInfo.setText("");
201-
return;
202-
}
203-
binding.playlistInfo.setText("当前:" + (position + 1) + "/" + count + " " + player.getCurrentMediaTitle());
204-
}
205-
206-
private void updatePlaylistInfoSoon() {
207-
updatePlaylistInfo();
208-
binding.detailPlayer.postDelayed(new Runnable() {
209-
@Override
210-
public void run() {
211-
updatePlaylistInfo();
212-
}
213-
}, 300);
214-
}
215-
216168

217169
}

app/src/main/java/com/example/gsyvideoplayer/exo/GSYExo2MediaPlayer.java

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@
66
import android.os.Looper;
77

88
import androidx.media3.common.C;
9-
import androidx.media3.common.MediaItem;
109
import androidx.media3.common.Player;
10+
import androidx.media3.common.Timeline;
1111
import androidx.media3.exoplayer.DefaultLoadControl;
1212
import androidx.media3.exoplayer.DefaultRenderersFactory;
1313
import androidx.media3.exoplayer.ExoPlayer;
14+
import androidx.media3.exoplayer.source.ConcatenatingMediaSource;
15+
import androidx.media3.exoplayer.source.ConcatenatingMediaSource2;
1416
import androidx.media3.exoplayer.source.MediaSource;
1517
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
1618

1719

1820
import java.io.FileDescriptor;
19-
import java.util.ArrayList;
2021
import java.util.List;
2122
import java.util.Map;
2223

2324
import tv.danmaku.ijk.media.exo2.IjkExo2MediaPlayer;
2425
import tv.danmaku.ijk.media.exo2.demo.EventLogger;
25-
import tv.danmaku.ijk.media.player.IMediaPlayer;
2626

2727
/**
2828
* 自定义exo player,实现不同于库的exo 无缝切换效果
@@ -31,14 +31,14 @@ public class GSYExo2MediaPlayer extends IjkExo2MediaPlayer {
3131

3232
private static final String TAG = "GSYExo2MediaPlayer";
3333

34-
private static final long PLAYLIST_PRELOAD_DURATION_US = 3_000_000L;
34+
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000;
35+
36+
private final Timeline.Window window = new Timeline.Window();
3537

3638
public static final int POSITION_DISCONTINUITY = 899;
3739

3840
private int playIndex = 0;
3941

40-
private final List<MediaSource> mediaSources = new ArrayList<>();
41-
4242
public GSYExo2MediaPlayer(Context context) {
4343
super(context);
4444
}
@@ -70,33 +70,33 @@ public void setDataSource(FileDescriptor fd) {
7070
@Override
7171
public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, @Player.DiscontinuityReason int reason) {
7272
super.onPositionDiscontinuity(oldPosition, newPosition, reason);
73-
if (oldPosition.mediaItemIndex != newPosition.mediaItemIndex) {
74-
playIndex = newPosition.mediaItemIndex;
75-
notifyOnInfo(POSITION_DISCONTINUITY, reason);
76-
}
77-
}
78-
79-
@Override
80-
public void onMediaItemTransition(MediaItem mediaItem, @Player.MediaItemTransitionReason int reason) {
81-
if (mInternalPlayer != null) {
82-
playIndex = mInternalPlayer.getCurrentMediaItemIndex();
83-
notifyOnInfo(POSITION_DISCONTINUITY, reason);
84-
}
73+
notifyOnInfo(POSITION_DISCONTINUITY, reason);
8574
}
8675

8776
public void setDataSource(List<String> uris, Map<String, String> headers, int index, boolean cache) {
8877
mHeaders = headers;
89-
mediaSources.clear();
90-
mMediaSource = null;
9178
if (uris == null) {
9279
return;
9380
}
81+
ConcatenatingMediaSource concatenatedSource = new ConcatenatingMediaSource();
9482
for (String uri : uris) {
9583
MediaSource mediaSource = mExoHelper.getMediaSource(uri, isPreview, cache, false, mCacheDir, getOverrideExtension());
96-
mediaSources.add(mediaSource);
84+
concatenatedSource.addMediaSource(mediaSource);
9785
}
9886
playIndex = index;
99-
mMediaSource = mediaSources.isEmpty() ? null : mediaSources.get(0);
87+
mMediaSource = concatenatedSource;
88+
89+
90+
/// ConcatenatingMediaSource2 是把多个视频拼成一个播放,时间轴只有一个
91+
// ConcatenatingMediaSource2.Builder mediaSourceBuilder =
92+
// new ConcatenatingMediaSource2.Builder().useDefaultMediaSourceFactory(mAppContext);
93+
//
94+
// for (String uri : uris) {
95+
// MediaSource mediaSource = mExoHelper.getMediaSource(uri, isPreview, cache, false, mCacheDir, getOverrideExtension());
96+
// mediaSourceBuilder.add(mediaSource, 0);
97+
// }
98+
// playIndex = index;
99+
// mMediaSource = mediaSourceBuilder.build();
100100
}
101101

102102

@@ -107,10 +107,20 @@ public void previous() {
107107
if (mInternalPlayer == null) {
108108
return;
109109
}
110-
if (!mInternalPlayer.hasPreviousMediaItem()) {
110+
Timeline timeline = mInternalPlayer.getCurrentTimeline();
111+
if (timeline.isEmpty()) {
111112
return;
112113
}
113-
mInternalPlayer.seekToPreviousMediaItem();
114+
int windowIndex = mInternalPlayer.getCurrentMediaItemIndex();
115+
timeline.getWindow(windowIndex, window);
116+
int previousWindowIndex = mInternalPlayer.getPreviousMediaItemIndex();
117+
if (previousWindowIndex != C.INDEX_UNSET
118+
&& (mInternalPlayer.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
119+
|| (window.isDynamic && !window.isSeekable))) {
120+
mInternalPlayer.seekTo(previousWindowIndex, C.TIME_UNSET);
121+
} else {
122+
mInternalPlayer.seekTo(0);
123+
}
114124
}
115125

116126
@Override
@@ -140,8 +150,6 @@ public void run() {
140150
.setLooper(Looper.getMainLooper())
141151
.setTrackSelector(mTrackSelector)
142152
.setLoadControl(mLoadControl).build();
143-
mInternalPlayer.setPreloadConfiguration(
144-
new ExoPlayer.PreloadConfiguration(PLAYLIST_PRELOAD_DURATION_US));
145153

146154
mInternalPlayer.addListener(GSYExo2MediaPlayer.this);
147155
mInternalPlayer.addAnalyticsListener(GSYExo2MediaPlayer.this);
@@ -151,16 +159,11 @@ public void run() {
151159
}
152160
if (mSurface != null)
153161
mInternalPlayer.setVideoSurface(mSurface);
154-
if (isLooping) {
155-
mInternalPlayer.setRepeatMode(Player.REPEAT_MODE_ALL);
156-
}
157-
if (mediaSources.isEmpty()) {
158-
notifyOnError(IMediaPlayer.MEDIA_ERROR_UNKNOWN, IMediaPlayer.MEDIA_ERROR_UNKNOWN);
159-
release();
160-
return;
162+
///fix start index
163+
if (playIndex > 0) {
164+
mInternalPlayer.seekTo(playIndex, C.INDEX_UNSET);
161165
}
162-
int startIndex = Math.min(Math.max(0, playIndex), mediaSources.size() - 1);
163-
mInternalPlayer.setMediaSources(mediaSources, startIndex, C.TIME_UNSET);
166+
mInternalPlayer.setMediaSource(mMediaSource, false);
164167
mInternalPlayer.prepare();
165168
mInternalPlayer.setPlayWhenReady(false);
166169
}
@@ -175,18 +178,17 @@ public void next() {
175178
if (mInternalPlayer == null) {
176179
return;
177180
}
178-
if (!mInternalPlayer.hasNextMediaItem()) {
181+
Timeline timeline = mInternalPlayer.getCurrentTimeline();
182+
if (timeline.isEmpty()) {
179183
return;
180184
}
181-
mInternalPlayer.seekToNextMediaItem();
182-
}
183-
184-
public boolean hasNext() {
185-
return mInternalPlayer != null && mInternalPlayer.hasNextMediaItem();
186-
}
187-
188-
public boolean hasPrevious() {
189-
return mInternalPlayer != null && mInternalPlayer.hasPreviousMediaItem();
185+
int windowIndex = mInternalPlayer.getCurrentMediaItemIndex();
186+
int nextWindowIndex = mInternalPlayer.getNextMediaItemIndex();
187+
if (nextWindowIndex != C.INDEX_UNSET) {
188+
mInternalPlayer.seekTo(nextWindowIndex, C.TIME_UNSET);
189+
} else if (timeline.getWindow(windowIndex, window).isDynamic) {
190+
mInternalPlayer.seekTo(windowIndex, C.TIME_UNSET);
191+
}
190192
}
191193

192194
public int getCurrentWindowIndex() {

app/src/main/java/com/example/gsyvideoplayer/exo/GSYExo2PlayerView.java

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -340,52 +340,22 @@ protected int getSmallId() {
340340
@Override
341341
public void onInfo(int what, int extra) {
342342
if (what == POSITION_DISCONTINUITY) {
343-
syncCurrentMediaInfoFromPlayer();
343+
int window = ((GSYExo2MediaPlayer) getGSYVideoManager().getPlayer().getMediaPlayer()).getCurrentWindowIndex();
344+
mPlayPosition = window;
345+
GSYVideoModel gsyVideoModel = mUriList.get(window);
346+
if (!TextUtils.isEmpty(gsyVideoModel.getTitle())) {
347+
mTitleTextView.setText(gsyVideoModel.getTitle());
348+
}
344349
} else {
345350
super.onInfo(what, extra);
346351
}
347352
}
348353

349354

350355
public void nextUI() {
351-
onPlaylistSeek();
352-
}
353-
354-
public void onPlaylistSeek() {
355-
syncCurrentMediaInfoFromPlayer();
356356
resetProgressAndTime();
357357
}
358358

359-
public int getPlayPosition() {
360-
return mPlayPosition;
361-
}
362-
363-
public int getMediaItemCount() {
364-
return mUriList == null ? 0 : mUriList.size();
365-
}
366-
367-
public String getCurrentMediaTitle() {
368-
if (mUriList == null || mUriList.isEmpty() || mPlayPosition < 0 || mPlayPosition >= mUriList.size()) {
369-
return "";
370-
}
371-
return mUriList.get(mPlayPosition).getTitle();
372-
}
373-
374-
private void syncCurrentMediaInfoFromPlayer() {
375-
if (getGSYVideoManager().getPlayer() == null || getGSYVideoManager().getPlayer().getMediaPlayer() == null) {
376-
return;
377-
}
378-
int window = ((GSYExo2MediaPlayer) getGSYVideoManager().getPlayer().getMediaPlayer()).getCurrentWindowIndex();
379-
if (mUriList == null || window < 0 || window >= mUriList.size()) {
380-
return;
381-
}
382-
mPlayPosition = window;
383-
GSYVideoModel gsyVideoModel = mUriList.get(window);
384-
if (!TextUtils.isEmpty(gsyVideoModel.getTitle())) {
385-
mTitleTextView.setText(gsyVideoModel.getTitle());
386-
}
387-
}
388-
389359

390360
@Override
391361
protected void setDisplay(Surface surface) {

0 commit comments

Comments
 (0)