手把手叫你制作一个精美的在线音乐播放器

最近项目中要增加一些特殊的功能,实现音乐的在线播放。虽说网上源码一大把,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.csdn.net/detail/androidstarjack/9690396

另外你觉得此篇文章对您有所帮助 请关注终端研发部,QQ交流群 :232203809



展开阅读全文

没有更多推荐了,返回首页