音乐分类合集进入播放页面

This commit is contained in:
litingting 2024-10-11 18:55:45 +08:00
parent 7fd2da133c
commit 9ca0c2cebf
15 changed files with 320 additions and 104 deletions

View File

@ -2,6 +2,7 @@ package com.hi.music.player.adapter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -23,10 +24,11 @@ import com.hi.music.player.api.onImageColorListener;
import com.hi.music.player.databinding.ItemCategoryListBinding; import com.hi.music.player.databinding.ItemCategoryListBinding;
import com.hi.music.player.databinding.ItemSingerBinding; import com.hi.music.player.databinding.ItemSingerBinding;
import com.hi.music.player.helper.CommonUtils; import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild; import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
import com.hi.music.player.javabean.response.child.ResponseSingle; import com.hi.music.player.javabean.response.child.ResponseSingle;
public class AdapterCategoryList extends BaseAdapter<ResponseCategoryListChild, ItemCategoryListBinding> { public class AdapterCategoryList extends BaseAdapter<ResponsePlayListInfo, ItemCategoryListBinding> {
@Override @Override
protected ItemCategoryListBinding getViewBinding(ViewGroup parent) { protected ItemCategoryListBinding getViewBinding(ViewGroup parent) {
@ -36,7 +38,7 @@ public class AdapterCategoryList extends BaseAdapter<ResponseCategoryListChild,
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
VHolder<ItemCategoryListBinding> itemHolder = (VHolder<ItemCategoryListBinding>) holder; VHolder<ItemCategoryListBinding> itemHolder = (VHolder<ItemCategoryListBinding>) holder;
ResponseCategoryListChild child = data.get(position); ResponsePlayListInfo child = data.get(position);
ItemCategoryListBinding vb = itemHolder.getVb(); ItemCategoryListBinding vb = itemHolder.getVb();
vb.tvSongName.setText(child.getSongTitle()); vb.tvSongName.setText(child.getSongTitle());
@ -45,7 +47,7 @@ public class AdapterCategoryList extends BaseAdapter<ResponseCategoryListChild,
Glide.with(MusicApplication.myApplication) Glide.with(MusicApplication.myApplication)
.asDrawable() .asDrawable()
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(16)))) .apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(16))))
.load(child.getSongCovert()) .load(child.getCovert())
.placeholder(R.mipmap.ic_launcher) .placeholder(R.mipmap.ic_launcher)
.listener(new RequestListener<Drawable>() { .listener(new RequestListener<Drawable>() {
@Override @Override
@ -61,6 +63,13 @@ public class AdapterCategoryList extends BaseAdapter<ResponseCategoryListChild,
} }
}) })
.into(vb.image); .into(vb.image);
vb.getRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
homeItemClickListener.onClickItemCategoryList(child,itemHolder.getAbsoluteAdapterPosition());
}
});
} }

View File

@ -1,11 +1,26 @@
package com.hi.music.player.api; package com.hi.music.player.api;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.child.ResponseCategory; import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.child.ResponseSingle; import com.hi.music.player.javabean.response.child.ResponseSingle;
public interface HomeItemClickListener { public interface HomeItemClickListener {
void onClickItemSinger(ResponseSingle data) ;
void onClickItemCategory(ResponseCategory data) ; //首页点击了单曲
default void onClickItemSinger(ResponseSingle data) {
}
//首页点击了分类合集
default void onClickItemCategory(ResponseCategory data) {
}
//分类合集点击了某一首歌曲
default void onClickItemCategoryList(ResponsePlayListInfo data,int musicIndex) {
}
} }

View File

