昨天做了一天使用MediaPlayer播放音频,然并卵,完成不了需求,但无论怎样也算是有所收获。
我想要完成的效果是(1)边下载(缓存)边播放
出现的问题是 a.实现不了边下载边播放 b.使用进度条记录下载进度效果不理想。
先说一下边下载边播放实现不了的原因:
在MediaPlayer播放音频的时候分为若干个状态。实例化一个MediaPlayer mp 可以为其分配资源;
1) mp.setDataSource(url);调用该方法的时候会出现异常,一个好的编程习惯是要进行异常捕获。这个时候MediaPlayer处于Initialized;
2)上一步为其分配了数据源之后就要获取数据源(应该可以说成是下载或者缓存数据吧?)可供调用的方法有两个mp.prepare()或者mp.prepareAsync();两个方法的区别是,prepare()是同步,prepareAsync()是异步,也就是说当调用prepareAsync()方法时不需要等待下载完成就可以继续向下执行。在数据加载的过程中MediaPlayer处于preparing状态。加载完成之后处于prepared状态!
通过以上两个阶段就完成了数据的初始化,和数据的准备。那么为什么不能实现边下载边播放呢?
播放音频调用的方法为mp.start();而start()方法只有处于prepared状态时才能被调用!!!这也就是说当其处于下载状态(preparing)时,是没有办法调用start()方法的。怎么办啊,怎么办,流媒体什么的是不是要去了解一下?
使用进度条记录播放进度是比较准确的;可以通过一下方式记录播放进度:
//通过定时器和Handler完成进度条的更新
TimerTask mTimerTask = new TimerTask() {
@Override
public void run() {
if(mp==null)
return;
是播放的状态,seekbar不是被挤压的状态
if (mp.isPlaying() && skbProgress.isPressed() == false) {
handleProgress.sendEmptyMessage(0);
handleProgress= newHandler() {
public void handleMessage(Message msg) {
int position = mp.getCurrentPosition();
int duration = mp.getDuration();
if (duration > 0) {
long pos = skbProgress.getMax() * position / duration;
skbProgress.setProgress((int) pos);
但是记录缓冲的进度是效果不尽如人意,我实现了OnBufferingUpdateListener这个接口,这个接口中的方法
@Override
public voidonBufferingUpdate(MediaPlayer arg0, int bufferingProgress) {
记录的是加载时候的进度的% 值为1-100
skbProgress.setSecondaryProgress(bufferingProgress);
intcurrentProgress=skbProgress.getMax()*mediaPlayer.getCurrentPosition()/mediaPlayer.getDuration();
Log.e(currentProgress+"% play", bufferingProgress + "% buffer");
这里的bufferingProgress并没有按照我预计的样子从1一直变到100而是跳跃式的增长,这样也会使seekbar跳跃式的增长,通过多次测试,第一个数值均为70多,然后直接跳到100,严重影响了用户体验。