From c3cf575e02eaebbabdbc0ef6bb02bb7a438be481 Mon Sep 17 00:00:00 2001 From: litingting Date: Wed, 30 Oct 2024 11:53:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=92=AD=E6=94=BE=E6=97=B6=E9=95=BF=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=8D=E5=87=86=E7=A1=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hi/music/player/helper/CommonUtils.java | 36 ++++++++++--- .../media3/MyMediaControllerManager.java | 13 +++-- .../hi/music/player/network/JsonHelper.java | 20 ++++--- .../player/ui/activity/BaseActivity.java | 54 ++++++++++++++++++- .../player/ui/activity/PlayActivity.java | 28 +++------- .../player/ui/fragmnt/SearchFragment.java | 44 +++++++++------ app/src/main/res/drawable/icon_next_black.xml | 24 +++++++++ app/src/main/res/layout/activity_play.xml | 20 ++++--- app/src/main/res/layout/dialog_play_list.xml | 2 +- app/src/main/res/layout/item_play_list.xml | 5 +- app/src/main/res/layout/layout_panel.xml | 22 +++++--- app/src/main/res/values/strings.xml | 2 + 12 files changed, 201 insertions(+), 69 deletions(-) create mode 100644 app/src/main/res/drawable/icon_next_black.xml 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 ba20303..ee6e802 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 @@ -81,20 +81,42 @@ public class CommonUtils { } - //time 3:45 + //time 3:45 转换成毫秒 public static long convertToMilliseconds(String time) { String[] parts = time.split(":"); - int minutes = Integer.parseInt(parts[0]); - int seconds = Integer.parseInt(parts[1]); + if(parts.length == 2){ + //3:45 + int minutes = Integer.parseInt(parts[0]); + int seconds = Integer.parseInt(parts[1]); + + return (minutes * 60L + seconds) * 1000-1000; + }else{ + //3:45:07 + int hours = Integer.parseInt(parts[0]); + int minutes = Integer.parseInt(parts[1]); + int seconds = Integer.parseInt(parts[2]); + return (hours*60L*60L+minutes * 60L + seconds) * 1000-1000; + } + - return (minutes * 60 + seconds) * 1000; // 转换为毫秒 } public static String convertMillisToTime(long millis) { - long seconds = (millis / 1000) % 60; - long minutes = (millis / (1000 * 60)) % 60; - return String.format("%d:%02d", minutes, seconds); // 格式化为 mm:ss + long seconds = millis / 1000; + long hours = seconds / 3600; + long minutes = (seconds % 3600) / 60; + long remainingSeconds = seconds % 60; + + +// long seconds = (millis / 1000) % 60; +// long minutes = (millis / (1000 * 60)) % 60; + if(hours>0){ + return String.format(MusicApplication.myApplication.getString(R.string.time_format),hours, minutes, remainingSeconds); // 格式化为 mm:ss + }else { + return String.format(MusicApplication.myApplication.getString(R.string.minute_time_format), minutes, remainingSeconds); // 格式化为 mm:ss + } + } public static int getMyColor(int resId) { 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 32ba47f..ac6a1dc 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 @@ -178,7 +178,7 @@ public class MyMediaControllerManager { } /** - * //0 不循环、1 列表循环、2 单曲循环、 + * //0 不循环、1 单曲循环、2 列表循环、 * @param mode */ public void setMode(int mode){ @@ -187,15 +187,20 @@ public class MyMediaControllerManager { mediaController.setRepeatMode(Player.REPEAT_MODE_OFF); break; case 1: - mediaController.setRepeatMode(Player.REPEAT_MODE_ALL); - break; - case 2: mediaController.setRepeatMode(Player.REPEAT_MODE_ONE); break; + case 2: + mediaController.setRepeatMode(Player.REPEAT_MODE_ALL); + break; } } + public int getRepeatMode(){ + return mediaController.getRepeatMode(); + + } + public String getCurVideoId() { MediaItem currentMediaItem = mediaController.getCurrentMediaItem(); if(currentMediaItem!= null){ diff --git a/app/src/main/java/com/hi/music/player/network/JsonHelper.java b/app/src/main/java/com/hi/music/player/network/JsonHelper.java index d3a7d39..4b4870f 100644 --- a/app/src/main/java/com/hi/music/player/network/JsonHelper.java +++ b/app/src/main/java/com/hi/music/player/network/JsonHelper.java @@ -79,7 +79,7 @@ public class JsonHelper { getCommonHome(sectionListContinuation, responseHome); } catch (JSONException exception) { - CommonUtils.LogMsg("----------exception="); + CommonUtils.LogMsg("----------exception="+exception.getMessage()); exception.printStackTrace(); } @@ -119,7 +119,8 @@ public class JsonHelper { String SongDuration = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("lengthText"), 0); long ms = CommonUtils.convertToMilliseconds(SongDuration); - + String textTime = CommonUtils.convertMillisToTime(ms); + CommonUtils.LogMsg("----------SongDuration=" + SongDuration + "---ms="+ms+"---textTime="+textTime); String[] watchEndPoint = getWatchEndPoint(playlistPanelVideoRenderer); @@ -129,11 +130,11 @@ public class JsonHelper { responsePlayListInfo.setSingerName(singerName); responsePlayListInfo.setAlbumTitle(AlbumTitle); responsePlayListInfo.setYear(YearRelease); - responsePlayListInfo.setDuration(SongDuration); + responsePlayListInfo.setDuration(textTime); responsePlayListInfo.setDurationMs(ms); responsePlayListInfo.setVideoId(watchEndPoint[0]); if (watchEndPoint[0] == null || watchEndPoint[0].isEmpty()) { - CommonUtils.LogMsg("----------songName=" + songName + "---setVideoId=null"); + continue; } responsePlayListInfo.setPlaylistId(watchEndPoint[1]); @@ -528,7 +529,12 @@ public class JsonHelper { if (list.size() > 0) { responseSearch.setList(list); } - searchList.add(responseSearch); + if(musicCardShelfRenderer!= null){ + searchList.add(responseSearch); + }else if(list.size() > 0){ + searchList.add(responseSearch); + } + } return searchList; @@ -695,6 +701,8 @@ public class JsonHelper { String duration = getJsonTitle(jsonText, 0); long ms = CommonUtils.convertToMilliseconds(duration); + //比接口返回的减少一秒 + String textTime = CommonUtils.convertMillisToTime(ms); JSONArray flexColumns = musicResponsiveListItemRenderer .getJSONArray("flexColumns"); @@ -730,7 +738,7 @@ public class JsonHelper { if (g == 2) Description = text; } listInfo.setDescribe(Description); - listInfo.setDuration(duration); + listInfo.setDuration(textTime); listInfo.setDurationMs(ms); listInfo.setSingerName(SingerName); listInfo.setSongTitle(SongTitle); diff --git a/app/src/main/java/com/hi/music/player/ui/activity/BaseActivity.java b/app/src/main/java/com/hi/music/player/ui/activity/BaseActivity.java index 0669a4f..2b245b5 100644 --- a/app/src/main/java/com/hi/music/player/ui/activity/BaseActivity.java +++ b/app/src/main/java/com/hi/music/player/ui/activity/BaseActivity.java @@ -3,13 +3,16 @@ package com.hi.music.player.ui.activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.view.Gravity; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.FrameLayout; +import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.OptIn; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; import androidx.core.view.WindowInsetsControllerCompat; @@ -17,11 +20,14 @@ import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModel; import androidx.media3.common.MediaItem; import androidx.media3.common.Player; +import androidx.media3.common.util.UnstableApi; import androidx.viewbinding.ViewBinding; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CircleCrop; import com.hi.music.player.MusicApplication; +import com.hi.music.player.R; +import com.hi.music.player.api.onPlayNextListener; import com.hi.music.player.databinding.ActivityBaseBinding; import com.hi.music.player.databinding.LayoutPanelBinding; import com.hi.music.player.helper.CommonUtils; @@ -44,7 +50,8 @@ public abstract class BaseActivity extends AppCompatActiv protected VMApplication vmApplication; protected MyMediaControllerManager mediaControllerManager; - + private Handler mHandler; + private Runnable mRunnable; @Override protected void onCreate(Bundle savedInstanceState) { @@ -94,6 +101,7 @@ public abstract class BaseActivity extends AppCompatActiv FrameLayout.LayoutParams.MATCH_PARENT, CommonUtils.dpToPx(74) ); + initProgressHandler(panelVb); panelVb.imPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -106,6 +114,19 @@ public abstract class BaseActivity extends AppCompatActiv } }); + panelVb.imNext.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mediaControllerManager.playNext(new onPlayNextListener() { + @Override + public void onPlayNext(boolean hasNext) { + if (!hasNext) { + Toast.makeText(MusicApplication.myApplication, getString(R.string.no_next_song_yet), Toast.LENGTH_SHORT).show(); + } + } + }); + } + }); panelVb.layoutPanel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -123,12 +144,14 @@ public abstract class BaseActivity extends AppCompatActiv layoutParams.gravity = Gravity.BOTTOM; vmApplication.playStatus.observe(this, new Observer() { + @OptIn(markerClass = UnstableApi.class) @Override public void onChanged(Integer integer) { CommonUtils.LogMsg("----------面板 播放状态更新=" + integer); if (panelView.getParent() == null) { CommonUtils.LogMsg("----------显示面板"); rootVb.frameLayout.addView(panelView, layoutParams); + mHandler.post(mRunnable); } MediaItem currentMediaItem = mediaControllerManager.getMediaController().getCurrentMediaItem(); if(currentMediaItem!= null){ @@ -136,6 +159,10 @@ public abstract class BaseActivity extends AppCompatActiv CharSequence title = currentMediaItem.mediaMetadata.title; CharSequence artist = currentMediaItem.mediaMetadata.artist; + if (currentMediaItem.mediaMetadata.durationMs != null) { + long durationMs = currentMediaItem.mediaMetadata.durationMs; + panelVb.circularPb.setMaxProgress((int) durationMs); + } if(artworkUri!= null){ CommonUtils.LogMsg("----------artworkUri="+artworkUri.toString()); Glide.with(MusicApplication.myApplication) @@ -175,7 +202,25 @@ public abstract class BaseActivity extends AppCompatActiv } + private void initProgressHandler(LayoutPanelBinding panelBinding) { + mHandler = new Handler(); + mRunnable = new Runnable() { + @Override + public void run() { + updatePlaybackProgress(panelBinding); + mHandler.postDelayed(this, 1000); + } + }; + } + private void updatePlaybackProgress(LayoutPanelBinding panelBinding) { + // 获取当前播放位置 + long contentPos = mediaControllerManager.getContentPos(); + long bufferPos = mediaControllerManager.getBufferPos(); + +// CommonUtils.LogMsg("---------播放进度-----contentPos=" + contentPos + "-----缓冲进度=" + bufferPos); + panelBinding.circularPb.setProgress((int) contentPos); + } private void setStatusBar() { //深色模式 WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView()); @@ -196,4 +241,11 @@ public abstract class BaseActivity extends AppCompatActiv protected K getApplicationScopeViewModel(@NonNull Class modelClass) { return mViewModelScope.getApplicationScopeViewModel(modelClass); } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mHandler != null && mRunnable != null) + mHandler.removeCallbacks(mRunnable); + } } \ No newline at end of file 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 9e21be7..36caf89 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 @@ -88,8 +88,8 @@ public class PlayActivity extends BaseActivity implements S private int[] imageStates = { R.drawable.icon_looper_no, - R.drawable.icon_looper, - R.drawable.icon_looper_1 + R.drawable.icon_looper_1, + R.drawable.icon_looper }; //0 不循环、1 列表循环、2 单曲循环、 @@ -177,7 +177,6 @@ public class PlayActivity extends BaseActivity implements S if (customerUrlInfo.isNeedPlayNow() && customerUrlInfo.getPlayUrl() == null) { // TODO: 2024/9/26 需要马上播放这首歌曲,但是此次网络请求失败 CommonUtils.LogErrorMsg("-------------需要马上播放这首歌曲,但是此次网络请求失败"); - updateErrorLayout(getString(R.string.song_loading_failed),true); netError = 1; mCustomerUrlInfo = customerUrlInfo; @@ -249,20 +248,9 @@ public class PlayActivity extends BaseActivity implements S } private void initMediaController() { -// mediaControllerManager = MyMediaControllerManager.getInstance(); -// String videoId = responseSingle.getVideoId(); - MediaItem currentMediaItem = mediaControllerManager.getMediaController().getCurrentMediaItem(); - if (currentMediaItem != null) { -// if (currentMediaItem.mediaId.equals(videoId)) { - // TODO: 2024/9/27 正在播放当前歌曲,又点进来 -// mediaControllerManager.getMediaController().seekTo(0); -// } -// if (mediaControllerManager.getMediaController().isPlaying()) { -// mediaControllerManager.stop(); -// } -// mediaControllerManager.resetPlayList(); - } - mediaControllerManager.setMode(currentMode); + int repeatMode = mediaControllerManager.getRepeatMode(); + CommonUtils.LogMsg("-------------repeatMode="+repeatMode); + vb.btnLoop.setImageResource(imageStates[repeatMode]); mediaControllerManager.addListener(vmApplication, new MediaControllerListener() { @Override public void onPlayStatus(int playStatus) { @@ -357,8 +345,7 @@ public class PlayActivity extends BaseActivity implements S String s = CommonUtils.convertMillisToTime(contentPos); - -// CommonUtils.LogMsg("---------播放进度-----contentPos=" + contentPos + "-----缓冲进度=" + bufferPos); + CommonUtils.LogMsg("---------播放进度-----contentPos=" + contentPos + "-----s=" + s); vb.tvCurrent.setText(s); vb.playProgress.setProgress((int) contentPos); vb.progressBarBuffer.setProgress((int) bufferPos); @@ -427,7 +414,7 @@ public class PlayActivity extends BaseActivity implements S if (color == -1) { return; } - lighterColor = CommonUtils.adjustBrightness(color, 1f); // 比原始颜色亮 20% + lighterColor = CommonUtils.adjustBrightness(color, 0.8f); // 比原始颜色亮 20% darkerColor = CommonUtils.adjustBrightness(color, 0.6f); // 比原始颜色暗 20% gradientDrawable = new GradientDrawable( GradientDrawable.Orientation.TOP_BOTTOM, @@ -544,6 +531,7 @@ public class PlayActivity extends BaseActivity implements S } break; case 1: + vb.progressBarLoading.setVisibility(View.VISIBLE); int curIndex = mediaControllerManager.getCurIndex(); String curVideoId = mediaControllerManager.getCurVideoId(); diff --git a/app/src/main/java/com/hi/music/player/ui/fragmnt/SearchFragment.java b/app/src/main/java/com/hi/music/player/ui/fragmnt/SearchFragment.java index 65a2538..eb58fc6 100644 --- a/app/src/main/java/com/hi/music/player/ui/fragmnt/SearchFragment.java +++ b/app/src/main/java/com/hi/music/player/ui/fragmnt/SearchFragment.java @@ -147,22 +147,36 @@ public class SearchFragment extends BaseFragment implemen String beastVideoId = responseSearch.getBeastVideoId(); String beastSongTitle = responseSearch.getBeastSongTitle(); String beastSongTCovert = responseSearch.getBeastSongTCovert(); + String pageType = responseSearch.getPageType(); - if(beastBrowserId!= null&&!beastBrowserId.isEmpty()){ - Intent intent = new Intent(requireActivity(), ResultListActivity.class); - intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, beastBrowserId); - startActivity(intent); - }else { - CommonUtils.LogMsg("---------击搜索结果的play按钮--beastVideoId="+beastVideoId); + if(beastVideoId!= null&&!beastVideoId.isEmpty()){ + CommonUtils.LogMsg("---------击搜索结果的play按钮--beastVideoId="+beastVideoId); - ResponseSingle responseSingle = new ResponseSingle(); - responseSingle.setSongTitle(beastSongTitle); - responseSingle.setSingerHead(beastSongTCovert); - responseSingle.setVideoId(beastVideoId); - responseSingle.setPlaylistId(""); - Intent intent = new Intent(requireActivity(), PlayActivity.class); - intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle); - startActivity(intent); + ResponseSingle responseSingle = new ResponseSingle(); + responseSingle.setSongTitle(beastSongTitle); + responseSingle.setSingerHead(beastSongTCovert); + responseSingle.setVideoId(beastVideoId); + responseSingle.setPlaylistId(""); + Intent intent = new Intent(requireActivity(), PlayActivity.class); + intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle); + startActivity(intent); + }else if(beastBrowserId!= null&&!beastBrowserId.isEmpty()){ + CommonUtils.LogMsg("---------击搜索结果的play按钮--pageType="+pageType); + switch (pageType){ + case "MUSIC_PAGE_TYPE_PLAYLIST": + case "MUSIC_PAGE_TYPE_ALBUM": + Intent intent1 = new Intent(requireActivity(), CategoryListActivity.class); + intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType); + intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, responseSearch.getBeastSongDescribe()); + intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, beastBrowserId); + startActivity(intent1); + break; + default: + Intent intent = new Intent(requireActivity(), ResultListActivity.class); + intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, beastBrowserId); + startActivity(intent); + break; + } } } @@ -177,8 +191,6 @@ public class SearchFragment extends BaseFragment implemen String songDescribe = responseSearchChild.getSongDescribe(); if(browserId!= null&&!browserId.isEmpty()){ - - String pageType = responseSearchChild.getPageType(); CommonUtils.LogMsg("---------点击搜索结果--pageType="+pageType); switch (pageType){ diff --git a/app/src/main/res/drawable/icon_next_black.xml b/app/src/main/res/drawable/icon_next_black.xml new file mode 100644 index 0000000..a266e90 --- /dev/null +++ b/app/src/main/res/drawable/icon_next_black.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/app/src/main/res/layout/activity_play.xml b/app/src/main/res/layout/activity_play.xml index 2f1ea6a..ccac461 100644 --- a/app/src/main/res/layout/activity_play.xml +++ b/app/src/main/res/layout/activity_play.xml @@ -62,6 +62,18 @@ app:use_controller="false" /> + + + - + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_play_list.xml b/app/src/main/res/layout/dialog_play_list.xml index 81f7123..3b8f8fb 100644 --- a/app/src/main/res/layout/dialog_play_list.xml +++ b/app/src/main/res/layout/dialog_play_list.xml @@ -34,7 +34,7 @@ android:id="@+id/top_im" android:layout_width="match_parent" android:layout_height="match_parent" - android:scaleType="fitXY" + android:scaleType="centerCrop" android:adjustViewBounds="true" android:src="@drawable/placeholder" /> diff --git a/app/src/main/res/layout/item_play_list.xml b/app/src/main/res/layout/item_play_list.xml index d726074..60226ec 100644 --- a/app/src/main/res/layout/item_play_list.xml +++ b/app/src/main/res/layout/item_play_list.xml @@ -35,10 +35,11 @@ @@ -47,6 +48,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name" + android:maxLines="1" + android:ellipsize="end" android:textColor="@color/text_color_1" android:textSize="14sp" /> diff --git a/app/src/main/res/layout/layout_panel.xml b/app/src/main/res/layout/layout_panel.xml index 0b547a2..09d0661 100644 --- a/app/src/main/res/layout/layout_panel.xml +++ b/app/src/main/res/layout/layout_panel.xml @@ -14,7 +14,17 @@ android:layout_height="52dp" android:layout_centerVertical="true" android:layout_marginStart="2dp" - android:src="@drawable/placeholder" /> + android:src="@mipmap/ic_launcher" /> + + @@ -64,7 +74,7 @@ + android:visibility="visible" + android:src="@drawable/icon_next_black" /> \ 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 f696cc9..95feed5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,4 +30,6 @@ Image loading failed Song loading failed Playlist loading failed + %d:%02d:%02d + %d:%02d \ No newline at end of file