播放时长显示不准确处理

This commit is contained in:
litingting 2024-10-30 11:53:35 +08:00
parent 26eb76deb3
commit c3cf575e02
12 changed files with 201 additions and 69 deletions

View File

@ -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:4507
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) {

View File

@ -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){

View File

@ -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);

View File

@ -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<T extends ViewBinding> 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<T extends ViewBinding> 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<T extends ViewBinding> 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<T extends ViewBinding> extends AppCompatActiv
layoutParams.gravity = Gravity.BOTTOM;
vmApplication.playStatus.observe(this, new Observer<Integer>() {
@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<T extends ViewBinding> 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<T extends ViewBinding> 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<T extends ViewBinding> extends AppCompatActiv
protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
return mViewModelScope.getApplicationScopeViewModel(modelClass);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mHandler != null && mRunnable != null)
mHandler.removeCallbacks(mRunnable);
}
}

View File

@ -88,8 +88,8 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> 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<ActivityPlayBinding> 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<ActivityPlayBinding> 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<ActivityPlayBinding> 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<ActivityPlayBinding> 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<ActivityPlayBinding> implements S
}
break;
case 1:
vb.progressBarLoading.setVisibility(View.VISIBLE);
int curIndex = mediaControllerManager.getCurIndex();
String curVideoId = mediaControllerManager.getCurVideoId();

View File

@ -147,22 +147,36 @@ public class SearchFragment extends BaseFragment<FragmentSearchBinding> 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<FragmentSearchBinding> implemen
String songDescribe = responseSearchChild.getSongDescribe();
if(browserId!= null&&!browserId.isEmpty()){
String pageType = responseSearchChild.getPageType();
CommonUtils.LogMsg("---------点击搜索结果--pageType="+pageType);
switch (pageType){

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2024 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@color/black"
android:pathData="M660,720L660,240L740,240L740,720L660,720ZM220,720L220,240L580,480L220,720Z"/>
</vector>

View File

@ -62,6 +62,18 @@
app:use_controller="false" />
</androidx.cardview.widget.CardView>
<ProgressBar
android:id="@+id/progressBarLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="@id/card_playerView"
app:layout_constraintRight_toRightOf="@id/card_playerView"
app:layout_constraintTop_toTopOf="@id/card_playerView"
app:layout_constraintBottom_toBottomOf="@id/card_playerView"
android:indeterminateTint="@color/white"
android:visibility="gone" />
<include layout="@layout/layout_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -252,11 +264,5 @@
layout="@layout/dialog_play_list" />
<ProgressBar
android:id="@+id/progressBarLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminateTint="@color/white"
android:visibility="gone" />
</FrameLayout>

View File

@ -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" />
</androidx.cardview.widget.CardView>

View File

@ -35,10 +35,11 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="12dp"
android:paddingEnd="10dp"
android:layout_toEndOf="@id/card"
android:orientation="vertical">
@ -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" />

View File

@ -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" />
<com.hi.music.player.helper.CircularProgressBar
android:id="@+id/circular_pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/image"
android:layout_alignBottom="@id/image"
android:layout_alignStart="@id/image"
android:layout_alignEnd="@id/image"
android:layout_gravity="center" />
<LinearLayout
android:layout_width="wrap_content"
@ -50,8 +60,8 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_marginEnd="20dp"
android:layout_toStartOf="@id/im_list"
android:layout_marginEnd="10dp"
android:layout_toStartOf="@id/im_next"
android:paddingStart="10dp"
android:paddingEnd="10dp">
@ -64,7 +74,7 @@
</FrameLayout>
<ImageView
android:id="@+id/im_list"
android:id="@+id/im_next"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
@ -72,7 +82,7 @@
android:layout_marginEnd="10dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:visibility="invisible"
android:src="@drawable/panel_icon_list" />
android:visibility="visible"
android:src="@drawable/icon_next_black" />
</RelativeLayout>

View File

@ -30,4 +30,6 @@
<string name="image_loading_failed">Image loading failed</string>
<string name="song_loading_failed">Song loading failed</string>
<string name="playList_loading_failed">Playlist loading failed</string>
<string name="time_format">%d:%02d:%02d</string>
<string name="minute_time_format">%d:%02d</string>
</resources>