最近项目中要增加一些特殊的功能,实现音乐的在线播放。虽说网上源码一大把,demo一大堆,但是能用的其实寥寥无几,看来关键时刻还是自己动手,丰衣足食啊。话不多说,直接看效果图吧:
看是不是很美观。
该功能主要是实现:从后台请求一个音乐地址,进而实现在线播放,且能够支持暂停,快进,以及播放进度条,播放时间等。
代码不是很多,主要是用MediaPlayer重要工具类
这里控制着音乐的播放,暂停,开始播放等播放状态。
public void play() {
new Thread(new Runnable() {
@Override
public void run() {
if (player.mediaPlayer.isPlaying() || getPlayStatus() == PlayStatus.PLAYING) {
player.pause();
setPlayStatus(PlayStatus.PAUSE);
} else if(getPlayStatus() == PlayStatus.NOPLAY || getPlayStatus() == PlayStatus.FINISH){
if(getPlayStatus() == PlayStatus.FINISH){
player.mediaPlayer.reset();//重置MediaPlayer到初始化状态
player.mediaPlayer.seekTo(0);//须将播放时间设置到0;这样才能在下次播放是重新开始,否则会继续上次播放
}
player.playUrl(URLMUSIC);
setPlayStatus(PlayStatus.PLAYING);
}else if(getPlayStatus() == PlayStatus.PAUSE){
player.start();//继续播放
setPlayStatus(PlayStatus.PLAYING);
}
}
}).start();
}
这里要注意的是:
player.mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Long totleLong = new Long((long) player.mediaPlayer.getDuration());
Long currentLong = new Long((long) player.mediaPlayer.getCurrentPosition());
String totleTime = formatter.format(mp.getDuration());
String currentTime = formatter.format((mp.getCurrentPosition()));
LogUtil.e(TAG,"totle: " +totleTime+"当前: " + currentTime);
if(mp.isPlaying()){//减少误差,避免得到getDuration()的时间出问题---->在这里花费了好多的时间
mySeekProgressListener.onMySeekProgressData(totleTime,currentTime,0);
if(totleTime.equals(currentTime)){//用这样的方式判断完成,减少时间的误差
LogUtil.e(TAG,"我进来啦!!!");
setPlayStatus(PlayStatus.FINISH);
player.mediaPlayer.pause();
// player.mediaPlayer.release();
}
}
}
});
这里的 setOnBufferingUpdateListener是用于音乐或者视频在线缓冲的更新监听器
public class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
int progress;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
LogUtil.e(TAG,"totle: " +player.mediaPlayer.getDuration());
this.progress = progress * player.mediaPlayer.getDuration() / seekBar.getMax();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
player.mediaPlayer.seekTo(progress);
if(getPlayStatus() == PlayStatus.FINISH) {
play();
}
}
}
这里是坚挺拖动条的拖动状态,用于显示在线音乐的进度,当然是SeekBar能进行拖动。
以下是全部代码:
public class MainActivity extends Activity implements View.OnClickListener{
private final int MUSIC_FINISH = 1000;
@Bind(R.id.iv_bg_music)
ImageView iv_bg_music;
@Bind(R.id.titlebar_back_music)
ImageView titlebar_back_music;
@Bind(R.id.titlebar_title_music)
TextView titlebar_title_music;
@Bind(R.id.ib_paly_music)//播放音乐
ImageButton ib_paly_music;
@Bind(R.id.ll_to_play)//播放音乐
LinearLayout ll_to_play;
@Bind(R.id.tv_time_progress)//正在播放的时间
TextView tv_time_progress;
@Bind(R.id.tv_time_totle)//播放总时间
TextView tv_time_totle;
@Bind(R.id.sb_music_progress)//播放拖动条
SeekBar sb_music_progress;
private MusicPlay mausicPlay;
private SimpleDateFormat formatter;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case MUSIC_FINISH:
tv_time_progress.setText("0:00");//播放完毕后,重新设置没有播放的状态
sb_music_progress.setProgress(0);
ib_paly_music.setBackgroundResource(R.drawable.iv_paly);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initListener();
initView();
}
private void initView() {
formatter = new SimpleDateFormat("mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
mausicPlay = MusicPlay.getInstance(this).setMySeekListener(sb_music_progress)
.setMySeekProgressListener(new MusicPlay.MySeekProgressListener() {
@Override
public void onMySeekProgressData(String totleTime, String currentTime,int finishStatus) {
if(finishStatus == 100){//播放完毕
LogUtil.e("yuyahao","mian 时间 放放完啦!!! ");
}else{
tv_time_totle.setText(totleTime);
if(totleTime.equals(currentTime)){//用时间字符串进行比较,防止出现两次的时间结束状态
handler.postDelayed(new Runnable() {
@Override
public void run() {
Message msg = handler.obtainMessage();
msg.what = MUSIC_FINISH;
handler.sendMessage(msg);
}
}, 800);
}else{
tv_time_totle.setText(totleTime);
tv_time_progress.setText(currentTime);
}
}
}
});
ib_paly_music.setTag(R.drawable.iv_stop_paly);
ib_paly_music.setBackgroundResource(R.drawable.iv_paly);
}
private void initListener() {
ib_paly_music.setOnClickListener(this);
titlebar_back_music.setOnClickListener(this);
ll_to_play.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ll_to_play:
case R.id.ib_paly_music://博faNG或者是暂停
Integer tag = (Integer) ib_paly_music.getTag();
if(mausicPlay.isPlayIng()){//正在播放,去暂停播放
ib_paly_music.setBackgroundResource(R.drawable.iv_paly);
}else{//去进行播放
ib_paly_music.setBackgroundResource(R.drawable.iv_stop_paly);
}
mausicPlay.play();
break;
case R.id.titlebar_back_music:
onBackPressed();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mausicPlay != null){
mausicPlay.onDestroy();
}
}
@Override
public void onBackPressed() {
if(mausicPlay.isPlayIng()){
}else{
super.onBackPressed();
}
}
}
工具类:
/**
* Created by fei on 2016/11/12.
* 音乐在线播放 工具类
*/
public class MusicPlay {
private static final String TAG = "yyh";
private static Player player;
private static MusicPlay musicPlay;
private String URLMUSIC = "http://abv.cn/music/红豆.mp3";
private Context context;
private static PlayStatus isPlaystatic = PlayStatus.NOPLAY;//播放状态:默认0不播放, 1:开始博播放 ,2是暂停播放 ,3:是播放完毕
private static SimpleDateFormat formatter;
//private SeekBar sb_music_progress;//当前播放的拖动条
public enum PlayStatus{
NOPLAY(0),//默认0不播放
PLAYING(1),//,1:开始博播放
PAUSE(2),//,2是暂停播放
FINISH(3);//3:是播放完毕
private int status;
PlayStatus(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
public MusicPlay(Context context) {
this.context = context;
}
public static void setPlayStatus(PlayStatus isPlaystatic){
MusicPlay.isPlaystatic = isPlaystatic;
}
public PlayStatus getPlayStatus(){
return this.isPlaystatic;
}
public static MusicPlay getInstance(Context context) {
if (musicPlay == null) {
musicPlay = new MusicPlay(context);
formatter = new SimpleDateFormat("mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
}
return musicPlay;
}
public MusicPlay setMySeekListener(SeekBar sb_music_progress){
sb_music_progress.setOnSeekBarChangeListener(new SeekBarChangeEvent());
player = new Player(sb_music_progress);
initSetMediaPlaylistener();
return musicPlay;
}
public MusicPlay setMySeekProgressListener(MySeekProgressListener mySeekProgressListener){
this.mySeekProgressListener = mySeekProgressListener;
return musicPlay;
}
private static MySeekProgressListener mySeekProgressListener;
public interface MySeekProgressListener{
void onMySeekProgressData(String totleTime, String currentTime, int finishStatus);
}
/**
* 是否在进行播放
* @return
*/
public boolean isPlayIng(){
return player.mediaPlayer.isPlaying();
}
/**
* 释放资源
*/
public void release(){
player.mediaPlayer.release();
}
public void play() {
new Thread(new Runnable() {
@Override
public void run() {
if (player.mediaPlayer.isPlaying() || getPlayStatus() == PlayStatus.PLAYING) {
player.pause();
setPlayStatus(PlayStatus.PAUSE);
} else if(getPlayStatus() == PlayStatus.NOPLAY || getPlayStatus() == PlayStatus.FINISH){
if(getPlayStatus() == PlayStatus.FINISH){
player.mediaPlayer.reset();//重置MediaPlayer到初始化状态
player.mediaPlayer.seekTo(0);//须将播放时间设置到0;这样才能在下次播放是重新开始,否则会继续上次播放
}
player.playUrl(URLMUSIC);
setPlayStatus(PlayStatus.PLAYING);
}else if(getPlayStatus() == PlayStatus.PAUSE){
player.start();//继续播放
setPlayStatus(PlayStatus.PLAYING);
}
}
}).start();
}
/**
* 开始播放
*/
public void startPlay() {
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
}
/**
* 停止播放
*/
public void stopPlay() {
}
/**
* 继续播放
*/
public void continuePlay() {
}
private static void initSetMediaPlaylistener(){
/*player.mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Long totleLong = new Long((long) player.mediaPlayer.getDuration());
mySeekProgressListener.onMySeekProgressData(totleLong,0L,100);
LogUtil.i(TAG, mp.getDuration()+"我已完成啦!!!!");
}
});*/
player.mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Long totleLong = new Long((long) player.mediaPlayer.getDuration());
Long currentLong = new Long((long) player.mediaPlayer.getCurrentPosition());
String totleTime = formatter.format(mp.getDuration());
String currentTime = formatter.format((mp.getCurrentPosition()));
LogUtil.e(TAG,"totle: " +totleTime+"当前: " + currentTime);
if(mp.isPlaying()){//减少误差,避免得到getDuration()的时间出问题---->在这里花费了好多的时间
mySeekProgressListener.onMySeekProgressData(totleTime,currentTime,0);
if(totleTime.equals(currentTime)){//用这样的方式判断完成,减少时间的误差
LogUtil.e(TAG,"我进来啦!!!");
setPlayStatus(PlayStatus.FINISH);
player.mediaPlayer.pause();
// player.mediaPlayer.release();
}
}
}
});
}
public class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {
int progress;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
LogUtil.e(TAG,"totle: " +player.mediaPlayer.getDuration());
this.progress = progress * player.mediaPlayer.getDuration() / seekBar.getMax();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
player.mediaPlayer.seekTo(progress);
if(getPlayStatus() == PlayStatus.FINISH) {
play();
}
}
}
/**
* 销毁时
*/
public void onDestroy() {
if (player != null && player.mediaPlayer.isPlaying()) {
player.stop();
// player.mediaPlayer.pause();
player = null;
}
setPlayStatus(PlayStatus.NOPLAY);
}
public void palyByMobileSevice(){
Intent intent = new Intent();
Uri uri = Uri.parse(URLMUSIC);
intent.setDataAndType(uri, "audio/mp3");// intent.setDataAndType(uri, "audio/*");这里可以改成audio/mp3
intent.setAction(Intent.ACTION_VIEW);
context.startActivity(intent);
}
}
最后一个:
public class Player implements OnBufferingUpdateListener, OnCompletionListener,OnPreparedListener{
public MediaPlayer mediaPlayer;
private SeekBar seekBar;
private Timer mTimer = new Timer();
public Player(SeekBar seekBar) {
super();
this.seekBar = seekBar;
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnPreparedListener(this);
} catch (Exception e) {
e.printStackTrace();
}
mTimer.schedule(timerTask, 0, 1000);
}
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
if (mediaPlayer == null)
return;
if (mediaPlayer.isPlaying() && seekBar.isPressed() == false) {
handler.sendEmptyMessage(0);
}
}
};
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
int position = mediaPlayer.getCurrentPosition();
int duration = mediaPlayer.getDuration();
if (duration >= 0) {
long pos = seekBar.getMax() * position / duration;
seekBar.setProgress((int) pos);
}
};
};
public void play() {
mediaPlayer.start();
}
/**
*
* @param url
*/
public void playUrl(String url) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
// 通过异步的方式装载媒体资源
/*mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// 装载完毕回调
mediaPlayer.start();
}
});*/
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void pause() {
mediaPlayer.pause();
}
public void start() {
mediaPlayer.start();
}
public void stop() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
Log.e("mediaPlayer", "onPrepared");
}
@Override
public void onCompletion(MediaPlayer mp) {
Log.e("mediaPlayer", "onCompletion");
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
seekBar.setSecondaryProgress(percent);
int currentProgress = seekBar.getMax()
* mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration();
Log.e(currentProgress + "% play", percent + " buffer");
}
}
但是到了最后竟然忘记写权限了:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
否则就会播放不出来。报一些其他类型的错误。
好了,最后贴上项目地址:http://download.youkuaiyun.com/detail/androidstarjack/9690396
另外你觉得此篇文章对您有所帮助 请关注终端研发部,QQ交流群 :232203809