diff --git a/app/src/main/java/com/hi/music/player/adapter/AdapterPlayList.java b/app/src/main/java/com/hi/music/player/adapter/AdapterPlayList.java index b3b6ecd..2cd796a 100644 --- a/app/src/main/java/com/hi/music/player/adapter/AdapterPlayList.java +++ b/app/src/main/java/com/hi/music/player/adapter/AdapterPlayList.java @@ -15,6 +15,7 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; import com.hi.music.player.MusicApplication; import com.hi.music.player.R; +import com.hi.music.player.api.MediaControllerListener; import com.hi.music.player.databinding.ItemPlayListBinding; import com.hi.music.player.helper.CommonUtils; import com.hi.music.player.javabean.response.ResponsePlayListInfo; @@ -26,7 +27,7 @@ public class AdapterPlayList extends BaseAdapter extends RecyclerView notifyDataSetChanged(); } + + public void setData(List data) { + this.data.clear(); + this.data.addAll(data); + notifyDataSetChanged(); + } + public void addLoadingFooter() { isLoadingAdded = true; // notifyItemInserted(data.size()); diff --git a/app/src/main/java/com/hi/music/player/api/MediaControllerListener.java b/app/src/main/java/com/hi/music/player/api/MediaControllerListener.java index c1d618a..393f5ed 100644 --- a/app/src/main/java/com/hi/music/player/api/MediaControllerListener.java +++ b/app/src/main/java/com/hi/music/player/api/MediaControllerListener.java @@ -18,5 +18,5 @@ public interface MediaControllerListener { void onRequestNextUri(String videoId,int playListIndex,boolean playNow); - void onChangeMusic(MediaItem mediaItem); + void onChangeMusic(MediaItem mediaItem); } diff --git a/app/src/main/java/com/hi/music/player/api/OnHasUrlAction.java b/app/src/main/java/com/hi/music/player/api/OnHasUrlAction.java new file mode 100644 index 0000000..6afc635 --- /dev/null +++ b/app/src/main/java/com/hi/music/player/api/OnHasUrlAction.java @@ -0,0 +1,5 @@ +package com.hi.music.player.api; + +public interface OnHasUrlAction { + void onHasUrl(); +} diff --git a/app/src/main/java/com/hi/music/player/customerview/AnimaPlayingView.java b/app/src/main/java/com/hi/music/player/customerview/AnimaPlayingView.java index b151594..f3cdc2a 100644 --- a/app/src/main/java/com/hi/music/player/customerview/AnimaPlayingView.java +++ b/app/src/main/java/com/hi/music/player/customerview/AnimaPlayingView.java @@ -11,6 +11,8 @@ import android.view.animation.LinearInterpolator; import com.hi.music.player.helper.CommonUtils; +import java.util.ArrayList; +import java.util.List; import java.util.Random; public class AnimaPlayingView extends View { @@ -23,7 +25,7 @@ public class AnimaPlayingView extends View { private int minHeight = CommonUtils.dpToPx(4); // 音量条的最小高度 // 每个柱子的宽度 - private int barWidth =CommonUtils. dpToPx(4); + private int barWidth = CommonUtils.dpToPx(4); // 柱子之间的间距 private int barSpacing = CommonUtils.dpToPx(2); @@ -31,6 +33,7 @@ public class AnimaPlayingView extends View { private Random random; private ValueAnimator animator; + private List valueAnimatorList; public AnimaPlayingView(Context context) { super(context); @@ -48,6 +51,7 @@ public class AnimaPlayingView extends View { } private void init() { + valueAnimatorList = new ArrayList<>(); paint = new Paint(); paint.setColor(barColor); paint.setStyle(Paint.Style.FILL); @@ -58,6 +62,7 @@ public class AnimaPlayingView extends View { for (int i = 0; i < numBars; i++) { barHeights[i] = 0; } + initAnimating(); } @@ -84,9 +89,14 @@ public class AnimaPlayingView extends View { } } - // 启动固定动画,使音量条的高度变化 public void startAnimating() { + for (ValueAnimator valueAnimator : valueAnimatorList) { + valueAnimator.start(); + } + } + // 启动固定动画,使音量条的高度变化 + public void initAnimating() { for (int i = 0; i < numBars; i++) { animator = ValueAnimator.ofFloat(0, 1); animator.setDuration(1000); // 每0.5秒更新一次 @@ -104,16 +114,16 @@ public class AnimaPlayingView extends View { invalidate(); // 重绘视图 } }); - animator.setStartDelay(i* 200L); - animator.start(); + valueAnimatorList.add(animator); + animator.setStartDelay(i * 200L); } } - public void pauseAnimating(){ - if(animator!= null){ - animator.pause(); + public void pauseAnimating() { + for (ValueAnimator valueAnimator : valueAnimatorList) { + valueAnimator.pause(); } for (int i = 0; i < numBars; i++) { barHeights[i] = minHeight; @@ -122,7 +132,6 @@ public class AnimaPlayingView extends View { } - // 随机生成音量条的高度 private float randomHeight() { return minHeight + random.nextFloat() * (maxHeight - minHeight); diff --git a/app/src/main/java/com/hi/music/player/helper/CommonUtils.java b/app/src/main/java/com/hi/music/player/helper/CommonUtils.java index 575eae9..317c177 100644 --- a/app/src/main/java/com/hi/music/player/helper/CommonUtils.java +++ b/app/src/main/java/com/hi/music/player/helper/CommonUtils.java @@ -31,7 +31,7 @@ public class CommonUtils { private static String TAG = "----MUSIC---------"; - private static String TAG_ERROR = "----ERROR MUSIC---------"; + private static String TAG_ERROR = "----MUSIC---------ERROR--"; public static void LogMsg(String msg) { Log.d(TAG, msg); @@ -191,7 +191,6 @@ public class CommonUtils { // 3. 检查 URI 是否具有正确的格式 try { if (parsedUri.getScheme() == null) { - LogMsg( "URI has no valid scheme."); return false; } } catch (Exception e) { diff --git a/app/src/main/java/com/hi/music/player/javabean/CustomerUrlInfo.java b/app/src/main/java/com/hi/music/player/javabean/CustomerUrlInfo.java index 379ee49..2cf56fe 100644 --- a/app/src/main/java/com/hi/music/player/javabean/CustomerUrlInfo.java +++ b/app/src/main/java/com/hi/music/player/javabean/CustomerUrlInfo.java @@ -7,8 +7,17 @@ public class CustomerUrlInfo { private ResponsePlayUrl playUrl; private int playMusicIndex; private boolean needPlayNow; + private String videoId; + public String getVideoId() { + return videoId; + } + + public void setVideoId(String videoId) { + this.videoId = videoId; + } + public ResponsePlayUrl getPlayUrl() { return playUrl; } diff --git a/app/src/main/java/com/hi/music/player/media3/DynamicMediaSourceFactory.java b/app/src/main/java/com/hi/music/player/media3/DynamicMediaSourceFactory.java index 38eac36..7d253d4 100644 --- a/app/src/main/java/com/hi/music/player/media3/DynamicMediaSourceFactory.java +++ b/app/src/main/java/com/hi/music/player/media3/DynamicMediaSourceFactory.java @@ -6,8 +6,12 @@ import androidx.media3.common.MediaItem; import androidx.media3.common.util.UnstableApi; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DataSpec; +import androidx.media3.datasource.DefaultDataSource; +import androidx.media3.datasource.DefaultDataSourceFactory; +import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.datasource.ResolvingDataSource; import androidx.media3.datasource.cache.CacheDataSource; +import androidx.media3.datasource.cache.SimpleCache; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.drm.DrmSessionManagerProvider; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; @@ -16,6 +20,7 @@ import androidx.media3.exoplayer.source.MediaSourceFactory; import androidx.media3.exoplayer.source.ProgressiveMediaSource; import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy; +import com.hi.music.player.MusicApplication; import com.hi.music.player.api.RequestListener; import com.hi.music.player.helper.CommonUtils; import com.hi.music.player.javabean.response.ResponsePlayUrl; @@ -32,16 +37,18 @@ import okhttp3.ResponseBody; public class DynamicMediaSourceFactory implements MediaSource.Factory { // private final CacheDataSource.Factory cacheDataSourceFactory; // private final ExoPlayer player; - private DefaultMediaSourceFactory mediaSourceFactory; + private DataSource.Factory mediaSourceFactory; + private SimpleCache simpleCache; // public DynamicMediaSourceFactory(DefaultMediaSourceFactory factory,CacheDataSource.Factory cacheDataSourceFactory, ExoPlayer exoPlayer) { // this.cacheDataSourceFactory = cacheDataSourceFactory; // this.player = exoPlayer; // this.mediaSourceFactory = factory; // } - public DynamicMediaSourceFactory(DefaultMediaSourceFactory factory) { + public DynamicMediaSourceFactory(DataSource.Factory factory, SimpleCache cache) { this.mediaSourceFactory = factory; + this.simpleCache = cache; } @@ -105,22 +112,40 @@ public class DynamicMediaSourceFactory implements MediaSource.Factory { // } // }); + + +// DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true); +// 这里的DefaultDataSource同时支持本地和HTTP请求的资源,自动实现检测 (The DefaultDataSource supports both local and Http sources. It automatically detects which one to use.) + + //实现缓存 + CacheDataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory() + .setCache(simpleCache) + .setUpstreamDataSourceFactory(mediaSourceFactory) + .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); + + MediaSource mediaSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory) + .createMediaSource(mediaItem); + + return mediaSource; + + + // return new ProgressiveMediaSource.Factory(cacheDataSourceFactory) // .createMediaSource(MediaItem.fromUri(responsePlayUrl.getAudioUrlMedium())); // 可以在这里根据 mediaItem 的 ID 动态生成新的 URI - String updatedUri = "https://rr1---sn-tt1e7nlz.googlevideo.com/videoplayback?expire=1727628605&ei=3TD5ZuWFEe-yzN0P27WuqQ4&ip=146.19.167.8&id=o-ANGM0PjEvsfYH7TmYV_DFuD-65tipJeeLe2URDOk90sL&itag=140&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&mh=xj&mm=31%2C29&mn=sn-tt1e7nlz%2Csn-vgqsknsk&ms=au%2Crdu&mv=m&mvi=1&pl=24&pcm2=no&gcr=us&initcwndbps=7610000&vprv=1&svpuc=1&mime=audio%2Fmp4&rqh=1&gir=yes&clen=5440168&dur=335.973&lmt=1709326903801285&mt=1727606690&fvip=5&keepalive=yes&fexp=51299152&c=ANDROID_MUSIC&txp=2318224&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cpcm2%2Cgcr%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIhALmM_S8Cmagr60muB3wDOby0OdcjF-x6f7TcEenixH0KAiAnR0-hmA03MeVzSg2wi5ncJ4Ve5FFlpZnlSoRNGWgGhQ%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=ABPmVW0wRQIhAPv5slfEnf8_E7o6yjEkussQ6JIFFaSY6QtP9HXncTTcAiAjlhMa71t76Wu1R1rcmsHoO6pyxjhGYouio4D0deJqEA%3D%3D"; - Uri updateUri = null; +// String updatedUri = "https://rr1---sn-tt1e7nlz.googlevideo.com/videoplayback?expire=1727628605&ei=3TD5ZuWFEe-yzN0P27WuqQ4&ip=146.19.167.8&id=o-ANGM0PjEvsfYH7TmYV_DFuD-65tipJeeLe2URDOk90sL&itag=140&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&mh=xj&mm=31%2C29&mn=sn-tt1e7nlz%2Csn-vgqsknsk&ms=au%2Crdu&mv=m&mvi=1&pl=24&pcm2=no&gcr=us&initcwndbps=7610000&vprv=1&svpuc=1&mime=audio%2Fmp4&rqh=1&gir=yes&clen=5440168&dur=335.973&lmt=1709326903801285&mt=1727606690&fvip=5&keepalive=yes&fexp=51299152&c=ANDROID_MUSIC&txp=2318224&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cpcm2%2Cgcr%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIhALmM_S8Cmagr60muB3wDOby0OdcjF-x6f7TcEenixH0KAiAnR0-hmA03MeVzSg2wi5ncJ4Ve5FFlpZnlSoRNGWgGhQ%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=ABPmVW0wRQIhAPv5slfEnf8_E7o6yjEkussQ6JIFFaSY6QtP9HXncTTcAiAjlhMa71t76Wu1R1rcmsHoO6pyxjhGYouio4D0deJqEA%3D%3D"; +// Uri updateUri = null; +// +// MediaItem.Builder builder = mediaItem.buildUpon(); +// if (mediaItem.localConfiguration != null) { +// updateUri = mediaItem.localConfiguration.uri; +// builder.setUri(updateUri); +// CommonUtils.LogErrorMsg("----updateUri=成功 builder="+mediaItem.mediaId+"--updateUri="+updateUri); +// }else { +// CommonUtils.LogErrorMsg("----updateUri=null builder="+mediaItem.mediaId); +// } - MediaItem.Builder builder = mediaItem.buildUpon(); - if (mediaItem.localConfiguration != null) { - updateUri = mediaItem.localConfiguration.uri; - builder.setUri(updateUri); - CommonUtils.LogErrorMsg("----updateUri=成功 builder="+mediaItem.mediaId+"--updateUri="+updateUri); - }else { - CommonUtils.LogErrorMsg("----updateUri=null builder="+mediaItem.mediaId); - } - - return mediaSourceFactory.createMediaSource(builder.build()); +// return mediaSourceFactory.createMediaSource(builder.build()); } diff --git a/app/src/main/java/com/hi/music/player/media3/MyMediaControllerManager.java b/app/src/main/java/com/hi/music/player/media3/MyMediaControllerManager.java index c4158de..dba29f4 100644 --- a/app/src/main/java/com/hi/music/player/media3/MyMediaControllerManager.java +++ b/app/src/main/java/com/hi/music/player/media3/MyMediaControllerManager.java @@ -18,6 +18,7 @@ import com.google.common.util.concurrent.MoreExecutors; import com.hi.music.player.MusicApplication; import com.hi.music.player.api.MediaControllerListener; import com.hi.music.player.api.MediaControllerStatusListener; +import com.hi.music.player.api.OnHasUrlAction; import com.hi.music.player.helper.CommonUtils; import com.hi.music.player.helper.MyValue; import com.hi.music.player.javabean.response.ResponsePlayListInfo; @@ -78,7 +79,6 @@ public class MyMediaControllerManager { mediaController.addListener(new Player.Listener() { @Override public void onPlayerError(PlaybackException error) { - CommonUtils.LogMsg("=-----PlaybackException+" + error.getMessage()); mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR); } @@ -99,13 +99,22 @@ public class MyMediaControllerManager { mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING); // TODO: 2024/9/26 自动播放完成切歌到下一首播放没有触发这里请求下一首 if (mediaController.hasNextMediaItem()) { - MediaItem mediaItemAt = mediaController.getMediaItemAt(mediaController.getNextMediaItemIndex()); - if (!CommonUtils.hasValidUri(mediaItemAt)) { - CommonUtils.LogMsg("----0000000000-请求下一首的uri" + mediaController.getMediaItemCount()); - int nextIndex = mediaController.getNextMediaItemIndex(); - mListener.onRequestNextUri(mediaController.getMediaItemAt(nextIndex).mediaId, nextIndex, false); - } - + int nextMediaItemIndex = mediaController.getNextMediaItemIndex(); + onCallRequestUrl(nextMediaItemIndex, false, new OnHasUrlAction() { + @Override + public void onHasUrl() { + CommonUtils.LogMsg("-------------有有效URl--播放检查下一首 位置="+nextMediaItemIndex ); + } + }); + } + if (mediaController.hasPreviousMediaItem()) { + int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex(); + onCallRequestUrl(previousMediaItemIndex, false, new OnHasUrlAction() { + @Override + public void onHasUrl() { + CommonUtils.LogMsg("-------------有有效URl--播放检查上一首 位置="+previousMediaItemIndex ); + } + }); } } else { @@ -145,11 +154,15 @@ public class MyMediaControllerManager { } - // /** -// * 更新播放列表中的音频url -// * -// * @param playUrl -// */ + public int getCurIndex(){ + return mediaController.getCurrentMediaItemIndex(); + } + + /** + * 更新播放列表中的音频url + * + * @param playUrl + */ public void UpdateAudioUrl(ResponsePlayUrl playUrl, int index) { CommonUtils.LogMsg("-------------更新播放列表中的音频url= index=" + index); for (int i = 0; i < mediaController.getMediaItemCount(); i++) { @@ -285,15 +298,14 @@ public class MyMediaControllerManager { public void playNext() { if (mediaController.hasNextMediaItem()) { int nextMediaItemIndex = mediaController.getNextMediaItemIndex(); - MediaItem mediaItemAt = mediaController.getMediaItemAt(nextMediaItemIndex); - boolean b = CommonUtils.hasValidUri(mediaItemAt); - if (b) { - mediaController.seekToNextMediaItem(); - return; - } - CommonUtils.LogMsg("-------------有下一首,但是歌曲url请求失败,需要重新请求"); - mListener.onRequestNextUri(mediaController.getMediaItemAt(nextMediaItemIndex).mediaId, nextMediaItemIndex, true); + onCallRequestUrl(nextMediaItemIndex, true, new OnHasUrlAction() { + @Override + public void onHasUrl() { + mediaController.seekToNextMediaItem(); + mediaController.play(); + } + }); } else { // int currentMediaItemIndex = mediaController.getCurrentMediaItemIndex(); // if (currentMediaItemIndex < playList.size() - 1) { @@ -307,7 +319,16 @@ public class MyMediaControllerManager { public void playPrevious() { if (mediaController.hasPreviousMediaItem()) { - mediaController.seekToPreviousMediaItem(); + + int nextMediaItemIndex = mediaController.getNextMediaItemIndex(); + onCallRequestUrl(nextMediaItemIndex, true, new OnHasUrlAction() { + @Override + public void onHasUrl() { + mediaController.seekToPreviousMediaItem(); + mediaController.play(); + } + }); + } else { mediaController.seekTo(0); mediaController.play(); @@ -327,15 +348,25 @@ public class MyMediaControllerManager { } stop(); - mediaController.prepare(); - mediaController.seekTo(index); + mediaController.seekTo(index,0); + onCallRequestUrl(index, true, new OnHasUrlAction() { + @Override + public void onHasUrl() { + mediaController.play(); + CommonUtils.LogMsg("-------------有有效URl--播放指定播放列表位置的歌曲" ); + } + }); + } + + private void onCallRequestUrl(int index, boolean playNow, OnHasUrlAction action){ MediaItem mediaItemAt = mediaController.getMediaItemAt(index); boolean b = CommonUtils.hasValidUri(mediaItemAt); if (!b) { - CommonUtils.LogMsg("-------------播放指定播放列表位置的歌曲,需要重新请求"); - mListener.onRequestNextUri(mediaItemAt.mediaId, index, true); + CommonUtils.LogMsg("-------------请求URl index"+index+"---playNow="+playNow); + mListener.onRequestNextUri(mediaItemAt.mediaId, index, playNow); + }else { + action.onHasUrl(); } - } } diff --git a/app/src/main/java/com/hi/music/player/media3/PlaybackService.java b/app/src/main/java/com/hi/music/player/media3/PlaybackService.java index 5511551..5321da7 100644 --- a/app/src/main/java/com/hi/music/player/media3/PlaybackService.java +++ b/app/src/main/java/com/hi/music/player/media3/PlaybackService.java @@ -7,10 +7,13 @@ import androidx.annotation.Nullable; import androidx.annotation.OptIn; import androidx.media3.common.Player; import androidx.media3.common.util.UnstableApi; +import androidx.media3.database.DatabaseProvider; +import androidx.media3.database.ExoDatabaseProvider; import androidx.media3.database.StandaloneDatabaseProvider; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DataSpec; import androidx.media3.datasource.DefaultDataSource; +import androidx.media3.datasource.DefaultDataSourceFactory; import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.datasource.ResolvingDataSource; import androidx.media3.datasource.cache.CacheDataSource; @@ -40,8 +43,21 @@ public class PlaybackService extends MediaSessionService { public void onCreate() { super.onCreate(); + // 1. 初始化缓存 + File cacheDir = new File(getCacheDir(), "media_cache"); + long maxCacheSize = 100 * 1024 * 1024; // 缓存大小 100MB + StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(this); + SimpleCache cache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(maxCacheSize), databaseProvider); - DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(new DefaultMediaSourceFactory(new DefaultHttpDataSource.Factory())); + + + DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true); +// 这里的DefaultDataSource同时支持本地和HTTP请求的资源,自动实现检测 (The DefaultDataSource supports both local and Http sources. It automatically detects which one to use.) +// DefaultDataSource.Factory defaultDataSourceFactory = new DefaultDataSourceFactory(MusicApplication.myApplication, httpDataSourceFactory); + DefaultDataSource.Factory upstreamFactory = new DefaultDataSource.Factory(this); + + DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(upstreamFactory,cache); +// DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(new DefaultMediaSourceFactory(new DefaultHttpDataSource.Factory()),cache); DefaultMediaSourceFactory defaultMediaSourceFactory1 = new DefaultMediaSourceFactory(getUrlFactory()); @@ -53,8 +69,13 @@ public class PlaybackService extends MediaSessionService { 10000, // bufferForPlaybackMs: 播放时的目标缓冲时间(毫秒) 5000) // bufferForPlaybackAfterRebufferMs: 重新缓冲后的缓冲时间(毫秒) .build(); + + + + + player = new ExoPlayer.Builder(this) -// .setMediaSourceFactory(customMediaSourceFactory) + .setMediaSourceFactory(customMediaSourceFactory) // .setLoadControl(loadControl) .build(); mediaSession = new MediaSession.Builder(this, player) diff --git a/app/src/main/java/com/hi/music/player/network/ObserverWrapper.java b/app/src/main/java/com/hi/music/player/network/ObserverWrapper.java index 7c6f9e9..e61d911 100644 --- a/app/src/main/java/com/hi/music/player/network/ObserverWrapper.java +++ b/app/src/main/java/com/hi/music/player/network/ObserverWrapper.java @@ -26,7 +26,7 @@ public class ObserverWrapper implements Observer { @Override public void onError(Throwable e) { - CommonUtils.LogMsg("----------onError"+e.getMessage()); + CommonUtils.LogMsg("----------onError---"+e.getMessage()); requestListener.onFail(e.getMessage()); } diff --git a/app/src/main/java/com/hi/music/player/network/RetrofitManager.java b/app/src/main/java/com/hi/music/player/network/RetrofitManager.java index 21a2d52..a64f8c8 100644 --- a/app/src/main/java/com/hi/music/player/network/RetrofitManager.java +++ b/app/src/main/java/com/hi/music/player/network/RetrofitManager.java @@ -53,7 +53,7 @@ public class RetrofitManager { .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) - .addInterceptor(httpLoggingInterceptor) +// .addInterceptor(httpLoggingInterceptor) .build(); retrofit = new Retrofit.Builder() .baseUrl(base_Host) diff --git a/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java b/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java index ab8f761..f56e94c 100644 --- a/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java +++ b/app/src/main/java/com/hi/music/player/ui/activity/PlayActivity.java @@ -73,6 +73,12 @@ public class PlayActivity extends BaseActivity implements S private GradientDrawable gradientDrawable; private int lighterColor, darkerColor; + // 0 播放列表请求失败 1 立即播放的歌曲请求失败 + private int netError = 0; + + + // 请求失败的立即播放的歌曲信息 + private CustomerUrlInfo mCustomerUrlInfo; @Override protected ActivityPlayBinding getViewBinding() { @@ -94,7 +100,9 @@ public class PlayActivity extends BaseActivity implements S @Override public void onChanged(List playList) { if (playList == null) { - CommonUtils.LogMsg("---------playList = null"); + CommonUtils.LogErrorMsg("---------playList = null"); + netError = 0; + vb.linearRetry.setVisibility(View.VISIBLE); return; } if (playList.size() > 0) { @@ -111,7 +119,12 @@ public class PlayActivity extends BaseActivity implements S public void onChanged(CustomerUrlInfo customerUrlInfo) { if (customerUrlInfo.isNeedPlayNow() && customerUrlInfo.getPlayUrl() == null) { // TODO: 2024/9/26 需要马上播放这首歌曲,但是此次网络请求失败 - CommonUtils.LogMsg("-------------需要马上播放这首歌曲,但是此次网络请求失败"); + CommonUtils.LogErrorMsg("-------------需要马上播放这首歌曲,但是此次网络请求失败"); + netError = 1; + mCustomerUrlInfo = customerUrlInfo; + initShowPlayList(false); + vb.linearRetry.setVisibility(View.VISIBLE); + mediaControllerManager.pause(); return; } @@ -119,13 +132,13 @@ public class PlayActivity extends BaseActivity implements S int second = customerUrlInfo.getPlayMusicIndex(); boolean needPlayNow = customerUrlInfo.isNeedPlayNow(); if (needPlayNow) { + mediaControllerManager.playPositionMusic(second); mediaControllerManager.play(); } } }); } - @OptIn(markerClass = UnstableApi.class) private void initPlayerView() { vb.playerView.setShowRewindButton(false); @@ -154,35 +167,45 @@ public class PlayActivity extends BaseActivity implements S switch (playStatus) { case Player.STATE_IDLE: - CommonUtils.LogMsg("-------------playStatus=STATE_IDLE"); + CommonUtils.LogMsg("-------------IDLE"); break; case Player.STATE_BUFFERING: //快进没有缓冲的时候触发 vb.btnPlay.setSelected(false); vb.progressBarLoading.setVisibility(View.VISIBLE); - CommonUtils.LogMsg("-------------playStatus=STATE_BUFFERING"); + CommonUtils.LogMsg("-------------缓冲"); break; case Player.STATE_READY: vb.btnPlay.setSelected(true); mHandler.post(mRunnable); vb.progressBarLoading.setVisibility(View.GONE); - CommonUtils.LogMsg("-------------playStatus=STATE_READY"); + CommonUtils.LogMsg("-------------准备"); break; case Player.STATE_ENDED: //播放完成 vb.btnPlay.setSelected(false); - CommonUtils.LogMsg("-------------playStatus=STATE_ENDED 播放完成"); + CommonUtils.LogMsg("------------- 播放完成"); mHandler.removeCallbacks(mRunnable); // 停止更新 updatePlayComplete(); mediaControllerManager.playNext(); break; case MyValue.PLAY_STATUS_CODE_PAUSE: + CommonUtils.LogMsg("------------- 暂停"); vb.btnPlay.setSelected(false); + vb.layoutPlayList.imPlay.setSelected(false); break; case MyValue.PLAY_STATUS_CODE_PLAYING: + CommonUtils.LogMsg("------------- 播放ing getCurIndex=" + mediaControllerManager.getCurIndex()); + vb.progressBarLoading.setVisibility(View.GONE); vb.btnPlay.setSelected(true); + vb.layoutPlayList.imPlay.setSelected(true); + break; + case MyValue.PLAY_STATUS_CODE_ERROR: + vb.progressBarLoading.setVisibility(View.GONE); + int currentMediaItemIndex = mediaControllerManager.getMediaController().getCurrentMediaItemIndex(); + CommonUtils.LogMsg("------------- 播放错误 currentMediaItemIndex=" + currentMediaItemIndex); break; } @@ -190,7 +213,6 @@ public class PlayActivity extends BaseActivity implements S @Override public void onRequestNextUri(String videoId, int playListIndex, boolean playNow) { - CommonUtils.LogMsg("------------onRequestNextUri= videoId=" + videoId); if (playNow) { vb.progressBarLoading.setVisibility(View.VISIBLE); } @@ -215,6 +237,7 @@ public class PlayActivity extends BaseActivity implements S vb.btnPrevious.setOnClickListener(this); vb.imBack.setOnClickListener(this); vb.btnMusicList.setOnClickListener(this); + vb.tvRetry.setOnClickListener(this); } @@ -363,9 +386,19 @@ public class PlayActivity extends BaseActivity implements S } else { mediaControllerManager.pause(); } - if(adapterPlayList!= null){ + if (adapterPlayList != null) { adapterPlayList.updateCurMusicAnimation(); } + } else if (v.equals(vb.tvRetry)) { + vb.linearRetry.setVisibility(View.GONE); + if (netError == 0) { + vmPlay.getPlayMusicList(responseSingle); + } else { + if (mCustomerUrlInfo != null) { + vmPlay.getPlayUrl(mCustomerUrlInfo.getVideoId(), mCustomerUrlInfo.getPlayMusicIndex(), true); + } + + } } } @@ -387,7 +420,7 @@ public class PlayActivity extends BaseActivity implements S List playList = mediaControllerManager.getPlayList(); adapterPlayList = new AdapterPlayList(); vb.layoutPlayList.recyclerList.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication)); - adapterPlayList.addData(playList); + adapterPlayList.setData(playList); vb.layoutPlayList.recyclerList.setAdapter(adapterPlayList); vb.layoutPlayList.imPlay.setOnClickListener(this); initPlayList = true; diff --git a/app/src/main/java/com/hi/music/player/ui/activity/viewmodel/VMPlay.java b/app/src/main/java/com/hi/music/player/ui/activity/viewmodel/VMPlay.java index c01ec40..f1c6cbe 100644 --- a/app/src/main/java/com/hi/music/player/ui/activity/viewmodel/VMPlay.java +++ b/app/src/main/java/com/hi/music/player/ui/activity/viewmodel/VMPlay.java @@ -41,6 +41,7 @@ public class VMPlay extends ViewModel { @Override public void onFail(String errorMsg) { + // TODO: 2024/10/8 播放列表拉取失败 _playList.setValue(null); } @@ -63,10 +64,12 @@ public class VMPlay extends ViewModel { public void getPlayUrl(String videoId, int playListIndex,boolean playNow) { CustomerUrlInfo customerUrlInfo = new CustomerUrlInfo(); customerUrlInfo.setNeedPlayNow(playNow); + customerUrlInfo.setVideoId(videoId); RetrofitManager.getInstance().getPlayUrl(videoId, new RequestListener() { @Override public void onFail(String errorMsg) { + CommonUtils.LogMsg("-------------此次网络请求失败 playNow="+playNow); _playUrlMutableLiveData.setValue(customerUrlInfo); } diff --git a/app/src/main/res/drawable/bg_retry.xml b/app/src/main/res/drawable/bg_retry.xml new file mode 100644 index 0000000..137718f --- /dev/null +++ b/app/src/main/res/drawable/bg_retry.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_play.xml b/app/src/main/res/layout/activity_play.xml index afd771b..71f312e 100644 --- a/app/src/main/res/layout/activity_play.xml +++ b/app/src/main/res/layout/activity_play.xml @@ -37,6 +37,39 @@ app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/im_back" /> + + + + + + + + + + + android:indeterminateTint="@color/white" + android:visibility="gone" /> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f73c0a7..5f6ae07 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,4 +22,6 @@ Privacy Policy Terms of Service Play next + Retry + An error occurred \ No newline at end of file