播放页面Ui
This commit is contained in:
parent
7f065a1835
commit
96eecd07e7
@ -59,6 +59,8 @@ dependencies {
|
||||
|
||||
//----------media3
|
||||
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
||||
implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
|
||||
implementation("androidx.media3:media3-session:1.4.1")
|
||||
implementation("androidx.media3:media3-ui:1.4.1")
|
||||
//----------media3
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.hi.music.player.api;
|
||||
|
||||
public interface MediaControllerListener {
|
||||
|
||||
|
||||
void onMediaControllerComplete(boolean isOk);
|
||||
|
||||
void onPlayStatus(int playStatus);
|
||||
}
|
||||
@ -62,4 +62,22 @@ public class CommonUtils {
|
||||
}
|
||||
return statusBarHeight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//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]);
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
package com.hi.music.player.javabean.requestbody;
|
||||
|
||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* 首页接口请求体
|
||||
*/
|
||||
public class BodyPlayUrl implements Serializable {
|
||||
|
||||
private String videoId ;
|
||||
|
||||
private ContextBody context = new ContextBody();
|
||||
|
||||
|
||||
|
||||
|
||||
public String getVideoId() {
|
||||
return videoId;
|
||||
}
|
||||
|
||||
public void setVideoId(String videoId) {
|
||||
this.videoId = videoId;
|
||||
}
|
||||
|
||||
public ContextBody getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(ContextBody context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -7,6 +7,13 @@ public class ContextBody {
|
||||
|
||||
private Client client = new Client();
|
||||
|
||||
private ThirdParty thirdParty = new ThirdParty();
|
||||
|
||||
|
||||
public ThirdParty getThirdParty() {
|
||||
return thirdParty;
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
return client;
|
||||
}
|
||||
@ -16,7 +23,7 @@ public class ContextBody {
|
||||
}
|
||||
|
||||
|
||||
public class Client implements Serializable {
|
||||
public static class Client implements Serializable {
|
||||
private String clientName = "WEB_REMIX";
|
||||
private String clientVersion = "1.20220918";
|
||||
private String hl = Locale.getDefault().getLanguage();
|
||||
@ -32,5 +39,27 @@ public class ContextBody {
|
||||
public void setVisitorData(String visitorData) {
|
||||
this.visitorData = visitorData;
|
||||
}
|
||||
|
||||
|
||||
public void setClientName(String clientName) {
|
||||
this.clientName = clientName;
|
||||
}
|
||||
|
||||
public void setClientVersion(String clientVersion) {
|
||||
this.clientVersion = clientVersion;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ThirdParty{
|
||||
//https://www.youtube.com/watch?v=UqyT8IEBkvY
|
||||
private String embedUrl;
|
||||
|
||||
public void setEmbedUrl(String embedUrl) {
|
||||
this.embedUrl = embedUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public class ResponseHome {
|
||||
private String continuation;
|
||||
|
||||
@Nullable
|
||||
//用于更多数据请求的visitorData(只有第一个接口会返回该值)
|
||||
//用于更多数据请求的visitorData(只有第一个接口会返回该值,youtubei/v1/browse?prettyPrint=false)
|
||||
private String visitorData;
|
||||
|
||||
@Nullable
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package com.hi.music.player.javabean.response;
|
||||
|
||||
public class ResponsePlay {
|
||||
public class ResponsePlayListInfo {
|
||||
|
||||
//封面
|
||||
private String covert;
|
||||
@ -20,11 +20,22 @@ public class ResponsePlay {
|
||||
private String Duration;
|
||||
|
||||
|
||||
//歌曲时长 毫秒
|
||||
private long DurationMs;
|
||||
|
||||
|
||||
private String videoId;
|
||||
private String playlistId;
|
||||
private String params;
|
||||
private String musicVideoType;
|
||||
|
||||
public long getDurationMs() {
|
||||
return DurationMs;
|
||||
}
|
||||
|
||||
public void setDurationMs(long durationMs) {
|
||||
DurationMs = durationMs;
|
||||
}
|
||||
|
||||
public String getDuration() {
|
||||
return Duration;
|
||||
@ -0,0 +1,55 @@
|
||||
package com.hi.music.player.javabean.response;
|
||||
|
||||
public class ResponsePlayUrl {
|
||||
|
||||
private String status;
|
||||
private String audioUrlLow;
|
||||
|
||||
private String audioUrlMedium;
|
||||
private String videoId;
|
||||
|
||||
public String getAudioUrlMedium() {
|
||||
return audioUrlMedium;
|
||||
}
|
||||
|
||||
public void setAudioUrlMedium(String audioUrlMedium) {
|
||||
this.audioUrlMedium = audioUrlMedium;
|
||||
}
|
||||
|
||||
|
||||
///AUDIO_QUALITY_MEDIUM、AUDIO_QUALITY_LOW
|
||||
// private String audioQuality;
|
||||
//
|
||||
//
|
||||
// public String getAudioQuality() {
|
||||
// return audioQuality;
|
||||
// }
|
||||
//
|
||||
// public void setAudioQuality(String audioQuality) {
|
||||
// this.audioQuality = audioQuality;
|
||||
// }
|
||||
|
||||
public String getVideoId() {
|
||||
return videoId;
|
||||
}
|
||||
|
||||
public void setVideoId(String videoId) {
|
||||
this.videoId = videoId;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getAudioUrlLow() {
|
||||
return audioUrlLow;
|
||||
}
|
||||
|
||||
public void setAudioUrlLow(String audioUrlLow) {
|
||||
this.audioUrlLow = audioUrlLow;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.hi.music.player.media3;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.ui.PlayerControlView;
|
||||
|
||||
@UnstableApi
|
||||
public class MyControllerView extends PlayerControlView{
|
||||
public MyControllerView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
@ -2,16 +2,22 @@ package com.hi.music.player.media3;
|
||||
|
||||
import android.content.ComponentName;
|
||||
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.common.PlaybackException;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.session.MediaController;
|
||||
import androidx.media3.session.SessionToken;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
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.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponsePlay;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
||||
import com.hi.music.player.network.RetrofitManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -34,7 +40,7 @@ public class MyMediaControllerManager {
|
||||
return myMediaControllerManagerInstance;
|
||||
}
|
||||
|
||||
public void init(){
|
||||
public void init(MediaControllerListener mediaControllerListener){
|
||||
SessionToken sessionToken =
|
||||
new SessionToken(MusicApplication.myApplication, new ComponentName(MusicApplication.myApplication, PlaybackService.class));
|
||||
ListenableFuture<MediaController> controllerFuture =
|
||||
@ -46,8 +52,30 @@ public class MyMediaControllerManager {
|
||||
// playerView.setPlayer(controllerFuture.get());
|
||||
try {
|
||||
mediaController = controllerFuture.get();
|
||||
mediaController.addListener(new Player.Listener() {
|
||||
@Override
|
||||
public void onPlayerError(PlaybackException error) {
|
||||
CommonUtils.LogMsg("=-----PlaybackException+"+error.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaybackStateChanged(int playbackState) {
|
||||
CommonUtils.LogMsg("=-----playbackState+"+playbackState);
|
||||
mediaControllerListener.onPlayStatus(playbackState);
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {
|
||||
// 快进、快退等操作
|
||||
CommonUtils.LogMsg("=-----newPosition+"+newPosition.positionMs);
|
||||
// mediaControllerListener.onPlayStatus(playbackState);
|
||||
}
|
||||
});
|
||||
mediaControllerListener.onMediaControllerComplete(true);
|
||||
CommonUtils.LogMsg("=-----mediaController+"+mediaController);
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
CommonUtils.LogErrorMsg(e.getMessage());
|
||||
mediaControllerListener.onMediaControllerComplete(false);
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
|
||||
@ -55,17 +83,33 @@ public class MyMediaControllerManager {
|
||||
|
||||
}
|
||||
|
||||
public void addMusicPlay(ResponsePlay responsePlay){
|
||||
public MediaController getMediaController() {
|
||||
return mediaController;
|
||||
}
|
||||
|
||||
|
||||
public long getContentPos() {
|
||||
return mediaController.getContentPosition();
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
public void addMusicPlay(ResponsePlayListInfo playInfo, ResponsePlayUrl responsePlay){
|
||||
List<MediaItem> mediaItems = new ArrayList<>();
|
||||
MediaItem.Builder builder = new MediaItem.Builder();
|
||||
builder.setUri(responsePlay.getVideoId());
|
||||
if(responsePlay.getAudioUrlMedium()!= null){
|
||||
builder.setUri(responsePlay.getAudioUrlMedium());
|
||||
}else {
|
||||
builder.setUri(responsePlay.getAudioUrlLow());
|
||||
}
|
||||
|
||||
builder.setMediaId(responsePlay.getVideoId());
|
||||
MediaMetadata.Builder MediaMetadata_builder = new MediaMetadata.Builder();
|
||||
// MediaMetadata_builder.setMediaType();
|
||||
// MediaMetadata_builder.setAlbumTitle();
|
||||
// MediaMetadata_builder.setArtist();
|
||||
// MediaMetadata_builder.setDurationMs();
|
||||
// MediaMetadata_builder.setTitle();
|
||||
// MediaMetadata_builder.setRecordingYear();
|
||||
|
||||
MediaMetadata_builder.setArtist(playInfo.getSingerName());
|
||||
// MediaMetadata_builder.setDurationMs( );
|
||||
MediaMetadata_builder.setAlbumArtist(playInfo.getCovert());
|
||||
MediaMetadata_builder.setTitle(playInfo.getSongTitle());
|
||||
// MediaMetadata_builder.setRecordingYear(Integer.parseInt(playInfo.getYear()));
|
||||
builder.setMediaMetadata(MediaMetadata_builder.build());
|
||||
|
||||
mediaItems.add(builder.build());
|
||||
@ -76,4 +120,6 @@ public class MyMediaControllerManager {
|
||||
public void play(){
|
||||
mediaController.play();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,27 +1,83 @@
|
||||
package com.hi.music.player.media3;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.AudioAttributes;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
|
||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||
import androidx.media3.exoplayer.source.MediaSource;
|
||||
import androidx.media3.session.MediaSession;
|
||||
import androidx.media3.session.MediaSessionService;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PlaybackService extends MediaSessionService {
|
||||
private MediaSession mediaSession = null;
|
||||
private ExoPlayer player;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
ExoPlayer player = new ExoPlayer.Builder(this).build();
|
||||
mediaSession = new MediaSession.Builder(this, player).build();
|
||||
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.DEFAULT.usage)
|
||||
.setContentType(AudioAttributes.DEFAULT.contentType)
|
||||
.build();
|
||||
|
||||
// MediaSource.Factory mediaSourceFactory =
|
||||
// new DefaultMediaSourceFactory(context)
|
||||
// .setDataSourceFactory(cacheDataSourceFactory)
|
||||
// .setLocalAdInsertionComponents(adsLoaderProvider);
|
||||
|
||||
player = new ExoPlayer.Builder(this)
|
||||
.setWakeMode(C.WAKE_MODE_LOCAL)
|
||||
// .setMediaSourceFactory(mediaSourceFactory)
|
||||
.setAudioAttributes(audioAttributes, true).build();
|
||||
|
||||
mediaSession = new MediaSession.Builder(this, player).setCallback(new MediaSession.Callback() {
|
||||
@Override
|
||||
public ListenableFuture<List<MediaItem>> onAddMediaItems(MediaSession mediaSession, MediaSession.ControllerInfo controller, List<MediaItem> mediaItems) {
|
||||
|
||||
CommonUtils.LogMsg("--------mediaItems="+mediaItems.get(0).mediaMetadata.title);
|
||||
// player.addMediaItems(mediaItems);
|
||||
|
||||
return MediaSession.Callback.super.onAddMediaItems(mediaSession, controller, mediaItems);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
|
||||
return mediaSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskRemoved(@Nullable Intent rootIntent) {
|
||||
Player player = mediaSession.getPlayer();
|
||||
// if (player.getPlayWhenReady()) {
|
||||
// // Make sure the service is not in foreground.
|
||||
// player.pause();
|
||||
// }
|
||||
// stopSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
mediaSession.getPlayer().release();
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
package com.hi.music.player.network;
|
||||
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponsePlay;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
||||
import com.hi.music.player.javabean.response.ResponseHome;
|
||||
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
|
||||
@ -21,20 +22,11 @@ public class JsonHelper {
|
||||
public static ResponseHome ResolveHomeJson(JSONObject jsonObject) {
|
||||
ResponseHome responseHome = new ResponseHome();
|
||||
try {
|
||||
String bgUrl = getJsonUrl(jsonObject
|
||||
.getJSONObject("background"));
|
||||
String bgUrl = getJsonUrl(jsonObject.getJSONObject("background"));
|
||||
|
||||
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");
|
||||
|
||||
JSONObject responseContext = jsonObject
|
||||
.getJSONObject("responseContext");
|
||||
JSONObject responseContext = jsonObject.getJSONObject("responseContext");
|
||||
JSONArray serviceTrackingParams = responseContext.getJSONArray("serviceTrackingParams");
|
||||
String visitorData = responseContext.getString("visitorData");
|
||||
CommonUtils.LogMsg("---------参数-visitorData=" + visitorData);
|
||||
@ -58,13 +50,10 @@ public class JsonHelper {
|
||||
ResponseHome responseHome = new ResponseHome();
|
||||
try {
|
||||
|
||||
JSONObject sectionListContinuation = jsonObject
|
||||
.getJSONObject("continuationContents")
|
||||
.getJSONObject("sectionListContinuation");
|
||||
JSONObject sectionListContinuation = jsonObject.getJSONObject("continuationContents").getJSONObject("sectionListContinuation");
|
||||
|
||||
|
||||
JSONObject responseContext = jsonObject
|
||||
.getJSONObject("responseContext");
|
||||
JSONObject responseContext = jsonObject.getJSONObject("responseContext");
|
||||
JSONArray serviceTrackingParams = responseContext.getJSONArray("serviceTrackingParams");
|
||||
|
||||
getCommonHome(sectionListContinuation, responseHome);
|
||||
@ -77,73 +66,10 @@ public class JsonHelper {
|
||||
return responseHome;
|
||||
}
|
||||
|
||||
|
||||
public static List<ResponsePlay> ResolvePlayJson(JSONObject jsonObject) {
|
||||
List<ResponsePlay> list = new ArrayList<>();
|
||||
try {
|
||||
JSONObject playlistPanelRenderer = jsonObject.getJSONObject("contents")
|
||||
.getJSONObject("singleColumnMusicWatchNextResultsRenderer")
|
||||
.getJSONObject("tabbedRenderer")
|
||||
.getJSONObject("watchNextTabbedResultsRenderer")
|
||||
.getJSONArray("tabs")
|
||||
.getJSONObject(0)
|
||||
.getJSONObject("tabRenderer")
|
||||
.getJSONObject("content")
|
||||
.getJSONObject("musicQueueRenderer")
|
||||
.getJSONObject("content")
|
||||
.getJSONObject("playlistPanelRenderer");
|
||||
|
||||
JSONArray contents = playlistPanelRenderer.getJSONArray("contents");
|
||||
|
||||
for (int i = 0; i < contents.length(); i++) {
|
||||
ResponsePlay responsePlay = new ResponsePlay();
|
||||
JSONObject playlistPanelVideoRenderer = contents.getJSONObject(i)
|
||||
.getJSONObject("playlistPanelVideoRenderer");
|
||||
|
||||
String jsonUrl = getJsonUrl(playlistPanelVideoRenderer);
|
||||
String songName = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("title"), 0);
|
||||
|
||||
JSONObject longBylineText = playlistPanelVideoRenderer.getJSONObject("longBylineText");
|
||||
String singerName = getJsonTitle(longBylineText, 0);
|
||||
String AlbumTitle = getJsonTitle(longBylineText, 2);
|
||||
String YearRelease = getJsonTitle(longBylineText, 4);
|
||||
|
||||
String SongDuration = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("lengthText"), 0);
|
||||
|
||||
String[] watchEndPoint = getWatchEndPoint(playlistPanelVideoRenderer);
|
||||
|
||||
responsePlay.setCovert(jsonUrl);
|
||||
responsePlay.setSongTitle(songName);
|
||||
responsePlay.setSingerName(singerName);
|
||||
responsePlay.setAlbumTitle(AlbumTitle);
|
||||
responsePlay.setYear(YearRelease);
|
||||
responsePlay.setDuration(SongDuration);
|
||||
responsePlay.setVideoId(watchEndPoint[0]);
|
||||
responsePlay.setPlaylistId(watchEndPoint[1]);
|
||||
responsePlay.setParams(watchEndPoint[2]);
|
||||
responsePlay.setMusicVideoType(watchEndPoint[3]);
|
||||
|
||||
list.add(responsePlay);
|
||||
CommonUtils.LogMsg("----------歌曲名字=" + songName + "---" + Arrays.toString(watchEndPoint));
|
||||
}
|
||||
|
||||
|
||||
} catch (JSONException exception) {
|
||||
CommonUtils.LogMsg("----------exception=");
|
||||
exception.printStackTrace();
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private static void getCommonHome(JSONObject sectionListRenderer, ResponseHome responseHome) throws JSONException {
|
||||
|
||||
|
||||
JSONObject nextContinuationData = sectionListRenderer
|
||||
.getJSONArray("continuations")
|
||||
.getJSONObject(0)
|
||||
.getJSONObject("nextContinuationData");
|
||||
JSONObject nextContinuationData = sectionListRenderer.getJSONArray("continuations").getJSONObject(0).getJSONObject("nextContinuationData");
|
||||
|
||||
//token=continuation,cit= clickTrackingParams
|
||||
|
||||
@ -154,8 +80,7 @@ public class JsonHelper {
|
||||
responseHome.setClickTrackingParams(clickTrackingParams);
|
||||
responseHome.setContinuation(continuation);
|
||||
|
||||
JSONArray contents = sectionListRenderer
|
||||
.getJSONArray("contents");
|
||||
JSONArray contents = sectionListRenderer.getJSONArray("contents");
|
||||
|
||||
List<ResponseHomeChild> childList = new ArrayList<>();
|
||||
|
||||
@ -167,14 +92,10 @@ public class JsonHelper {
|
||||
if (musicCarouselShelfRenderer != null) {
|
||||
|
||||
//模块标题
|
||||
String title = getJsonTitle(musicCarouselShelfRenderer
|
||||
.getJSONObject("header")
|
||||
.getJSONObject("musicCarouselShelfBasicHeaderRenderer")
|
||||
.getJSONObject("title"), 0);
|
||||
String title = getJsonTitle(musicCarouselShelfRenderer.getJSONObject("header").getJSONObject("musicCarouselShelfBasicHeaderRenderer").getJSONObject("title"), 0);
|
||||
CommonUtils.LogMsg("----------headertitle=" + title);
|
||||
responseHomeChild.setHeaderTitle(title);
|
||||
JSONArray childContents = musicCarouselShelfRenderer
|
||||
.getJSONArray("contents");
|
||||
JSONArray childContents = musicCarouselShelfRenderer.getJSONArray("contents");
|
||||
|
||||
|
||||
List<ResponseCategory> categoryList = new ArrayList<>();
|
||||
@ -185,8 +106,7 @@ public class JsonHelper {
|
||||
if (musicResponsiveListItemRenderer != null) {
|
||||
ResponseSingle responseSingle = new ResponseSingle();
|
||||
|
||||
String SingerHead = getJsonUrl(musicResponsiveListItemRenderer
|
||||
.getJSONObject("thumbnail"));
|
||||
String SingerHead = getJsonUrl(musicResponsiveListItemRenderer.getJSONObject("thumbnail"));
|
||||
|
||||
|
||||
JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns");
|
||||
@ -196,16 +116,12 @@ public class JsonHelper {
|
||||
String SingerName = "";
|
||||
String Description = "";
|
||||
for (int g = 0; g < flexColumns.length(); g++) {
|
||||
JSONObject jsonObject = musicResponsiveListItemRenderer.getJSONArray("flexColumns")
|
||||
.getJSONObject(g)
|
||||
.getJSONObject("musicResponsiveListItemFlexColumnRenderer")
|
||||
.getJSONObject("text");
|
||||
JSONObject jsonObject = musicResponsiveListItemRenderer.getJSONArray("flexColumns").getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text");
|
||||
String text = getJsonTitle(jsonObject, 0);
|
||||
if (g == 0) {
|
||||
SongTitle = text;
|
||||
|
||||
JSONObject runs = jsonObject.getJSONArray("runs")
|
||||
.getJSONObject(0);
|
||||
JSONObject runs = jsonObject.getJSONArray("runs").getJSONObject(0);
|
||||
|
||||
String[] watchEndPoint = getWatchEndPoint(runs);
|
||||
|
||||
@ -229,8 +145,7 @@ public class JsonHelper {
|
||||
JSONObject musicTwoRowItemRenderer = jsonList.optJSONObject("musicTwoRowItemRenderer");
|
||||
if (musicTwoRowItemRenderer != null) {
|
||||
ResponseCategory responseCategory = new ResponseCategory();
|
||||
String covert = getJsonUrl(musicTwoRowItemRenderer
|
||||
.getJSONObject("thumbnailRenderer"));
|
||||
String covert = getJsonUrl(musicTwoRowItemRenderer.getJSONObject("thumbnailRenderer"));
|
||||
|
||||
JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title");
|
||||
String twoTitle = getJsonTitle(title1, 0);
|
||||
@ -259,14 +174,107 @@ public class JsonHelper {
|
||||
|
||||
}
|
||||
|
||||
public static List<ResponsePlayListInfo> ResolvePlayListJson(JSONObject jsonObject) {
|
||||
List<ResponsePlayListInfo> list = new ArrayList<>();
|
||||
try {
|
||||
JSONObject playlistPanelRenderer = jsonObject.getJSONObject("contents").getJSONObject("singleColumnMusicWatchNextResultsRenderer").getJSONObject("tabbedRenderer").getJSONObject("watchNextTabbedResultsRenderer").getJSONArray("tabs").getJSONObject(0).getJSONObject("tabRenderer").getJSONObject("content").getJSONObject("musicQueueRenderer").getJSONObject("content").getJSONObject("playlistPanelRenderer");
|
||||
|
||||
JSONArray contents = playlistPanelRenderer.getJSONArray("contents");
|
||||
|
||||
for (int i = 0; i < contents.length(); i++) {
|
||||
ResponsePlayListInfo responsePlayListInfo = new ResponsePlayListInfo();
|
||||
JSONObject playlistPanelVideoRenderer = contents.getJSONObject(i).getJSONObject("playlistPanelVideoRenderer");
|
||||
|
||||
String jsonUrl = getJsonUrl(playlistPanelVideoRenderer);
|
||||
String songName = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("title"), 0);
|
||||
|
||||
JSONObject longBylineText = playlistPanelVideoRenderer.getJSONObject("longBylineText");
|
||||
String singerName = getJsonTitle(longBylineText, 0);
|
||||
String AlbumTitle = getJsonTitle(longBylineText, 2);
|
||||
String YearRelease = getJsonTitle(longBylineText, 4);
|
||||
|
||||
String SongDuration = getJsonTitle(playlistPanelVideoRenderer.getJSONObject("lengthText"), 0);
|
||||
|
||||
long ms = CommonUtils.convertToMilliseconds(SongDuration);
|
||||
|
||||
|
||||
String[] watchEndPoint = getWatchEndPoint(playlistPanelVideoRenderer);
|
||||
|
||||
responsePlayListInfo.setCovert(jsonUrl);
|
||||
responsePlayListInfo.setSongTitle(songName);
|
||||
responsePlayListInfo.setSingerName(singerName);
|
||||
responsePlayListInfo.setAlbumTitle(AlbumTitle);
|
||||
responsePlayListInfo.setYear(YearRelease);
|
||||
responsePlayListInfo.setDuration(SongDuration);
|
||||
responsePlayListInfo.setDurationMs(ms);
|
||||
responsePlayListInfo.setVideoId(watchEndPoint[0]);
|
||||
responsePlayListInfo.setPlaylistId(watchEndPoint[1]);
|
||||
responsePlayListInfo.setParams(watchEndPoint[2]);
|
||||
responsePlayListInfo.setMusicVideoType(watchEndPoint[3]);
|
||||
|
||||
list.add(responsePlayListInfo);
|
||||
CommonUtils.LogMsg("----------歌曲名字=" + songName + "---" + Arrays.toString(watchEndPoint));
|
||||
}
|
||||
|
||||
|
||||
} catch (JSONException exception) {
|
||||
CommonUtils.LogMsg("----------exception=");
|
||||
exception.printStackTrace();
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static ResponsePlayUrl ResolvePlayUrlJson(JSONObject jsonObject) {
|
||||
try {
|
||||
ResponsePlayUrl responsePlayUrl = new ResponsePlayUrl();
|
||||
String status = jsonObject.getJSONObject("playabilityStatus").getString("status");
|
||||
|
||||
JSONArray jsonArray = jsonObject.getJSONObject("streamingData").getJSONArray("adaptiveFormats");
|
||||
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject jsonIndex = jsonArray.getJSONObject(i);
|
||||
|
||||
String mimeType = jsonIndex.getString("mimeType");
|
||||
String itag = jsonIndex.getString("itag");
|
||||
if (mimeType.contains("audio/mp4")) {
|
||||
String url = jsonIndex.getString("url");
|
||||
boolean audioQuality1 = jsonIndex.has("audioQuality");
|
||||
CommonUtils.LogMsg("------------itag="+itag+"---------audioQuality1="+audioQuality1);
|
||||
if (jsonIndex.has("audioQuality")) {
|
||||
String audioQuality = jsonIndex.getString("audioQuality");
|
||||
if (audioQuality.equals("AUDIO_QUALITY_MEDIUM")) {
|
||||
responsePlayUrl.setAudioUrlMedium(url);
|
||||
} else {
|
||||
responsePlayUrl.setAudioUrlLow(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
String videoId = jsonObject.getJSONObject("videoDetails").getString("videoId");
|
||||
|
||||
|
||||
responsePlayUrl.setVideoId(videoId);
|
||||
|
||||
responsePlayUrl.setStatus(status);
|
||||
return responsePlayUrl;
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static String[] getWatchEndPoint(JSONObject job) {
|
||||
|
||||
String[] strings = new String[4];
|
||||
try {
|
||||
JSONObject watchEndpoint = job
|
||||
.getJSONObject("navigationEndpoint")
|
||||
.getJSONObject("watchEndpoint");
|
||||
JSONObject watchEndpoint = job.getJSONObject("navigationEndpoint").getJSONObject("watchEndpoint");
|
||||
if (watchEndpoint.has("videoId")) {
|
||||
strings[0] = watchEndpoint.getString("videoId");
|
||||
}
|
||||
@ -277,9 +285,7 @@ public class JsonHelper {
|
||||
strings[2] = watchEndpoint.getString("params");
|
||||
}
|
||||
if (watchEndpoint.has("watchEndpointMusicSupportedConfigs")) {
|
||||
strings[3] = watchEndpoint.getJSONObject("watchEndpointMusicSupportedConfigs")
|
||||
.getJSONObject("watchEndpointMusicConfig")
|
||||
.getString("musicVideoType");
|
||||
strings[3] = watchEndpoint.getJSONObject("watchEndpointMusicSupportedConfigs").getJSONObject("watchEndpointMusicConfig").getString("musicVideoType");
|
||||
}
|
||||
// String videoId = watchEndpoint.getString("videoId");
|
||||
// String playlistId = watchEndpoint.getString("playlistId");
|
||||
@ -300,13 +306,10 @@ public class JsonHelper {
|
||||
if (b) {
|
||||
jsonObject = jsonObject.getJSONObject("musicThumbnailRenderer");
|
||||
}
|
||||
JSONArray jsonArray = jsonObject
|
||||
.getJSONObject("thumbnail")
|
||||
.getJSONArray("thumbnails");
|
||||
JSONArray jsonArray = jsonObject.getJSONObject("thumbnail").getJSONArray("thumbnails");
|
||||
int length = jsonArray.length();
|
||||
CommonUtils.LogMsg("----------length=" + (length - 1));
|
||||
String pngUrl = jsonArray.getJSONObject(length - 1)
|
||||
.getString("url");
|
||||
String pngUrl = jsonArray.getJSONObject(length - 1).getString("url");
|
||||
|
||||
return pngUrl;
|
||||
} catch (JSONException exception) {
|
||||
@ -320,9 +323,7 @@ public class JsonHelper {
|
||||
try {
|
||||
JSONArray runs = jsonObject.getJSONArray("runs");
|
||||
if (index < runs.length()) {
|
||||
text = runs
|
||||
.getJSONObject(index)
|
||||
.getString("text");
|
||||
text = runs.getJSONObject(index).getString("text");
|
||||
}
|
||||
|
||||
} catch (JSONException exception) {
|
||||
|
||||
@ -4,6 +4,7 @@ import io.reactivex.Observable;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.Headers;
|
||||
import retrofit2.http.POST;
|
||||
@ -31,10 +32,25 @@ public interface MusicApi {
|
||||
|
||||
|
||||
|
||||
|
||||
// X-Goog-FieldMask: contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer(continuations,contents(automixPreviewVideoRenderer,playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)))
|
||||
|
||||
//获取播放列表
|
||||
@POST("youtubei/v1/next?prettyPrint=false")
|
||||
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
||||
Observable<ResponseBody> getMusicPlayPage(@Header("X-Goog-FieldMask") String customHeader, @Body RequestBody requestBody);
|
||||
|
||||
|
||||
|
||||
|
||||
@POST("youtubei/v1/player?prettyPrint=false")
|
||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
||||
"X-Goog-FieldMask:playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId"})
|
||||
Observable<ResponseBody> getMusicPlayUrl(@Body RequestBody requestBody);
|
||||
|
||||
|
||||
|
||||
@GET("videoplayback?expire=1727100941&ei=rSPxZoSXJ_eM2_gPgqT8mAs&ip=146.19.167.8&id=o-ADGacaLEhb3NOOc74tfR50VCTKy0vnUb2_GAm-tPlv9n&itag=137&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&mh=f8&mm=31%2C29&mn=sn-tt1e7nlz%2Csn-vgqsknzd&ms=au%2Crdu&mv=m&mvi=2&pl=24&gcr=us&initcwndbps=6450000&vprv=1&svpuc=1&mime=video%2Fmp4&rqh=1&gir=yes&clen=4444925&dur=293.280&lmt=1688643558849956&mt=1727078942&fvip=3&keepalive=yes&fexp=51299152&c=ANDROID_MUSIC&txp=4532434&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cgcr%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRgIhAKjjifMN7NMLqeoVXyqHPK1uHqev1PcnVMoycknt4QGfAiEAiCEcEYPDpQsCbE0tJ6MXjvPs4HmT0yM8Yoa26rWpc7M%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=ABPmVW0wRAIgeur5lMiKDgdWV5rrRTkmt0jbOQnifmVQwoTXk_Y17E0CIBfjGXpbdW2u3mtu1I-")
|
||||
Observable<ResponseBody> getTest();
|
||||
|
||||
}
|
||||
|
||||
@ -2,12 +2,10 @@ package com.hi.music.player.network;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.hi.music.player.api.RequestListener;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.requestbody.BodyHome;
|
||||
import com.hi.music.player.javabean.requestbody.BodyPlay;
|
||||
import com.hi.music.player.javabean.response.ResponseHome;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import com.hi.music.player.javabean.requestbody.BodyPlayUrl;
|
||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -26,6 +24,8 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
||||
public class RetrofitManager {
|
||||
|
||||
private String base_Host = "https://music.youtube.com/";
|
||||
|
||||
private String base_Host_test = "https://rr2---sn-tt1e7nlz.googlevideo.com/";
|
||||
private static volatile RetrofitManager REQUEST_MANAGER;
|
||||
|
||||
private Retrofit retrofit;
|
||||
@ -110,7 +110,7 @@ public class RetrofitManager {
|
||||
}
|
||||
|
||||
|
||||
public void getNext(String params,String playlistId,String videoId,String musicVideoType,RequestListener<ResponseBody> requestListener) {
|
||||
public void getPlayList(String params, String playlistId, String videoId, String musicVideoType, RequestListener<ResponseBody> requestListener) {
|
||||
BodyPlay bodyPlay = new BodyPlay();
|
||||
bodyPlay.setParams(params);
|
||||
bodyPlay.setPlaylistId(playlistId);
|
||||
@ -125,4 +125,29 @@ public class RetrofitManager {
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void getPlayUrl(String videoId,RequestListener<ResponseBody> requestListener) {
|
||||
BodyPlayUrl bodyPlay = new BodyPlayUrl();
|
||||
bodyPlay.setVideoId(videoId);
|
||||
ContextBody.Client client = bodyPlay.getContext().getClient();
|
||||
client.setClientName("ANDROID_MUSIC");
|
||||
client.setClientVersion("5.28.1");
|
||||
client.setPlatform("MOBILE");
|
||||
bodyPlay.getContext().getThirdParty().setEmbedUrl("https://www.youtube.com/watch?v="+videoId);
|
||||
|
||||
|
||||
Gson gson = new Gson();
|
||||
String s = gson.toJson(bodyPlay);
|
||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
||||
musicApi.getMusicPlayUrl(requestBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -2,11 +2,17 @@ package com.hi.music.player.ui.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.session.MediaController;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
@ -17,10 +23,12 @@ import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
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.ActivityPlayBinding;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.helper.MyValue;
|
||||
import com.hi.music.player.javabean.response.ResponsePlay;
|
||||
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.ui.activity.viewmodel.VMPlay;
|
||||
@ -32,7 +40,13 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
||||
|
||||
private ResponseSingle responseSingle;
|
||||
private VMPlay vmPlay;
|
||||
private MyMediaControllerManager mediaController;
|
||||
private List<ResponsePlayListInfo> mPlayList;
|
||||
|
||||
private ResponsePlayUrl mCurPlayInfo;
|
||||
private ResponsePlayListInfo musicInfo;
|
||||
private Handler mHandler;
|
||||
private Runnable mRunnable;
|
||||
private MyMediaControllerManager mediaControllerManager;
|
||||
|
||||
@Override
|
||||
protected ActivityPlayBinding getViewBinding() {
|
||||
@ -44,21 +58,78 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
||||
Intent intent = getIntent();
|
||||
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
|
||||
vmPlay = getActivityScopeViewModel(VMPlay.class);
|
||||
vmPlay.getPlay(responseSingle);
|
||||
vmPlay.getPlayUrl(responseSingle);
|
||||
vmPlay.getPlayMusicList(responseSingle);
|
||||
initPlayerView();
|
||||
initMediaController();
|
||||
|
||||
vmPlay.data.observe(this, new Observer<List<ResponsePlay>>() {
|
||||
vmPlay.data.observe(this, new Observer<List<ResponsePlayListInfo>>() {
|
||||
@Override
|
||||
public void onChanged(List<ResponsePlay> playList) {
|
||||
public void onChanged(List<ResponsePlayListInfo> playList) {
|
||||
if (playList.size() > 0) {
|
||||
ResponsePlay responsePlay = playList.get(0);
|
||||
loadCovert(responsePlay.getCovert());
|
||||
loadInfo(responsePlay);
|
||||
|
||||
mPlayList = playList;
|
||||
musicInfo = playList.get(0);
|
||||
loadCovert(musicInfo.getCovert());
|
||||
loadInfo(musicInfo);
|
||||
startPlayMusic();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
vmPlay.playUrlLiveData.observe(this, new Observer<ResponsePlayUrl>() {
|
||||
@Override
|
||||
public void onChanged(ResponsePlayUrl responsePlayUrl) {
|
||||
mCurPlayInfo = responsePlayUrl;
|
||||
CommonUtils.LogMsg("---------mCurPlayInfo=" + mCurPlayInfo.getAudioUrlLow());
|
||||
startPlayMusic();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void initPlayerView() {
|
||||
vb.playerView.setShowRewindButton(false);
|
||||
vb.playerView.setShowPreviousButton(false);
|
||||
vb.playerView.setDefaultArtwork(ContextCompat.getDrawable(this, R.mipmap.ic_launcher));
|
||||
}
|
||||
|
||||
private void initMediaController() {
|
||||
mediaControllerManager = MyMediaControllerManager.getInstance();
|
||||
mediaControllerManager.init(new MediaControllerListener() {
|
||||
|
||||
@Override
|
||||
public void onMediaControllerComplete(boolean isOk) {
|
||||
MediaController mediaController1 = mediaControllerManager.getMediaController();
|
||||
vb.playerView.setPlayer(mediaController1);
|
||||
|
||||
startPlayMusic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayStatus(int playStatus) {
|
||||
switch (playStatus) {
|
||||
case Player.STATE_READY:
|
||||
mHandler.post(mRunnable);
|
||||
vb.progressBar.setVisibility(View.GONE);
|
||||
break;
|
||||
|
||||
case Player.STATE_ENDED:
|
||||
mHandler.removeCallbacks(mRunnable); // 停止更新
|
||||
break;
|
||||
|
||||
case Player.STATE_BUFFERING:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -66,14 +137,49 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
||||
vb.btnPlay.setOnClickListener(this::onClick);
|
||||
}
|
||||
|
||||
private void loadInfo(ResponsePlay data) {
|
||||
|
||||
/**
|
||||
* 更新播放进度Ui
|
||||
*/
|
||||
private void updatePlaybackProgress() {
|
||||
// 获取当前播放位置
|
||||
long contentPos = mediaControllerManager.getContentPos();
|
||||
long currentPosition = mediaControllerManager.getMediaController().getCurrentPosition();
|
||||
long duration = mediaControllerManager.getMediaController().getContentDuration();
|
||||
|
||||
long durationMs = musicInfo.getDurationMs();
|
||||
|
||||
String s = CommonUtils.convertMillisToTime(contentPos);
|
||||
|
||||
|
||||
CommonUtils.LogMsg("---------播放进度-----contentPos=" + contentPos+"----currentPosition="+currentPosition+"------duration="+duration);
|
||||
vb.tvCurrent.setText(s);
|
||||
vb.seekbar.setValue(contentPos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化当前播放歌曲信息
|
||||
* @param data
|
||||
*/
|
||||
private void loadInfo(ResponsePlayListInfo data) {
|
||||
vb.tvSongName.setText(data.getSongTitle());
|
||||
vb.tvSingerName.setText(data.getSingerName());
|
||||
vb.tvDuration.setText(data.getDuration());
|
||||
vb.seekbar.setValueTo(data.getDurationMs());
|
||||
|
||||
}
|
||||
|
||||
private void startPlayMusic() {
|
||||
initProgressHandler();
|
||||
CommonUtils.LogMsg("00000");
|
||||
MediaController mediaController = mediaControllerManager.getMediaController();
|
||||
if (mCurPlayInfo != null && mediaController != null && mPlayList != null) {
|
||||
mediaControllerManager.addMusicPlay(mPlayList.get(0), mCurPlayInfo);
|
||||
mediaControllerManager.play();
|
||||
CommonUtils.LogMsg("111");
|
||||
}
|
||||
|
||||
mediaController = MyMediaControllerManager.getInstance();
|
||||
mediaController.init();
|
||||
mediaController.addMusicPlay(data);
|
||||
}
|
||||
|
||||
private void loadCovert(String url) {
|
||||
@ -89,8 +195,11 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
||||
return false;
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
||||
vb.playerView.setDefaultArtwork(resource);
|
||||
|
||||
return false;
|
||||
}
|
||||
})
|
||||
@ -98,11 +207,16 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
private void initProgressHandler() {
|
||||
mHandler = new Handler();
|
||||
mRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updatePlaybackProgress();
|
||||
// 继续定时更新
|
||||
mHandler.postDelayed(this, 1000); // 每秒更新一次
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,9 +231,16 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(v.equals(vb.btnPlay)){
|
||||
mediaController.play();
|
||||
if (v.equals(vb.btnPlay)) {
|
||||
vb.btnPlay.setSelected(!vb.btnPlay.isSelected());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mHandler != null && mRunnable != null)
|
||||
mHandler.removeCallbacks(mRunnable);
|
||||
}
|
||||
}
|
||||
@ -6,8 +6,8 @@ import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.hi.music.player.api.RequestListener;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.response.ResponseHome;
|
||||
import com.hi.music.player.javabean.response.ResponsePlay;
|
||||
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.network.JsonHelper;
|
||||
import com.hi.music.player.network.RetrofitManager;
|
||||
@ -21,18 +21,22 @@ import okhttp3.ResponseBody;
|
||||
public class VMPlay extends ViewModel {
|
||||
|
||||
|
||||
private MutableLiveData<List<ResponsePlay>> _data = new MutableLiveData<List<ResponsePlay>>();
|
||||
public LiveData<List<ResponsePlay>> data = _data;
|
||||
private MutableLiveData<List<ResponsePlayListInfo>> _data = new MutableLiveData<List<ResponsePlayListInfo>>();
|
||||
public LiveData<List<ResponsePlayListInfo>> data = _data;
|
||||
|
||||
|
||||
private MutableLiveData<ResponsePlayUrl> _playUrlMutableLiveData = new MutableLiveData<ResponsePlayUrl>();
|
||||
public LiveData<ResponsePlayUrl> playUrlLiveData = _playUrlMutableLiveData;
|
||||
|
||||
private String continuation, clickTrackingParams, visitorData;
|
||||
|
||||
public void getPlay(ResponseSingle responseSingle) {
|
||||
public void getPlayMusicList(ResponseSingle responseSingle) {
|
||||
String playlistId = responseSingle.getPlaylistId();
|
||||
String videoId = responseSingle.getVideoId();
|
||||
String params = responseSingle.getParams();
|
||||
String musicVideoType = responseSingle.getMusicVideoType();
|
||||
|
||||
RetrofitManager.getInstance().getNext(params, playlistId, videoId, musicVideoType, new RequestListener<ResponseBody>() {
|
||||
RetrofitManager.getInstance().getPlayList(params, playlistId, videoId, musicVideoType, new RequestListener<ResponseBody>() {
|
||||
|
||||
@Override
|
||||
public void onFail(String errorMsg) {
|
||||
@ -43,8 +47,8 @@ public class VMPlay extends ViewModel {
|
||||
public void onSuccess(ResponseBody data) {
|
||||
JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
||||
if (jsonObject != null) {
|
||||
List<ResponsePlay> responsePlays = JsonHelper.ResolvePlayJson(jsonObject);
|
||||
_data.setValue(responsePlays);
|
||||
List<ResponsePlayListInfo> responsePlayListInfos = JsonHelper.ResolvePlayListJson(jsonObject);
|
||||
_data.setValue(responsePlayListInfos);
|
||||
} else {
|
||||
_data.setValue(null);
|
||||
}
|
||||
@ -53,5 +57,28 @@ public class VMPlay extends ViewModel {
|
||||
});
|
||||
}
|
||||
|
||||
public void getPlayUrl(ResponseSingle responseSingle) {
|
||||
String videoId = responseSingle.getVideoId();
|
||||
RetrofitManager.getInstance().getPlayUrl(videoId, new RequestListener<ResponseBody>() {
|
||||
|
||||
@Override
|
||||
public void onFail(String errorMsg) {
|
||||
_playUrlMutableLiveData.setValue(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(ResponseBody data) {
|
||||
JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
||||
if (jsonObject != null) {
|
||||
ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(jsonObject);
|
||||
_playUrlMutableLiveData.setValue(responsePlayUrl);
|
||||
} else {
|
||||
_playUrlMutableLiveData.setValue(null);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -54,9 +54,11 @@ public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements C
|
||||
vmHome.getHome();
|
||||
|
||||
|
||||
|
||||
vmHome.data.observe(getViewLifecycleOwner(), new Observer<ResponseHome>() {
|
||||
@Override
|
||||
public void onChanged(ResponseHome responseHome) {
|
||||
if(responseHome == null)return;
|
||||
List<ResponseHomeChild> childList1 = responseHome.getChildList();
|
||||
childList.addAll(childList1);
|
||||
adapterHome.removeLoadingFooter();
|
||||
|
||||
@ -31,6 +31,32 @@
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_back" />
|
||||
|
||||
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:show_buffering="when_playing"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/im_back"
|
||||
app:show_shuffle_button="true"/>
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="@id/im_covert"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
android:indeterminateTint="@color/white"
|
||||
android:id="@+id/progressBar"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintRight_toRightOf="@id/im_covert"
|
||||
app:layout_constraintTop_toTopOf="@id/im_covert" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_song_name"
|
||||
android:layout_width="wrap_content"
|
||||
@ -53,10 +79,24 @@
|
||||
app:layout_constraintLeft_toLeftOf="@id/tv_song_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_song_name" />
|
||||
|
||||
<SeekBar
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/seekbar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="0"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
app:layout_constraintRight_toRightOf="@id/im_covert"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_singer_name"
|
||||
app:labelBehavior="gone"
|
||||
app:thumbColor="@color/white"
|
||||
app:thumbRadius="6dp"
|
||||
app:trackColorActive="@color/white"
|
||||
app:trackColorInactive="#00000000"
|
||||
app:trackHeight="3dp" />
|
||||
<SeekBar
|
||||
android:id="@+id/seekbar1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="25dp"
|
||||
android:maxHeight="3dp"
|
||||
android:paddingStart="0dp"
|
||||
@ -64,6 +104,7 @@
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:progress="10"
|
||||
android:visibility="gone"
|
||||
android:progressDrawable="@drawable/seekbar_progress_drawable"
|
||||
android:thumb="@drawable/seekbar_thumb"
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||
@ -131,4 +172,6 @@
|
||||
app:layout_constraintLeft_toLeftOf="@id/im_covert" />
|
||||
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Loading…
Reference in New Issue
Block a user