Skip to content

Commit

Permalink
update player implement
Browse files Browse the repository at this point in the history
  • Loading branch information
KunMinX committed Aug 12, 2022
1 parent 7125bb1 commit 356d3eb
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 485 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apply plugin: "com.android.application"
android {
compileSdkVersion appTargetSdk
defaultConfig {
applicationId "com.kunminx.puremusic"
applicationId "com.kunminx.player"
minSdkVersion appMinSdk
targetSdkVersion appTargetSdk
versionCode appVersionCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,7 @@ public void init(Context context, IServiceNotifier iServiceNotifier, ICacheProxy
.maxCacheSize(2147483648L) // 2GB
.build();

//添加额外的音乐格式
List<String> extraFormats = new ArrayList<>();
extraFormats.add(".flac");
extraFormats.add(".ape");

mController.init(context1, extraFormats, startOrStop -> {
mController.init(context1, startOrStop -> {
Intent intent = new Intent(context1, PlayerService.class);
if (startOrStop) {
context1.startService(intent);
Expand Down
24 changes: 14 additions & 10 deletions player/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ ext {

ARTIFACT_DESCRIPTION = 'Jetpack MusicPlayer Library for android'

POM_URL='https://github.com/KunMinX/Jetpack-MusicPlayer'
POM_SCM_URL='https://github.com/KunMinX/Jetpack-MusicPlayer/tree/master'
POM_SCM_CONNECTION='scm:git:github.com/KunMinX/Jetpack-MusicPlayer.git'
POM_SCM_DEV_CONNECTION='scm:git:ssh://github.com/KunMinX/Jetpack-MusicPlayer.git'
POM_URL = 'https://github.com/KunMinX/Jetpack-MusicPlayer'
POM_SCM_URL = 'https://github.com/KunMinX/Jetpack-MusicPlayer/tree/master'
POM_SCM_CONNECTION = 'scm:git:github.com/KunMinX/Jetpack-MusicPlayer.git'
POM_SCM_DEV_CONNECTION = 'scm:git:ssh://github.com/KunMinX/Jetpack-MusicPlayer.git'

POM_DEVELOPER_ID='KunMinX'
POM_DEVELOPER_NAME='KunMinX'
POM_DEVELOPER_URL='https://github.com/KunMinX'
POM_DEVELOPER_EMAIL='kunminx@gmail.com'
POM_DEVELOPER_ID = 'KunMinX'
POM_DEVELOPER_NAME = 'KunMinX'
POM_DEVELOPER_URL = 'https://github.com/KunMinX'
POM_DEVELOPER_EMAIL = 'kunminx@gmail.com'

LICENSE_NAME='The Apache Software License, Version 2.0'
LICENSE_URL='http://www.apache.org/licenses/LICENSE-2.0.txt'
LICENSE_NAME = 'The Apache Software License, Version 2.0'
LICENSE_URL = 'http://www.apache.org/licenses/LICENSE-2.0.txt'

uploadJavadocs = false
uploadSources = false
Expand Down Expand Up @@ -79,5 +79,9 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
api('com.github.KunMinX:MVI-Dispatcher:6.1.0-beta') {
exclude group: 'com.kunminx.arch', module: 'unpeek-livedata'
}
implementation 'com.google.android.exoplayer:exoplayer:2.18.1'
implementation "androidx.lifecycle:lifecycle-livedata:2.4.1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static DefaultPlayerManager getInstance() {

@Override
public void init(Context context, IServiceNotifier iServiceNotifier, ICacheProxy iCacheProxy) {
mController.init(context.getApplicationContext(), null, iServiceNotifier, iCacheProxy);
mController.init(context.getApplicationContext(), iServiceNotifier, iCacheProxy);
}

@Override
Expand Down
120 changes: 47 additions & 73 deletions player/src/main/java/com/kunminx/player/PlayerController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,22 @@
package com.kunminx.player;

import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.kunminx.player.bean.base.BaseAlbumItem;
import com.kunminx.player.bean.base.BaseArtistItem;
import com.kunminx.player.bean.base.BaseMusicItem;
import com.kunminx.player.bean.dto.ChangeMusic;
import com.kunminx.player.bean.dto.PlayingMusic;
import com.kunminx.player.contract.ICacheProxy;
import com.kunminx.player.contract.IServiceNotifier;
import com.kunminx.player.helper.MediaPlayerHelper;

import java.util.List;

Expand All @@ -42,7 +45,6 @@ public class PlayerController<
A extends BaseArtistItem> {

private final PlayingInfoManager<B, M, A> mPlayingInfoManager = new PlayingInfoManager<>();
private boolean mIsPaused;
private boolean mIsChangingPlayingMusic;

private ICacheProxy mICacheProxy;
Expand All @@ -57,18 +59,13 @@ public class PlayerController<
private final PlayingMusic<B, M, A> mCurrentPlay = new PlayingMusic<>("00:00", "00:00");
private final ChangeMusic<B, M, A> mChangeMusic = new ChangeMusic<>();

public void init(Context context, List<String> extraFormatList,
IServiceNotifier iServiceNotifier,
ICacheProxy iCacheProxy) {
private ExoPlayer mPlayer;
private Handler mHandler = new Handler();

public void init(Context context, IServiceNotifier iServiceNotifier, ICacheProxy iCacheProxy) {
mIServiceNotifier = iServiceNotifier;
mICacheProxy = iCacheProxy;

MediaPlayerHelper.getInstance().initAssetManager(context);

if (extraFormatList != null) {
MediaPlayerHelper.getInstance().getFormatList().addAll(extraFormatList);
}
mPlayer = new ExoPlayer.Builder(context).build();
}

public boolean isInit() {
Expand All @@ -79,6 +76,21 @@ public void loadAlbum(B musicAlbum) {
setAlbum(musicAlbum, 0);
}

private void updateProgress() {
mCurrentPlay.setNowTime(calculateTime(mPlayer.getCurrentPosition() / 1000));
mCurrentPlay.setAllTime(calculateTime(mPlayer.getDuration() / 1000));
mCurrentPlay.setDuration((int) mPlayer.getDuration());
mCurrentPlay.setPlayerPosition((int) mPlayer.getCurrentPosition());
playingMusicLiveData.postValue(mCurrentPlay);
if (mCurrentPlay.getAllTime().equals(mCurrentPlay.getNowTime())) {
if (getRepeatMode() == PlayingInfoManager.RepeatMode.SINGLE_CYCLE) playAgain();
else playNext();
}
mHandler.postDelayed(mProgressAction, 1000);
}

private Runnable mProgressAction = () -> updateProgress();

private void setAlbum(B musicAlbum, int albumIndex) {
mPlayingInfoManager.setMusicAlbum(musicAlbum);
mPlayingInfoManager.setAlbumIndex(albumIndex);
Expand All @@ -91,16 +103,13 @@ public void loadAlbum(B musicAlbum, int albumIndex) {
}

public boolean isPlaying() {
return MediaPlayerHelper.getInstance().getMediaPlayer().isPlaying();
return mPlayer.isPlaying();
}

public boolean isPaused() {
return mIsPaused;
return !mPlayer.getPlayWhenReady();
}

/**
* @param albumIndex 从 album 进来的一定是 album 列表的 index
*/
public void playAudio(int albumIndex) {
if (isPlaying() && albumIndex == mPlayingInfoManager.getAlbumIndex()) {
return;
Expand All @@ -114,85 +123,61 @@ public void playAudio(int albumIndex) {

public void playAudio() {
if (mIsChangingPlayingMusic) {
MediaPlayerHelper.getInstance().getMediaPlayer().stop();
getUrlAndPlay();
} else if (mIsPaused) {
} else if (isPaused()) {
resumeAudio();
}
}

private void getUrlAndPlay() {
String url = null;
M freeMusic = null;
String url;
M freeMusic;
freeMusic = mPlayingInfoManager.getCurrentPlayingMusic();
url = freeMusic.getUrl();

if (TextUtils.isEmpty(url)) {
pauseAudio();
} else {
//涉及到网络请求,因而使用时 请在外部自行判断网络连接状态
MediaItem item;
if ((url.contains("http:") || url.contains("ftp:") || url.contains("https:"))) {
MediaPlayerHelper.getInstance().play(mICacheProxy.getCacheUrl(url));
afterPlay();
item = MediaItem.fromUri(mICacheProxy.getCacheUrl(url));
} else if (url.contains("storage")) {
MediaPlayerHelper.getInstance().play(url);
afterPlay();
item = MediaItem.fromUri(url);
} else {
MediaPlayerHelper.getInstance().playAsset(url);
afterPlay();
item = MediaItem.fromUri(Uri.parse("file:///android_asset/" + url));
}
mPlayer.setMediaItem(item, true);
mPlayer.prepare();
mPlayer.play();
afterPlay();
}
}

private void afterPlay() {
setChangingPlayingMusic(false);
bindProgressListener();
mIsPaused = false;
mHandler.post(mProgressAction);
pauseLiveData.postValue(false);
if (mIServiceNotifier != null) {
mIServiceNotifier.notifyService(true);
}
}

private void bindProgressListener() {
MediaPlayerHelper.getInstance().setProgressInterval(1000).setMediaPlayerHelperCallBack(
(state, mediaPlayerHelper, args) -> {
if (state == MediaPlayerHelper.CallBackState.PROGRESS) {
int position = mediaPlayerHelper.getMediaPlayer().getCurrentPosition();
int duration = mediaPlayerHelper.getMediaPlayer().getDuration();
mCurrentPlay.setNowTime(calculateTime(position / 1000));
mCurrentPlay.setAllTime(calculateTime(duration / 1000));
mCurrentPlay.setDuration(duration);
mCurrentPlay.setPlayerPosition(position);
playingMusicLiveData.postValue(mCurrentPlay);
if (mCurrentPlay.getAllTime().equals(mCurrentPlay.getNowTime())
//容许两秒内的误差,有的内容它就是会差那么 1 秒
|| duration / 1000 - position / 1000 < 2) {
if (getRepeatMode() == PlayingInfoManager.RepeatMode.SINGLE_CYCLE) {
playAgain();
} else {
playNext();
}
}
}
});
}

public void requestLastPlayingInfo() {
playingMusicLiveData.postValue(mCurrentPlay);
changeMusicLiveData.postValue(mChangeMusic);
pauseLiveData.postValue(mIsPaused);
pauseLiveData.postValue(isPaused());
}

public void setSeek(int progress) {
MediaPlayerHelper.getInstance().getMediaPlayer().seekTo(progress);
mPlayer.seekTo(progress);
}

public String getTrackTime(int progress) {
return calculateTime(progress / 1000);
}

private String calculateTime(int time) {
private String calculateTime(long _time) {
int time = (int) _time;
int minute;
int second;
if (time >= 60) {
Expand All @@ -208,54 +193,46 @@ private String calculateTime(int time) {
}
}


public void playNext() {
mPlayingInfoManager.countNextIndex();
setChangingPlayingMusic(true);
playAudio();
}


public void playPrevious() {
mPlayingInfoManager.countPreviousIndex();
setChangingPlayingMusic(true);
playAudio();
}


public void playAgain() {
setChangingPlayingMusic(true);
playAudio();
}


public void pauseAudio() {
MediaPlayerHelper.getInstance().getMediaPlayer().pause();
mIsPaused = true;
mPlayer.pause();
mHandler.removeCallbacks(mProgressAction);
pauseLiveData.postValue(true);
if (mIServiceNotifier != null) {
mIServiceNotifier.notifyService(true);
}
}


public void resumeAudio() {
MediaPlayerHelper.getInstance().getMediaPlayer().start();
mIsPaused = false;
mPlayer.play();
mHandler.post(mProgressAction);
pauseLiveData.postValue(false);
if (mIServiceNotifier != null) {
mIServiceNotifier.notifyService(true);
}
}


public void clear() {
MediaPlayerHelper.getInstance().getMediaPlayer().stop();
MediaPlayerHelper.getInstance().getMediaPlayer().reset();
mPlayer.stop();
mPlayer.clearMediaItems();
pauseLiveData.postValue(true);
//这里设为true是因为可能通知栏清除后,还可能在页面中点击播放
resetIsChangingPlayingChapter();
MediaPlayerHelper.getInstance().setProgressInterval(1000).setMediaPlayerHelperCallBack(null);
if (mIServiceNotifier != null) {
mIServiceNotifier.notifyService(false);
}
Expand All @@ -274,7 +251,6 @@ public B getAlbum() {
return mPlayingInfoManager.getMusicAlbum();
}

//播放列表展示用
public List<M> getAlbumMusics() {
return mPlayingInfoManager.getOriginPlayingList();
}
Expand All @@ -285,7 +261,6 @@ public void setChangingPlayingMusic(boolean changingPlayingMusic) {
mChangeMusic.setBaseInfo(mPlayingInfoManager.getMusicAlbum(), getCurrentPlayingMusic());
changeMusicLiveData.postValue(mChangeMusic);
mCurrentPlay.setBaseInfo(mPlayingInfoManager.getMusicAlbum(), getCurrentPlayingMusic());
// 重置播放时间和进度数据
mCurrentPlay.setNowTime("00:00");
mCurrentPlay.setAllTime("00:00");
mCurrentPlay.setPlayerPosition(0);
Expand Down Expand Up @@ -328,5 +303,4 @@ public void togglePlay() {
public M getCurrentPlayingMusic() {
return mPlayingInfoManager.getCurrentPlayingMusic();
}

}
10 changes: 0 additions & 10 deletions player/src/main/java/com/kunminx/player/PlayingInfoManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,8 @@
*/
public class PlayingInfoManager<B extends BaseAlbumItem<M, A>, M extends BaseMusicItem<A>, A extends BaseArtistItem> {

//index of current playing which maybe Shuffled
private int mPlayIndex = 0;

//index of current playing which user see in the list
private int mAlbumIndex = 0;

//循环模式
private Enum<RepeatMode> mRepeatMode;

public enum RepeatMode {
Expand All @@ -44,13 +39,8 @@ public enum RepeatMode {
RANDOM
}

//原始列表
private final List<M> mOriginPlayingList = new ArrayList<>();

//随机播放列表
private final List<M> mShufflePlayingList = new ArrayList<>();

//专辑详情
private B mMusicAlbum;

boolean isInit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
* Create by KunMinX at 2021/6/11
*/
public interface ICacheProxy {

String getCacheUrl(String url);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
* Create by KunMinX at 18/9/24
*/
public interface IPlayController<B extends BaseAlbumItem<M, A>, M extends BaseMusicItem<A>, A extends BaseArtistItem>
extends ILiveDataNotifier<B, M, A>, IPlayInfoManager<B, M, A> {
extends IPlayNotifier<B, M, A>, IPlayInfoManager<B, M, A> {

//程序启动时就初始化
void init(Context context, IServiceNotifier iServiceNotifier, ICacheProxy iCacheProxy);
Expand Down
Loading

0 comments on commit 356d3eb

Please sign in to comment.