播放页面Ui
This commit is contained in:
parent
7f065a1835
commit
96eecd07e7
@ -59,6 +59,8 @@ dependencies {
|
|||||||
|
|
||||||
//----------media3
|
//----------media3
|
||||||
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
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-session:1.4.1")
|
||||||
|
implementation("androidx.media3:media3-ui:1.4.1")
|
||||||
//----------media3
|
//----------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;
|
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 Client client = new Client();
|
||||||
|
|
||||||
|
private ThirdParty thirdParty = new ThirdParty();
|
||||||
|
|
||||||
|
|
||||||
|
public ThirdParty getThirdParty() {
|
||||||
|
return thirdParty;
|
||||||
|
}
|
||||||
|
|
||||||
public Client getClient() {
|
public Client getClient() {
|
||||||
return client;
|
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 clientName = "WEB_REMIX";
|
||||||
private String clientVersion = "1.20220918";
|
private String clientVersion = "1.20220918";
|
||||||
private String hl = Locale.getDefault().getLanguage();
|
private String hl = Locale.getDefault().getLanguage();
|
||||||
@ -32,5 +39,27 @@ public class ContextBody {
|
|||||||
public void setVisitorData(String visitorData) {
|
public void setVisitorData(String visitorData) {
|
||||||
this.visitorData = 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;
|
private String continuation;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
//用于更多数据请求的visitorData(只有第一个接口会返回该值)
|
//用于更多数据请求的visitorData(只有第一个接口会返回该值,youtubei/v1/browse?prettyPrint=false)
|
||||||
private String visitorData;
|
private String visitorData;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
package com.hi.music.player.javabean.response;
|
||||||
|
|
||||||
public class ResponsePlay {
|
public class ResponsePlayListInfo {
|
||||||
|
|
||||||
//封面
|
//封面
|
||||||
private String covert;
|
private String covert;
|
||||||
@ -20,11 +20,22 @@ public class ResponsePlay {
|
|||||||
private String Duration;
|
private String Duration;
|
||||||
|
|
||||||
|
|
||||||
|
//歌曲时长 毫秒
|
||||||
|
private long DurationMs;
|
||||||
|
|
||||||
|
|
||||||
private String videoId;
|
private String videoId;
|
||||||
private String playlistId;
|
private String playlistId;
|
||||||
private String params;
|
private String params;
|
||||||
private String musicVideoType;
|
private String musicVideoType;
|
||||||
|
|
||||||
|
public long getDurationMs() {
|
||||||
|
return DurationMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDurationMs(long durationMs) {
|
||||||
|
DurationMs = durationMs;
|
||||||
|
}
|
||||||
|
|
||||||
public String getDuration() {
|
public String getDuration() {
|
||||||
return Duration;
|
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 android.content.ComponentName;
|
||||||
|
|
||||||
|
import androidx.annotation.OptIn;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.MediaMetadata;
|
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.MediaController;
|
||||||
import androidx.media3.session.SessionToken;
|
import androidx.media3.session.SessionToken;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.hi.music.player.MusicApplication;
|
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.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 com.hi.music.player.network.RetrofitManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -34,7 +40,7 @@ public class MyMediaControllerManager {
|
|||||||
return myMediaControllerManagerInstance;
|
return myMediaControllerManagerInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(){
|
public void init(MediaControllerListener mediaControllerListener){
|
||||||
SessionToken sessionToken =
|
SessionToken sessionToken =
|
||||||
new SessionToken(MusicApplication.myApplication, new ComponentName(MusicApplication.myApplication, PlaybackService.class));
|
new SessionToken(MusicApplication.myApplication, new ComponentName(MusicApplication.myApplication, PlaybackService.class));
|
||||||
ListenableFuture<MediaController> controllerFuture =
|
ListenableFuture<MediaController> controllerFuture =
|
||||||
@ -46,8 +52,30 @@ public class MyMediaControllerManager {
|
|||||||
// playerView.setPlayer(controllerFuture.get());
|
// playerView.setPlayer(controllerFuture.get());
|
||||||
try {
|
try {
|
||||||
mediaController = controllerFuture.get();
|
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) {
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
CommonUtils.LogErrorMsg(e.getMessage());
|
CommonUtils.LogErrorMsg(e.getMessage());
|
||||||
|
mediaControllerListener.onMediaControllerComplete(false);
|
||||||
}
|
}
|
||||||
}, MoreExecutors.directExecutor());
|
}, 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<>();
|
List<MediaItem> mediaItems = new ArrayList<>();
|
||||||
MediaItem.Builder builder = new MediaItem.Builder();
|
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 MediaMetadata_builder = new MediaMetadata.Builder();
|
||||||
// MediaMetadata_builder.setMediaType();
|
|
||||||
// MediaMetadata_builder.setAlbumTitle();
|
MediaMetadata_builder.setArtist(playInfo.getSingerName());
|
||||||
// MediaMetadata_builder.setArtist();
|
// MediaMetadata_builder.setDurationMs( );
|
||||||
// MediaMetadata_builder.setDurationMs();
|
MediaMetadata_builder.setAlbumArtist(playInfo.getCovert());
|
||||||
// MediaMetadata_builder.setTitle();
|
MediaMetadata_builder.setTitle(playInfo.getSongTitle());
|
||||||
// MediaMetadata_builder.setRecordingYear();
|
// MediaMetadata_builder.setRecordingYear(Integer.parseInt(playInfo.getYear()));
|
||||||
builder.setMediaMetadata(MediaMetadata_builder.build());
|
builder.setMediaMetadata(MediaMetadata_builder.build());
|
||||||
|
|
||||||
mediaItems.add(builder.build());
|
mediaItems.add(builder.build());
|
||||||
@ -76,4 +120,6 @@ public class MyMediaControllerManager {
|
|||||||
public void play(){
|
public void play(){
|
||||||
mediaController.play();
|
mediaController.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,83 @@
|
|||||||
package com.hi.music.player.media3;
|
package com.hi.music.player.media3;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
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.ExoPlayer;
|
||||||
|
|
||||||
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||||
|
import androidx.media3.exoplayer.source.MediaSource;
|
||||||
import androidx.media3.session.MediaSession;
|
import androidx.media3.session.MediaSession;
|
||||||
import androidx.media3.session.MediaSessionService;
|
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 {
|
public class PlaybackService extends MediaSessionService {
|
||||||
private MediaSession mediaSession = null;
|
private MediaSession mediaSession = null;
|
||||||
|
private ExoPlayer player;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.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
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
|
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
|
||||||
return mediaSession;
|
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
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
mediaSession.getPlayer().release();
|
mediaSession.getPlayer().release();
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package com.hi.music.player.network;
|
package com.hi.music.player.network;
|
||||||
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
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.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.ResponseHomeChild;
|
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
|
||||||
@ -21,20 +22,11 @@ public class JsonHelper {
|
|||||||
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
|
String bgUrl = getJsonUrl(jsonObject.getJSONObject("background"));
|
||||||
.getJSONObject("background"));
|
|
||||||
|
|
||||||
JSONObject sectionListRenderer = jsonObject
|
JSONObject sectionListRenderer = jsonObject.getJSONObject("contents").getJSONObject("singleColumnBrowseResultsRenderer").getJSONArray("tabs").getJSONObject(0).getJSONObject("tabRenderer").getJSONObject("content").getJSONObject("sectionListRenderer");
|
||||||
.getJSONObject("contents")
|
|
||||||
.getJSONObject("singleColumnBrowseResultsRenderer")
|
|
||||||
.getJSONArray("tabs")
|
|
||||||
.getJSONObject(0)
|
|
||||||
.getJSONObject("tabRenderer")
|
|
||||||
.getJSONObject("content")
|
|
||||||
.getJSONObject("sectionListRenderer");
|
|
||||||
|
|
||||||
JSONObject responseContext = jsonObject
|
JSONObject responseContext = jsonObject.getJSONObject("responseContext");
|
||||||
.getJSONObject("responseContext");
|
|
||||||
JSONArray serviceTrackingParams = responseContext.getJSONArray("serviceTrackingParams");
|
JSONArray serviceTrackingParams = responseContext.getJSONArray("serviceTrackingParams");
|
||||||
String visitorData = responseContext.getString("visitorData");
|
String visitorData = responseContext.getString("visitorData");
|
||||||
CommonUtils.LogMsg("---------参数-visitorData=" + visitorData);
|
CommonUtils.LogMsg("---------参数-visitorData=" + visitorData);
|
||||||
@ -58,13 +50,10 @@ public class JsonHelper {
|
|||||||
ResponseHome responseHome = new ResponseHome();
|
ResponseHome responseHome = new ResponseHome();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
JSONObject sectionListContinuation = jsonObject
|
JSONObject sectionListContinuation = jsonObject.getJSONObject("continuationContents").getJSONObject("sectionListContinuation");
|
||||||
.getJSONObject("continuationContents")
|
|
||||||
.getJSONObject("sectionListContinuation");
|
|
||||||
|
|
||||||
|
|
||||||
JSONObject responseContext = jsonObject
|
JSONObject responseContext = jsonObject.getJSONObject("responseContext");
|
||||||
.getJSONObject("responseContext");
|
|
||||||
JSONArray serviceTrackingParams = responseContext.getJSONArray("serviceTrackingParams");
|
JSONArray serviceTrackingParams = responseContext.getJSONArray("serviceTrackingParams");
|
||||||
|
|
||||||
getCommonHome(sectionListContinuation, responseHome);
|
getCommonHome(sectionListContinuation, responseHome);
|
||||||
@ -77,73 +66,10 @@ public class JsonHelper {
|
|||||||
return responseHome;
|
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 {
|
private static void getCommonHome(JSONObject sectionListRenderer, ResponseHome responseHome) throws JSONException {
|
||||||
|
|
||||||
|
|
||||||
JSONObject nextContinuationData = sectionListRenderer
|
JSONObject nextContinuationData = sectionListRenderer.getJSONArray("continuations").getJSONObject(0).getJSONObject("nextContinuationData");
|
||||||
.getJSONArray("continuations")
|
|
||||||
.getJSONObject(0)
|
|
||||||
.getJSONObject("nextContinuationData");
|
|
||||||
|
|
||||||
//token=continuation,cit= clickTrackingParams
|
//token=continuation,cit= clickTrackingParams
|
||||||
|
|
||||||
@ -154,8 +80,7 @@ public class JsonHelper {
|
|||||||
responseHome.setClickTrackingParams(clickTrackingParams);
|
responseHome.setClickTrackingParams(clickTrackingParams);
|
||||||
responseHome.setContinuation(continuation);
|
responseHome.setContinuation(continuation);
|
||||||
|
|
||||||
JSONArray contents = sectionListRenderer
|
JSONArray contents = sectionListRenderer.getJSONArray("contents");
|
||||||
.getJSONArray("contents");
|
|
||||||
|
|
||||||
List<ResponseHomeChild> childList = new ArrayList<>();
|
List<ResponseHomeChild> childList = new ArrayList<>();
|
||||||
|
|
||||||
@ -167,14 +92,10 @@ public class JsonHelper {
|
|||||||
if (musicCarouselShelfRenderer != null) {
|
if (musicCarouselShelfRenderer != null) {
|
||||||
|
|
||||||
//模块标题
|
//模块标题
|
||||||
String title = getJsonTitle(musicCarouselShelfRenderer
|
String title = getJsonTitle(musicCarouselShelfRenderer.getJSONObject("header").getJSONObject("musicCarouselShelfBasicHeaderRenderer").getJSONObject("title"), 0);
|
||||||
.getJSONObject("header")
|
|
||||||
.getJSONObject("musicCarouselShelfBasicHeaderRenderer")
|
|
||||||
.getJSONObject("title"), 0);
|
|
||||||
CommonUtils.LogMsg("----------headertitle=" + title);
|
CommonUtils.LogMsg("----------headertitle=" + title);
|
||||||
responseHomeChild.setHeaderTitle(title);
|
responseHomeChild.setHeaderTitle(title);
|
||||||
JSONArray childContents = musicCarouselShelfRenderer
|
JSONArray childContents = musicCarouselShelfRenderer.getJSONArray("contents");
|
||||||
.getJSONArray("contents");
|
|
||||||
|
|
||||||
|
|
||||||
List<ResponseCategory> categoryList = new ArrayList<>();
|
List<ResponseCategory> categoryList = new ArrayList<>();
|
||||||
@ -185,8 +106,7 @@ public class JsonHelper {
|
|||||||
if (musicResponsiveListItemRenderer != null) {
|
if (musicResponsiveListItemRenderer != null) {
|
||||||
ResponseSingle responseSingle = new ResponseSingle();
|
ResponseSingle responseSingle = new ResponseSingle();
|
||||||
|
|
||||||
String SingerHead = getJsonUrl(musicResponsiveListItemRenderer
|
String SingerHead = getJsonUrl(musicResponsiveListItemRenderer.getJSONObject("thumbnail"));
|
||||||
.getJSONObject("thumbnail"));
|
|
||||||
|
|
||||||
|
|
||||||
JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns");
|
JSONArray flexColumns = musicResponsiveListItemRenderer.getJSONArray("flexColumns");
|
||||||
@ -196,16 +116,12 @@ public class JsonHelper {
|
|||||||
String SingerName = "";
|
String SingerName = "";
|
||||||
String Description = "";
|
String Description = "";
|
||||||
for (int g = 0; g < flexColumns.length(); g++) {
|
for (int g = 0; g < flexColumns.length(); g++) {
|
||||||
JSONObject jsonObject = musicResponsiveListItemRenderer.getJSONArray("flexColumns")
|
JSONObject jsonObject = musicResponsiveListItemRenderer.getJSONArray("flexColumns").getJSONObject(g).getJSONObject("musicResponsiveListItemFlexColumnRenderer").getJSONObject("text");
|
||||||
.getJSONObject(g)
|
|
||||||
.getJSONObject("musicResponsiveListItemFlexColumnRenderer")
|
|
||||||
.getJSONObject("text");
|
|
||||||
String text = getJsonTitle(jsonObject, 0);
|
String text = getJsonTitle(jsonObject, 0);
|
||||||
if (g == 0) {
|
if (g == 0) {
|
||||||
SongTitle = text;
|
SongTitle = text;
|
||||||
|
|
||||||
JSONObject runs = jsonObject.getJSONArray("runs")
|
JSONObject runs = jsonObject.getJSONArray("runs").getJSONObject(0);
|
||||||
.getJSONObject(0);
|
|
||||||
|
|
||||||
String[] watchEndPoint = getWatchEndPoint(runs);
|
String[] watchEndPoint = getWatchEndPoint(runs);
|
||||||
|
|
||||||
@ -229,8 +145,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
|
String covert = getJsonUrl(musicTwoRowItemRenderer.getJSONObject("thumbnailRenderer"));
|
||||||
.getJSONObject("thumbnailRenderer"));
|
|
||||||
|
|
||||||
JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title");
|
JSONObject title1 = musicTwoRowItemRenderer.getJSONObject("title");
|
||||||
String twoTitle = getJsonTitle(title1, 0);
|
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) {
|
private static String[] getWatchEndPoint(JSONObject job) {
|
||||||
|
|
||||||
String[] strings = new String[4];
|
String[] strings = new String[4];
|
||||||
try {
|
try {
|
||||||
JSONObject watchEndpoint = job
|
JSONObject watchEndpoint = job.getJSONObject("navigationEndpoint").getJSONObject("watchEndpoint");
|
||||||
.getJSONObject("navigationEndpoint")
|
|
||||||
.getJSONObject("watchEndpoint");
|
|
||||||
if (watchEndpoint.has("videoId")) {
|
if (watchEndpoint.has("videoId")) {
|
||||||
strings[0] = watchEndpoint.getString("videoId");
|
strings[0] = watchEndpoint.getString("videoId");
|
||||||
}
|
}
|
||||||
@ -277,9 +285,7 @@ public class JsonHelper {
|
|||||||
strings[2] = watchEndpoint.getString("params");
|
strings[2] = watchEndpoint.getString("params");
|
||||||
}
|
}
|
||||||
if (watchEndpoint.has("watchEndpointMusicSupportedConfigs")) {
|
if (watchEndpoint.has("watchEndpointMusicSupportedConfigs")) {
|
||||||
strings[3] = watchEndpoint.getJSONObject("watchEndpointMusicSupportedConfigs")
|
strings[3] = watchEndpoint.getJSONObject("watchEndpointMusicSupportedConfigs").getJSONObject("watchEndpointMusicConfig").getString("musicVideoType");
|
||||||
.getJSONObject("watchEndpointMusicConfig")
|
|
||||||
.getString("musicVideoType");
|
|
||||||
}
|
}
|
||||||
// String videoId = watchEndpoint.getString("videoId");
|
// String videoId = watchEndpoint.getString("videoId");
|
||||||
// String playlistId = watchEndpoint.getString("playlistId");
|
// String playlistId = watchEndpoint.getString("playlistId");
|
||||||
@ -300,13 +306,10 @@ public class JsonHelper {
|
|||||||
if (b) {
|
if (b) {
|
||||||
jsonObject = jsonObject.getJSONObject("musicThumbnailRenderer");
|
jsonObject = jsonObject.getJSONObject("musicThumbnailRenderer");
|
||||||
}
|
}
|
||||||
JSONArray jsonArray = jsonObject
|
JSONArray jsonArray = jsonObject.getJSONObject("thumbnail").getJSONArray("thumbnails");
|
||||||
.getJSONObject("thumbnail")
|
|
||||||
.getJSONArray("thumbnails");
|
|
||||||
int length = jsonArray.length();
|
int length = jsonArray.length();
|
||||||
CommonUtils.LogMsg("----------length=" + (length - 1));
|
CommonUtils.LogMsg("----------length=" + (length - 1));
|
||||||
String pngUrl = jsonArray.getJSONObject(length - 1)
|
String pngUrl = jsonArray.getJSONObject(length - 1).getString("url");
|
||||||
.getString("url");
|
|
||||||
|
|
||||||
return pngUrl;
|
return pngUrl;
|
||||||
} catch (JSONException exception) {
|
} catch (JSONException exception) {
|
||||||
@ -320,9 +323,7 @@ public class JsonHelper {
|
|||||||
try {
|
try {
|
||||||
JSONArray runs = jsonObject.getJSONArray("runs");
|
JSONArray runs = jsonObject.getJSONArray("runs");
|
||||||
if (index < runs.length()) {
|
if (index < runs.length()) {
|
||||||
text = runs
|
text = runs.getJSONObject(index).getString("text");
|
||||||
.getJSONObject(index)
|
|
||||||
.getString("text");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (JSONException exception) {
|
} catch (JSONException exception) {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import io.reactivex.Observable;
|
|||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
import retrofit2.http.Body;
|
import retrofit2.http.Body;
|
||||||
|
import retrofit2.http.GET;
|
||||||
import retrofit2.http.Header;
|
import retrofit2.http.Header;
|
||||||
import retrofit2.http.Headers;
|
import retrofit2.http.Headers;
|
||||||
import retrofit2.http.POST;
|
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)))
|
// 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")
|
@POST("youtubei/v1/next?prettyPrint=false")
|
||||||
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
||||||
Observable<ResponseBody> getMusicPlayPage(@Header("X-Goog-FieldMask") String customHeader, @Body RequestBody requestBody);
|
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.google.gson.Gson;
|
||||||
import com.hi.music.player.api.RequestListener;
|
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.BodyHome;
|
||||||
import com.hi.music.player.javabean.requestbody.BodyPlay;
|
import com.hi.music.player.javabean.requestbody.BodyPlay;
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
import com.hi.music.player.javabean.requestbody.BodyPlayUrl;
|
||||||
|
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -26,6 +24,8 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
|||||||
public class RetrofitManager {
|
public class RetrofitManager {
|
||||||
|
|
||||||
private String base_Host = "https://music.youtube.com/";
|
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 static volatile RetrofitManager REQUEST_MANAGER;
|
||||||
|
|
||||||
private Retrofit retrofit;
|
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 bodyPlay = new BodyPlay();
|
||||||
bodyPlay.setParams(params);
|
bodyPlay.setParams(params);
|
||||||
bodyPlay.setPlaylistId(playlistId);
|
bodyPlay.setPlaylistId(playlistId);
|
||||||
@ -125,4 +125,29 @@ public class RetrofitManager {
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
.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.content.Intent;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Handler;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.OptIn;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.lifecycle.Observer;
|
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.Glide;
|
||||||
import com.bumptech.glide.load.DataSource;
|
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.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.api.MediaControllerListener;
|
||||||
import com.hi.music.player.databinding.ActivityPlayBinding;
|
import com.hi.music.player.databinding.ActivityPlayBinding;
|
||||||
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.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.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.VMPlay;
|
import com.hi.music.player.ui.activity.viewmodel.VMPlay;
|
||||||
@ -32,7 +40,13 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
|||||||
|
|
||||||
private ResponseSingle responseSingle;
|
private ResponseSingle responseSingle;
|
||||||
private VMPlay vmPlay;
|
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
|
@Override
|
||||||
protected ActivityPlayBinding getViewBinding() {
|
protected ActivityPlayBinding getViewBinding() {
|
||||||
@ -44,21 +58,78 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
|||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
|
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
|
||||||
vmPlay = getActivityScopeViewModel(VMPlay.class);
|
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
|
@Override
|
||||||
public void onChanged(List<ResponsePlay> playList) {
|
public void onChanged(List<ResponsePlayListInfo> playList) {
|
||||||
if (playList.size() > 0) {
|
if (playList.size() > 0) {
|
||||||
ResponsePlay responsePlay = playList.get(0);
|
mPlayList = playList;
|
||||||
loadCovert(responsePlay.getCovert());
|
musicInfo = playList.get(0);
|
||||||
loadInfo(responsePlay);
|
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
|
@Override
|
||||||
@ -66,14 +137,49 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
|||||||
vb.btnPlay.setOnClickListener(this::onClick);
|
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.tvSongName.setText(data.getSongTitle());
|
||||||
vb.tvSingerName.setText(data.getSingerName());
|
vb.tvSingerName.setText(data.getSingerName());
|
||||||
vb.tvDuration.setText(data.getDuration());
|
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) {
|
private void loadCovert(String url) {
|
||||||
@ -89,8 +195,11 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(markerClass = UnstableApi.class)
|
||||||
@Override
|
@Override
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
||||||
|
vb.playerView.setDefaultArtwork(resource);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -98,11 +207,16 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initProgressHandler() {
|
||||||
@Override
|
mHandler = new Handler();
|
||||||
public void onStart() {
|
mRunnable = new Runnable() {
|
||||||
super.onStart();
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updatePlaybackProgress();
|
||||||
|
// 继续定时更新
|
||||||
|
mHandler.postDelayed(this, 1000); // 每秒更新一次
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -117,9 +231,16 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if(v.equals(vb.btnPlay)){
|
if (v.equals(vb.btnPlay)) {
|
||||||
mediaController.play();
|
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.api.RequestListener;
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
import com.hi.music.player.helper.CommonUtils;
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
||||||
import com.hi.music.player.javabean.response.ResponsePlay;
|
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.network.JsonHelper;
|
import com.hi.music.player.network.JsonHelper;
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
import com.hi.music.player.network.RetrofitManager;
|
||||||
@ -21,18 +21,22 @@ import okhttp3.ResponseBody;
|
|||||||
public class VMPlay extends ViewModel {
|
public class VMPlay extends ViewModel {
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<List<ResponsePlay>> _data = new MutableLiveData<List<ResponsePlay>>();
|
private MutableLiveData<List<ResponsePlayListInfo>> _data = new MutableLiveData<List<ResponsePlayListInfo>>();
|
||||||
public LiveData<List<ResponsePlay>> data = _data;
|
public LiveData<List<ResponsePlayListInfo>> data = _data;
|
||||||
|
|
||||||
|
|
||||||
|
private MutableLiveData<ResponsePlayUrl> _playUrlMutableLiveData = new MutableLiveData<ResponsePlayUrl>();
|
||||||
|
public LiveData<ResponsePlayUrl> playUrlLiveData = _playUrlMutableLiveData;
|
||||||
|
|
||||||
private String continuation, clickTrackingParams, visitorData;
|
private String continuation, clickTrackingParams, visitorData;
|
||||||
|
|
||||||
public void getPlay(ResponseSingle responseSingle) {
|
public void getPlayMusicList(ResponseSingle responseSingle) {
|
||||||
String playlistId = responseSingle.getPlaylistId();
|
String playlistId = responseSingle.getPlaylistId();
|
||||||
String videoId = responseSingle.getVideoId();
|
String videoId = responseSingle.getVideoId();
|
||||||
String params = responseSingle.getParams();
|
String params = responseSingle.getParams();
|
||||||
String musicVideoType = responseSingle.getMusicVideoType();
|
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
|
@Override
|
||||||
public void onFail(String errorMsg) {
|
public void onFail(String errorMsg) {
|
||||||
@ -43,8 +47,8 @@ public class VMPlay extends ViewModel {
|
|||||||
public void onSuccess(ResponseBody data) {
|
public void onSuccess(ResponseBody data) {
|
||||||
JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
||||||
if (jsonObject != null) {
|
if (jsonObject != null) {
|
||||||
List<ResponsePlay> responsePlays = JsonHelper.ResolvePlayJson(jsonObject);
|
List<ResponsePlayListInfo> responsePlayListInfos = JsonHelper.ResolvePlayListJson(jsonObject);
|
||||||
_data.setValue(responsePlays);
|
_data.setValue(responsePlayListInfos);
|
||||||
} else {
|
} else {
|
||||||
_data.setValue(null);
|
_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.getHome();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vmHome.data.observe(getViewLifecycleOwner(), new Observer<ResponseHome>() {
|
vmHome.data.observe(getViewLifecycleOwner(), new Observer<ResponseHome>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(ResponseHome responseHome) {
|
public void onChanged(ResponseHome responseHome) {
|
||||||
|
if(responseHome == null)return;
|
||||||
List<ResponseHomeChild> childList1 = responseHome.getChildList();
|
List<ResponseHomeChild> childList1 = responseHome.getChildList();
|
||||||
childList.addAll(childList1);
|
childList.addAll(childList1);
|
||||||
adapterHome.removeLoadingFooter();
|
adapterHome.removeLoadingFooter();
|
||||||
|
|||||||
@ -31,6 +31,32 @@
|
|||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/im_back" />
|
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
|
<TextView
|
||||||
android:id="@+id/tv_song_name"
|
android:id="@+id/tv_song_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -53,10 +79,24 @@
|
|||||||
app:layout_constraintLeft_toLeftOf="@id/tv_song_name"
|
app:layout_constraintLeft_toLeftOf="@id/tv_song_name"
|
||||||
app:layout_constraintTop_toBottomOf="@id/tv_song_name" />
|
app:layout_constraintTop_toBottomOf="@id/tv_song_name" />
|
||||||
|
|
||||||
<SeekBar
|
<com.google.android.material.slider.Slider
|
||||||
android:id="@+id/seekbar"
|
android:id="@+id/seekbar"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
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:layout_marginTop="25dp"
|
||||||
android:maxHeight="3dp"
|
android:maxHeight="3dp"
|
||||||
android:paddingStart="0dp"
|
android:paddingStart="0dp"
|
||||||
@ -64,6 +104,7 @@
|
|||||||
android:paddingEnd="0dp"
|
android:paddingEnd="0dp"
|
||||||
android:paddingRight="0dp"
|
android:paddingRight="0dp"
|
||||||
android:progress="10"
|
android:progress="10"
|
||||||
|
android:visibility="gone"
|
||||||
android:progressDrawable="@drawable/seekbar_progress_drawable"
|
android:progressDrawable="@drawable/seekbar_progress_drawable"
|
||||||
android:thumb="@drawable/seekbar_thumb"
|
android:thumb="@drawable/seekbar_thumb"
|
||||||
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
app:layout_constraintLeft_toLeftOf="@id/im_covert"
|
||||||
@ -131,4 +172,6 @@
|
|||||||
app:layout_constraintLeft_toLeftOf="@id/im_covert" />
|
app:layout_constraintLeft_toLeftOf="@id/im_covert" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
Loading…
Reference in New Issue
Block a user