@ -4,6 +4,10 @@ public class MyValue {
//-----------------------------PlayActivity //-----------------------------PlayActivity
public static String KEY_PLAY_ACTIVITY_SINGER = "click_singer"; public static String KEY_PLAY_ACTIVITY_SINGER = "click_singer";
public static String KEY_PLAY_ACTIVITY_CATEGORY_LIST = "click_category_list";
public static String KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX = "click_category_list_index";
//播放错误 //播放错误
public final static int PLAY_STATUS_CODE_ERROR = -1; public final static int PLAY_STATUS_CODE_ERROR = -1;
@ -15,6 +19,20 @@ public class MyValue {
public final static int PLAY_STATUS_CODE_PAUSE = -3; public final static int PLAY_STATUS_CODE_PAUSE = -3;
/**
* 进入播放页面的来源
* 0--单曲进入 0--单曲进入 0--音乐分类合集列表进入
*/
public static String KEY_ENTER_SOURCE = "ENTER_SOURCE";
public final static int TYPE_ENTER_SOURCE_SINGLE = 0;
public final static int TYPE_ENTER_SOURCE_CATEGORY = 1;
//-----------------------------PlayActivity //-----------------------------PlayActivity

View File

@ -2,16 +2,17 @@ package com.hi.music.player.javabean.response;
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild; import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
import java.io.Serializable;
import java.util.List; import java.util.List;
public class ResponseCategoryList { public class ResponseCategoryList implements Serializable {
private String covert; private String covert;
private String title; private String title;
private String description; private String description;
private String secondSubtitle; private String secondSubtitle;
private List<ResponseCategoryListChild> list; private List<ResponsePlayListInfo> list;
public String getCovert() { public String getCovert() {
@ -46,11 +47,11 @@ public class ResponseCategoryList {
this.secondSubtitle = secondSubtitle; this.secondSubtitle = secondSubtitle;
} }
public List<ResponseCategoryListChild> getList() { public List<ResponsePlayListInfo> getList() {
return list; return list;
} }
public void setList(List<ResponseCategoryListChild> list) { public void setList(List<ResponsePlayListInfo> list) {
this.list = list; this.list = list;
} }
} }

View File

@ -1,6 +1,11 @@
package com.hi.music.player.javabean.response; package com.hi.music.player.javabean.response;
public class ResponsePlayListInfo { import java.io.Serializable;
/**
* 播放列表
*/
public class ResponsePlayListInfo implements Serializable {
//封面 //封面
private String covert; private String covert;
@ -35,11 +40,11 @@ public class ResponsePlayListInfo {
private String musicVideoType; private String musicVideoType;
//
//------------自定义属性由另外接口请求返回的数据流组装 // //------------自定义属性由另外接口请求返回的数据流组装
private String audioUrlLow; // private String audioUrlLow;
//
private String audioUrlMedium; // private String audioUrlMedium;
public String getSmallCovert() { public String getSmallCovert() {
@ -139,19 +144,19 @@ public class ResponsePlayListInfo {
} }
public String getAudioUrlLow() { // public String getAudioUrlLow() {
return audioUrlLow; // return audioUrlLow;
} // }
//
public void setAudioUrlLow(String audioUrlLow) { // public void setAudioUrlLow(String audioUrlLow) {
this.audioUrlLow = audioUrlLow; // this.audioUrlLow = audioUrlLow;
} // }
//
public String getAudioUrlMedium() { // public String getAudioUrlMedium() {
return audioUrlMedium; // return audioUrlMedium;
} // }
//
public void setAudioUrlMedium(String audioUrlMedium) { // public void setAudioUrlMedium(String audioUrlMedium) {
this.audioUrlMedium = audioUrlMedium; // this.audioUrlMedium = audioUrlMedium;
} // }
} }

View File

@ -1,5 +1,9 @@
package com.hi.music.player.javabean.response; package com.hi.music.player.javabean.response;
/**
* 音频源地址
*/
public class ResponsePlayUrl { public class ResponsePlayUrl {
private String status; private String status;
@ -8,6 +12,17 @@ public class ResponsePlayUrl {
private String audioUrlMedium; private String audioUrlMedium;
private String videoId; private String videoId;
private String BigCovert;
public String getBigCovert() {
return BigCovert;
}
public void setBigCovert(String bigCovert) {
BigCovert = bigCovert;
}
public String getAudioUrlMedium() { public String getAudioUrlMedium() {
return audioUrlMedium; return audioUrlMedium;
} }

View File

@ -103,7 +103,7 @@ public class MyMediaControllerManager {
onCallRequestUrl(nextMediaItemIndex, false, new OnHasUrlAction() { onCallRequestUrl(nextMediaItemIndex, false, new OnHasUrlAction() {
@Override @Override
public void onHasUrl() { public void onHasUrl() {
CommonUtils.LogMsg("-------------有有效URl--播放检查下一首 位置="+nextMediaItemIndex ); CommonUtils.LogMsg("-------------有有效URl--播放检查下一首 位置=" + nextMediaItemIndex);
} }
}); });
} }
@ -112,7 +112,7 @@ public class MyMediaControllerManager {
onCallRequestUrl(previousMediaItemIndex, false, new OnHasUrlAction() { onCallRequestUrl(previousMediaItemIndex, false, new OnHasUrlAction() {
@Override @Override
public void onHasUrl() { public void onHasUrl() {
CommonUtils.LogMsg("-------------有有效URl--播放检查上一首 位置="+previousMediaItemIndex ); CommonUtils.LogMsg("-------------有有效URl--播放检查上一首 位置=" + previousMediaItemIndex);
} }
}); });
} }
@ -154,7 +154,7 @@ public class MyMediaControllerManager {
} }
public int getCurIndex(){ public int getCurIndex() {
return mediaController.getCurrentMediaItemIndex(); return mediaController.getCurrentMediaItemIndex();
} }
@ -176,6 +176,14 @@ public class MyMediaControllerManager {
} else { } else {
builder.setUri(playUrl.getAudioUrlLow()); builder.setUri(playUrl.getAudioUrlLow());
} }
//针对于已经从分类合集列表页面进入播放页面的数据(只有小的封面图)
if (mediaItemAt.mediaMetadata.artworkUri == null) {
MediaMetadata.Builder builder1 = mediaItemAt.mediaMetadata.buildUpon();
builder1.setArtworkUri(Uri.parse(playUrl.getBigCovert()));
builder.setMediaMetadata(builder1.build());
}
CharSequence title = mediaController.getMediaItemAt(i).mediaMetadata.title; CharSequence title = mediaController.getMediaItemAt(i).mediaMetadata.title;
CommonUtils.LogMsg("-------------更新播放列表中的音频url= i=" + i + "---id=" + playUrl.getVideoId() + "----mediaController.size=" + mediaController.getMediaItemCount()); CommonUtils.LogMsg("-------------更新播放列表中的音频url= i=" + i + "---id=" + playUrl.getVideoId() + "----mediaController.size=" + mediaController.getMediaItemCount());
mediaController.replaceMediaItem(i, builder.build()); mediaController.replaceMediaItem(i, builder.build());
@ -263,6 +271,7 @@ public class MyMediaControllerManager {
MediaMetadata_builder.setArtist(playInfo.getSingerName()); MediaMetadata_builder.setArtist(playInfo.getSingerName());
MediaMetadata_builder.setDescription(playInfo.getDuration()); MediaMetadata_builder.setDescription(playInfo.getDuration());
MediaMetadata_builder.setDurationMs(playInfo.getDurationMs()); MediaMetadata_builder.setDurationMs(playInfo.getDurationMs());
if (playInfo.getCovert() != null)
MediaMetadata_builder.setArtworkUri(Uri.parse(playInfo.getCovert())); MediaMetadata_builder.setArtworkUri(Uri.parse(playInfo.getCovert()));
MediaMetadata_builder.setTitle(playInfo.getSongTitle()); MediaMetadata_builder.setTitle(playInfo.getSongTitle());
@ -348,24 +357,24 @@ public class MyMediaControllerManager {
} }
stop(); stop();
mediaController.seekTo(index,0); mediaController.seekTo(index, 0);
onCallRequestUrl(index, true, new OnHasUrlAction() { onCallRequestUrl(index, true, new OnHasUrlAction() {
@Override @Override
public void onHasUrl() { public void onHasUrl() {
mediaController.play(); mediaController.play();
CommonUtils.LogMsg("-------------有有效URl--播放指定播放列表位置的歌曲" ); CommonUtils.LogMsg("-------------有有效URl--播放指定播放列表位置的歌曲");
} }
}); });
} }
private void onCallRequestUrl(int index, boolean playNow, OnHasUrlAction action){ private void onCallRequestUrl(int index, boolean playNow, OnHasUrlAction action) {
MediaItem mediaItemAt = mediaController.getMediaItemAt(index); MediaItem mediaItemAt = mediaController.getMediaItemAt(index);
boolean b = CommonUtils.hasValidUri(mediaItemAt); boolean b = CommonUtils.hasValidUri(mediaItemAt);
if (!b) { if (!b) {
CommonUtils.LogMsg("-------------请求URl index"+index+"---playNow="+playNow); CommonUtils.LogMsg("-------------请求URl index" + index + "---playNow=" + playNow);
mListener.onRequestNextUri(mediaItemAt.mediaId, index, playNow); mListener.onRequestNextUri(mediaItemAt.mediaId, index, playNow);
}else { } else {
action.onHasUrl(); action.onHasUrl();
} }
} }

View File

@ -6,7 +6,6 @@ import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.ResponsePlayUrl; import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.javabean.response.child.ResponseCategory; import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.ResponseHome; import com.hi.music.player.javabean.response.ResponseHome;
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
import com.hi.music.player.javabean.response.child.ResponseHomeChild; import com.hi.music.player.javabean.response.child.ResponseHomeChild;
import com.hi.music.player.javabean.response.child.ResponseSingle; import com.hi.music.player.javabean.response.child.ResponseSingle;
@ -15,16 +14,20 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class JsonHelper { public class JsonHelper {
/**
* 解析首页单曲
* @param jsonObject
* @return
*/
public static ResponseHome ResolveHomeJson(JSONObject jsonObject) { public static ResponseHome ResolveHomeJson(JSONObject jsonObject) {
ResponseHome responseHome = new ResponseHome(); ResponseHome responseHome = new ResponseHome();
try { try {
String bgUrl = getJsonUrl(jsonObject.getJSONObject("background"), true); String bgUrl = getCovertUrl(jsonObject.getJSONObject("background"), true);
JSONObject sectionListRenderer = jsonObject.getJSONObject("contents").getJSONObject("singleColumnBrowseResultsRenderer").getJSONArray("tabs").getJSONObject(0).getJSONObject("tabRenderer").getJSONObject("content").getJSONObject("sectionListRenderer"); JSONObject sectionListRenderer = jsonObject.getJSONObject("contents").getJSONObject("singleColumnBrowseResultsRenderer").getJSONArray("tabs").getJSONObject(0).getJSONObject("tabRenderer").getJSONObject("content").getJSONObject("sectionListRenderer");
@ -48,6 +51,11 @@ public class JsonHelper {
} }
/**
* 解析首页不同类型的音乐分类
* @param jsonObject
* @return
*/
public static ResponseHome ResolveHomeMoreJson(JSONObject jsonObject) { public static ResponseHome ResolveHomeMoreJson(JSONObject jsonObject) {
ResponseHome responseHome = new ResponseHome(); ResponseHome responseHome = new ResponseHome();
try { try {
@ -68,7 +76,11 @@ public class JsonHelper {
return responseHome; return responseHome;
} }
/**
* 解析根据单曲获取的播放列表
* @param jsonObject
* @return
*/
public static List<ResponsePlayListInfo> ResolvePlayListJson(JSONObject jsonObject) { public static List<ResponsePlayListInfo> ResolvePlayListJson(JSONObject jsonObject) {
List<ResponsePlayListInfo> list = new ArrayList<>(); List<ResponsePlayListInfo> list = new ArrayList<>();
try { try {
@ -80,9 +92,9 @@ public class JsonHelper {
ResponsePlayListInfo responsePlayListInfo = new ResponsePlayListInfo(); ResponsePlayListInfo responsePlayListInfo = new ResponsePlayListInfo();
JSONObject playlistPanelVideoRenderer = contents.getJSONObject(i).getJSONObject("playlistPanelVideoRenderer"); JSONObject playlistPanelVideoRenderer = contents.getJSONObject(i).getJSONObject("playlistPanelVideoRenderer");
String maxUrl = getJsonUrl(playlistPanelVideoRenderer, true); String maxUrl = getCovertUrl(playlistPanelVideoRenderer, true);
String smallUrl = getJsonUrl(playlistPanelVideoRenderer, false); String smallUrl = getCovertUrl(playlistPanelVideoRenderer, false);
String songName = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("title"), 0); String songName = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("title"), 0);
@ -123,7 +135,11 @@ public class JsonHelper {
} }
return list; return list;
} }
/**
* 解析音乐音频源地址
* @param jsonObject
* @return
*/
public static ResponsePlayUrl ResolvePlayUrlJson(JSONObject jsonObject) { public static ResponsePlayUrl ResolvePlayUrlJson(JSONObject jsonObject) {
try { try {
ResponsePlayUrl responsePlayUrl = new ResponsePlayUrl(); ResponsePlayUrl responsePlayUrl = new ResponsePlayUrl();
@ -151,12 +167,16 @@ public class JsonHelper {
} }
JSONObject videoDetails = jsonObject.getJSONObject("videoDetails");
String videoId = jsonObject.getJSONObject("videoDetails").getString("videoId"); String videoId = videoDetails.getString("videoId");
JSONArray thumbnails = videoDetails.getJSONObject("thumbnail").getJSONArray("thumbnails");
String url = thumbnails.getJSONObject(thumbnails.length() - 1).getString("url");
responsePlayUrl.setBigCovert(url);
responsePlayUrl.setVideoId(videoId); responsePlayUrl.setVideoId(videoId);
responsePlayUrl.setStatus(status); responsePlayUrl.setStatus(status);
return responsePlayUrl; return responsePlayUrl;
@ -168,9 +188,11 @@ public class JsonHelper {
} }
/**
* 解析音乐分类合集列表
* @param jsonObject
* @return
*/
public static ResponseCategoryList ResolveCategoryList(JSONObject jsonObject) { public static ResponseCategoryList ResolveCategoryList(JSONObject jsonObject) {
try { try {
ResponseCategoryList responseCategoryList = new ResponseCategoryList(); ResponseCategoryList responseCategoryList = new ResponseCategoryList();
@ -187,7 +209,7 @@ public class JsonHelper {
.getJSONObject("musicResponsiveHeaderRenderer"); .getJSONObject("musicResponsiveHeaderRenderer");
//封面图 //封面图
String covert = getJsonUrl(musicResponsiveHeaderRenderer.getJSONObject("thumbnail") String covert = getCovertUrl(musicResponsiveHeaderRenderer.getJSONObject("thumbnail")
.getJSONObject("musicThumbnailRenderer"), true); .getJSONObject("musicThumbnailRenderer"), true);
@ -215,43 +237,46 @@ public class JsonHelper {
responseCategoryList.setDescription(description); responseCategoryList.setDescription(description);
responseCategoryList.setTitle(title); responseCategoryList.setTitle(title);
responseCategoryList.setSecondSubtitle(secondSubtitle); responseCategoryList.setSecondSubtitle(secondSubtitle);
List<ResponseCategoryListChild> mList = new ArrayList<>(); List<ResponsePlayListInfo> mList = new ArrayList<>();
for(int i = 0;i<jsonArray.length();i++){ for(int i = 0;i<jsonArray.length();i++){
JSONObject arrayJSONObject = jsonArray.getJSONObject(i).getJSONObject("musicResponsiveListItemRenderer"); JSONObject arrayJSONObject = jsonArray.getJSONObject(i).getJSONObject("musicResponsiveListItemRenderer");
String duration = getJsonTitle(arrayJSONObject.getJSONArray("fixedColumns").getJSONObject(0).getJSONObject("musicResponsiveListItemFixedColumnRenderer").getJSONObject("text"), 0); String duration = getJsonTitle(arrayJSONObject.getJSONArray("fixedColumns").getJSONObject(0).getJSONObject("musicResponsiveListItemFixedColumnRenderer").getJSONObject("text"), 0);
long ms = CommonUtils.convertToMilliseconds(duration);
String thumbnail = getJsonUrl(arrayJSONObject.getJSONObject("thumbnail"), true); String thumbnail = getCovertUrl(arrayJSONObject.getJSONObject("thumbnail"), true);
JSONArray flexColumns = arrayJSONObject JSONArray flexColumns = arrayJSONObject
.getJSONArray("flexColumns"); .getJSONArray("flexColumns");
ResponsePlayListInfo child = new ResponsePlayListInfo();
//歌名歌手名字描述 //歌名歌手名字描述
String SongTitle = ""; String SongTitle = "";
String SingerName = ""; String SingerName = "";
String Description = ""; String Description = "";
for (int g = 0; g < flexColumns.length(); g++) { for (int g = 0; g < flexColumns.length(); g++) {
String text = getJsonTitle(flexColumns.getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text"), 0); JSONObject jsonObjectText = flexColumns.getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text");
String text = getJsonTitle(jsonObjectText, 0);
if (g == 0) { if (g == 0) {
SongTitle = text; SongTitle = text;
// JSONObject runs = jsonObject.getJSONArray("runs").getJSONObject(0); JSONObject runs = jsonObjectText.getJSONArray("runs").getJSONObject(0);
// String[] watchEndPoint = getWatchEndPoint(runs); String[] watchEndPoint = getWatchEndPoint(runs);
//
// responseSingle.setVideoId(watchEndPoint[0]); child.setVideoId(watchEndPoint[0]);
// responseSingle.setPlaylistId(watchEndPoint[1]); child.setPlaylistId(watchEndPoint[1]);
// responseSingle.setParams(watchEndPoint[2]); child.setParams(watchEndPoint[2]);
// responseSingle.setMusicVideoType(watchEndPoint[3]); child.setMusicVideoType(watchEndPoint[3]);
} }
if (g == 1) SingerName = text; if (g == 1) SingerName = text;
if (g == 2) Description = text; if (g == 2) Description = text;
} }
ResponseCategoryListChild child = new ResponseCategoryListChild();
child.setSongCovert(thumbnail); child.setSmallCovert(thumbnail);
child.setSongDuration(duration); // child.setCovert(thumbnail);
child.setDuration(duration);
child.setDurationMs(ms);
child.setSingerName(SingerName); child.setSingerName(SingerName);
child.setSongTitle(SongTitle); child.setSongTitle(SongTitle);
mList.add(child); mList.add(child);
@ -323,7 +348,7 @@ public class JsonHelper {
if (musicResponsiveListItemRenderer != null) { if (musicResponsiveListItemRenderer != null) {
ResponseSingle responseSingle = new ResponseSingle(); ResponseSingle responseSingle = new ResponseSingle();
String SingerHead = getJsonUrl(musicResponsiveListItemRenderer.getJSONObject("thumbnail"), true); String SingerHead = getCovertUrl(musicResponsiveListItemRenderer.getJSONObject("thumbnail"), true);
JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns"); JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns");
@ -362,7 +387,7 @@ public class JsonHelper {
JSONObject musicTwoRowItemRenderer = jsonList.optJSONObject("musicTwoRowItemRenderer"); JSONObject musicTwoRowItemRenderer = jsonList.optJSONObject("musicTwoRowItemRenderer");
if (musicTwoRowItemRenderer != null) { if (musicTwoRowItemRenderer != null) {
ResponseCategory responseCategory = new ResponseCategory(); ResponseCategory responseCategory = new ResponseCategory();
String covert = getJsonUrl(musicTwoRowItemRenderer.getJSONObject("thumbnailRenderer"), true); String covert = getCovertUrl(musicTwoRowItemRenderer.getJSONObject("thumbnailRenderer"), true);
JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title"); JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title");
String twoTitle = getJsonTitle(title1, 0); String twoTitle = getJsonTitle(title1, 0);
@ -433,7 +458,7 @@ public class JsonHelper {
* @param maxBig 是否取最大的一张图片 * @param maxBig 是否取最大的一张图片
* @return * @return
*/ */
private static String getJsonUrl(JSONObject jsonObject, boolean maxBig) { private static String getCovertUrl(JSONObject jsonObject, boolean maxBig) {
try { try {
boolean b = jsonObject.has("musicThumbnailRenderer"); boolean b = jsonObject.has("musicThumbnailRenderer");
if (b) { if (b) {

View File

@ -45,7 +45,7 @@ public interface MusicApi {
//获取播放音频资源url //获取播放音频资源url
@POST("youtubei/v1/player?prettyPrint=false") @POST("youtubei/v1/player?prettyPrint=false")
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8", @Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
"X-Goog-FieldMask:playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId"}) "X-Goog-FieldMask:playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId,videoDetails.thumbnail"})
Observable<ResponseBody> getMusicPlayUrl(@Body RequestBody requestBody); Observable<ResponseBody> getMusicPlayUrl(@Body RequestBody requestBody);

View File

@ -27,13 +27,17 @@ import com.bumptech.glide.request.target.Target;
import com.hi.music.player.MusicApplication; import com.hi.music.player.MusicApplication;
import com.hi.music.player.R; import com.hi.music.player.R;
import com.hi.music.player.adapter.AdapterCategoryList; import com.hi.music.player.adapter.AdapterCategoryList;
import com.hi.music.player.api.HomeItemClickListener;
import com.hi.music.player.api.onImageColorListener; import com.hi.music.player.api.onImageColorListener;
import com.hi.music.player.databinding.ActivityCategoryListBinding; import com.hi.music.player.databinding.ActivityCategoryListBinding;
import com.hi.music.player.databinding.ActivityHomeBinding; import com.hi.music.player.databinding.ActivityHomeBinding;
import com.hi.music.player.helper.CommonUtils; import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue; import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.response.ResponseCategoryList; import com.hi.music.player.javabean.response.ResponseCategoryList;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.child.ResponseCategory; import com.hi.music.player.javabean.response.child.ResponseCategory;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import com.hi.music.player.ui.fragmnt.viewmodel.VMCategoryList; import com.hi.music.player.ui.fragmnt.viewmodel.VMCategoryList;
import com.hi.music.player.ui.fragmnt.viewmodel.VMHome; import com.hi.music.player.ui.fragmnt.viewmodel.VMHome;
@ -41,10 +45,13 @@ import java.io.Serializable;
import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.BlurTransformation;
public class CategoryListActivity extends BaseActivity<ActivityCategoryListBinding> { public class CategoryListActivity extends BaseActivity<ActivityCategoryListBinding> implements HomeItemClickListener {
private VMCategoryList vm; private VMCategoryList vm;
private VMApplication vmApplication;
private ResponseCategoryList mCategoryList;
@Override @Override
protected ActivityCategoryListBinding getViewBinding() { protected ActivityCategoryListBinding getViewBinding() {
@ -54,6 +61,7 @@ public class CategoryListActivity extends BaseActivity<ActivityCategoryListBindi
@Override @Override
protected void onCreateInit() { protected void onCreateInit() {
vm = getActivityScopeViewModel(VMCategoryList.class); vm = getActivityScopeViewModel(VMCategoryList.class);
vmApplication = getApplicationScopeViewModel(VMApplication.class);
Intent intent = getIntent(); Intent intent = getIntent();
if (intent == null) { if (intent == null) {
@ -76,8 +84,8 @@ public class CategoryListActivity extends BaseActivity<ActivityCategoryListBindi
return; return;
} }
mCategoryList = responseCategoryList;
loadInfo(responseCategoryList); loadInfo(mCategoryList);
} }
}); });
@ -86,6 +94,7 @@ public class CategoryListActivity extends BaseActivity<ActivityCategoryListBindi
@Override @Override
protected void onInitClick() { protected void onInitClick() {
vb.imBack.setOnClickListener(this); vb.imBack.setOnClickListener(this);
vb.btnPlay.setOnClickListener(this);
} }
@Override @Override
@ -102,16 +111,23 @@ public class CategoryListActivity extends BaseActivity<ActivityCategoryListBindi
public void onClick(View v) { public void onClick(View v) {
if (v.equals(vb.imBack)) { if (v.equals(vb.imBack)) {
finish(); finish();
} else if (v.equals(vb.btnPlay)) {
int musicIndex = 0;
Intent intent = new Intent(this, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST, mCategoryList.getList().get(musicIndex));
// intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX,musicIndex);
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_CATEGORY);
startActivity(intent);
vmApplication.reSetPlayList(mCategoryList.getList());
} }
} }
private void loadInfo(ResponseCategoryList info) { private void loadInfo(ResponseCategoryList info) {
vb.tvTitle.setText(info.getTitle()); vb.tvTitle.setText(info.getTitle());
vb.tvSubTitle.setText(info.getSecondSubtitle()); vb.tvSubTitle.setText(info.getDescription());
AdapterCategoryList adapterCategoryList = new AdapterCategoryList(); AdapterCategoryList adapterCategoryList = new AdapterCategoryList();
adapterCategoryList.setHomeItemClickListener(this);
vb.recyclerview.setLayoutManager(new LinearLayoutManager(this)); vb.recyclerview.setLayoutManager(new LinearLayoutManager(this));
adapterCategoryList.setData(info.getList()); adapterCategoryList.setData(info.getList());
vb.recyclerview.setAdapter(adapterCategoryList); vb.recyclerview.setAdapter(adapterCategoryList);
@ -175,4 +191,14 @@ public class CategoryListActivity extends BaseActivity<ActivityCategoryListBindi
} }
@Override
public void onClickItemCategoryList(ResponsePlayListInfo data, int musicIndex) {
Intent intent = new Intent(this, PlayActivity.class);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST, data);
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, musicIndex);
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_CATEGORY);
startActivity(intent);
vmApplication.reSetPlayList(mCategoryList.getList());
}
} }

View File

@ -43,6 +43,7 @@ import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.ResponsePlayUrl; import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.javabean.response.child.ResponseSingle; import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.media3.MyMediaControllerManager; import com.hi.music.player.media3.MyMediaControllerManager;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
import com.hi.music.player.ui.activity.viewmodel.VMPlay; import com.hi.music.player.ui.activity.viewmodel.VMPlay;
import java.util.List; import java.util.List;
@ -50,9 +51,12 @@ import java.util.List;
public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements SeekBar.OnSeekBarChangeListener { public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements SeekBar.OnSeekBarChangeListener {
//单曲进入传递的数据
private ResponseSingle responseSingle; private ResponseSingle responseSingle;
private VMPlay vmPlay; private VMPlay vmPlay;
private VMApplication vmApplication;
//接口返回的播放列表(没有音频数据) //接口返回的播放列表(没有音频数据)
private List<ResponsePlayListInfo> mPlayList; private List<ResponsePlayListInfo> mPlayList;
@ -79,6 +83,14 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
// 请求失败的立即播放的歌曲信息 // 请求失败的立即播放的歌曲信息
private CustomerUrlInfo mCustomerUrlInfo; private CustomerUrlInfo mCustomerUrlInfo;
private int mEnterType;
//-------单曲进入播放列表接口请求需要的参数
private String playlistId, videoId, params, musicVideoType;
//-------单曲进入播放列表接口请求需要的参数
private int mDefaultPlayStartIndex = 0;
@Override @Override
protected ActivityPlayBinding getViewBinding() { protected ActivityPlayBinding getViewBinding() {
@ -87,28 +99,55 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
@Override @Override
protected void onCreateInit() { protected void onCreateInit() {
Intent intent = getIntent();
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
vmPlay = getActivityScopeViewModel(VMPlay.class); vmPlay = getActivityScopeViewModel(VMPlay.class);
vmApplication = getApplicationScopeViewModel(VMApplication.class);
initMediaController(); initMediaController();
vb.progressBarLoading.setVisibility(View.VISIBLE); vb.progressBarLoading.setVisibility(View.VISIBLE);
vmPlay.getPlayMusicList(responseSingle);
initPlayerView();
Intent intent = getIntent();
mEnterType = intent.getIntExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_SINGLE);
switch (mEnterType) {
case MyValue.TYPE_ENTER_SOURCE_SINGLE:
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
playlistId = responseSingle.getPlaylistId();
videoId = responseSingle.getVideoId();
params = responseSingle.getParams();
musicVideoType = responseSingle.getMusicVideoType();
vmPlay.getPlayMusicList(playlistId,videoId,params,musicVideoType);
vmPlay.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
@Override
public void onChanged(List<ResponsePlayListInfo> listInfos) {
vmApplication.reSetPlayList(listInfos);
}
});
break;
case MyValue.TYPE_ENTER_SOURCE_CATEGORY:
ResponsePlayListInfo playListInfo = (ResponsePlayListInfo) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST);
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX,mDefaultPlayStartIndex);
videoId = playListInfo.getVideoId();
CommonUtils.LogMsg("--------更新---videoId="+videoId);
break;
}
initPlayerView();
initProgressHandler(); initProgressHandler();
vmPlay.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() { vmApplication.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
@Override @Override
public void onChanged(List<ResponsePlayListInfo> playList) { public void onChanged(List<ResponsePlayListInfo> playList) {
if (playList == null) { if (playList == null) {
CommonUtils.LogErrorMsg("---------playList = null"); CommonUtils.LogErrorMsg("--------更新-playList null");
netError = 0; netError = 0;
vb.linearRetry.setVisibility(View.VISIBLE); vb.linearRetry.setVisibility(View.VISIBLE);
return; return;
} }
CommonUtils.LogMsg("--------更新-playList " + playList.size()+"--videoId="+videoId);
if (playList.size() > 0) { if (playList.size() > 0) {
mPlayList = playList; mPlayList = playList;
musicInfo = playList.get(0); musicInfo = playList.get(0);
setPlayListAndGetUrl(playList, videoId, mDefaultPlayStartIndex);
} }
} }
@ -139,6 +178,19 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
}); });
} }
/**
* 设置播放列表并请求当前需要播放的音乐url
*
* @param list
* @param id
* @param index
*/
private void setPlayListAndGetUrl(List<ResponsePlayListInfo> list, String id, int index) {
MyMediaControllerManager.getInstance().setPlayList(list);
vmPlay.getPlayUrl(id, index, true);
}
@OptIn(markerClass = UnstableApi.class) @OptIn(markerClass = UnstableApi.class)
private void initPlayerView() { private void initPlayerView() {
vb.playerView.setShowRewindButton(false); vb.playerView.setShowRewindButton(false);
@ -148,13 +200,13 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
private void initMediaController() { private void initMediaController() {
mediaControllerManager = MyMediaControllerManager.getInstance(); mediaControllerManager = MyMediaControllerManager.getInstance();
String videoId = responseSingle.getVideoId(); // String videoId = responseSingle.getVideoId();
MediaItem currentMediaItem = mediaControllerManager.getMediaController().getCurrentMediaItem(); MediaItem currentMediaItem = mediaControllerManager.getMediaController().getCurrentMediaItem();
if (currentMediaItem != null) { if (currentMediaItem != null) {
if (currentMediaItem.mediaId.equals(videoId)) { // if (currentMediaItem.mediaId.equals(videoId)) {
// TODO: 2024/9/27 正在播放当前歌曲又点进来 // TODO: 2024/9/27 正在播放当前歌曲又点进来
// mediaControllerManager.getMediaController().seekTo(0); // mediaControllerManager.getMediaController().seekTo(0);
} // }
if (mediaControllerManager.getMediaController().isPlaying()) { if (mediaControllerManager.getMediaController().isPlaying()) {
mediaControllerManager.stop(); mediaControllerManager.stop();
} }
@ -390,9 +442,15 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
adapterPlayList.updateCurMusicAnimation(); adapterPlayList.updateCurMusicAnimation();
} }
} else if (v.equals(vb.tvRetry)) { } else if (v.equals(vb.tvRetry)) {
//重试按钮
vb.linearRetry.setVisibility(View.GONE); vb.linearRetry.setVisibility(View.GONE);
if (netError == 0) { if (netError == 0) {
vmPlay.getPlayMusicList(responseSingle); switch (mEnterType){
case MyValue.TYPE_ENTER_SOURCE_SINGLE:
vmPlay.getPlayMusicList(playlistId,videoId,params,musicVideoType);
break;
}
} else { } else {
if (mCustomerUrlInfo != null) { if (mCustomerUrlInfo != null) {
vmPlay.getPlayUrl(mCustomerUrlInfo.getVideoId(), mCustomerUrlInfo.getPlayMusicIndex(), true); vmPlay.getPlayUrl(mCustomerUrlInfo.getVideoId(), mCustomerUrlInfo.getPlayMusicIndex(), true);

View File

@ -0,0 +1,45 @@
package com.hi.music.player.ui.activity.viewmodel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.hi.music.player.api.RequestListener;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.CustomerUrlInfo;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.javabean.response.child.ResponseSingle;
import com.hi.music.player.media3.MyMediaControllerManager;
import com.hi.music.player.network.JsonHelper;
import com.hi.music.player.network.RetrofitManager;
import org.json.JSONObject;
import java.util.List;
import okhttp3.ResponseBody;
public class VMApplication extends ViewModel {
private MutableLiveData<List<ResponsePlayListInfo>> _playList = new MutableLiveData<List<ResponsePlayListInfo>>();
public LiveData<List<ResponsePlayListInfo>> playList = _playList;
private MutableLiveData<CustomerUrlInfo> _playUrlMutableLiveData = new MutableLiveData<CustomerUrlInfo>();
public LiveData<CustomerUrlInfo> playUrlLiveData = _playUrlMutableLiveData;
/**
* 重置播放列表
* @param list
*/
public void reSetPlayList(List<ResponsePlayListInfo> list) {
_playList.setValue(list);
}
}

View File

@ -32,11 +32,7 @@ public class VMPlay extends ViewModel {
public void getPlayMusicList(ResponseSingle responseSingle) { public void getPlayMusicList(String playlistId, String videoId, String params, String musicVideoType) {
String playlistId = responseSingle.getPlaylistId();
String videoId = responseSingle.getVideoId();
String params = responseSingle.getParams();
String musicVideoType = responseSingle.getMusicVideoType();
RetrofitManager.getInstance().getPlayList(params, playlistId, videoId, musicVideoType, new RequestListener<ResponseBody>() { RetrofitManager.getInstance().getPlayList(params, playlistId, videoId, musicVideoType, new RequestListener<ResponseBody>() {
@Override @Override
@ -50,9 +46,7 @@ public class VMPlay extends ViewModel {
JSONObject jsonObject = CommonUtils.toJsonObject(data); JSONObject jsonObject = CommonUtils.toJsonObject(data);
if (jsonObject != null) { if (jsonObject != null) {
List<ResponsePlayListInfo> responsePlayListInfos = JsonHelper.ResolvePlayListJson(jsonObject); List<ResponsePlayListInfo> responsePlayListInfos = JsonHelper.ResolvePlayListJson(jsonObject);
MyMediaControllerManager.getInstance().setPlayList(responsePlayListInfos);
_playList.setValue(responsePlayListInfos); _playList.setValue(responsePlayListInfos);
getPlayUrl(responseSingle.getVideoId(),0,true);
} else { } else {
_playList.setValue(null); _playList.setValue(null);
} }

View File

@ -17,8 +17,6 @@ import org.json.JSONObject;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
public class VMCategoryList extends ViewModel { public class VMCategoryList extends ViewModel {
private MutableLiveData<ResponseCategoryList> _data = new MutableLiveData<>(); private MutableLiveData<ResponseCategoryList> _data = new MutableLiveData<>();
public LiveData<ResponseCategoryList> data = _data; public LiveData<ResponseCategoryList> data = _data;
@ -40,8 +38,6 @@ public class VMCategoryList extends ViewModel {
} }
} }
}); });
} }

View File

@ -65,7 +65,7 @@
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="21sp" />
<TextView <TextView
android:id="@+id/tvSubTitle" android:id="@+id/tvSubTitle"
@ -79,8 +79,8 @@
<ImageView <ImageView
android:id="@+id/btn_play" android:id="@+id/btn_play"
android:layout_width="66dp" android:layout_width="55dp"
android:layout_height="66dp" android:layout_height="55dp"
android:layout_below="@id/tvSubTitle" android:layout_below="@id/tvSubTitle"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"