您的位置:首页 > 移动开发 > Android开发

Android --- 多媒体应用开发(边下载边播放)

2017-11-05 14:47 435 查看
       做音乐播放器,有时候会用到系统自带的mediaplayer播放器,这个播放器底层是在linux上面,封装了一些api供使用者调用,由于网络HTTP请求歌曲流这一块的都已经被封装了,所以要想实现歌曲边下载同时还能缓存到我们的文件夹中,需要做的就是从请求过程中间再开辟一个中间代理,通过代理去处理之间的输入输出流,同时在代理中实现本文的功能,这样就能实现我们想要的边下边播了。

边下载边播放

文件头部分只要解析成功,那么内容部分可以后续补充让 MediaPlayer 解析到即可

1 、文件下载(Utils包建一个工具类)

public class MediaDownloader {
private OnDownloadListener onDownloadListener;

public MediaDownloader(OnDownloadListener onDownloadListener) {
this.onDownloadListener = onDownloadListener;
}

/**
* 下载媒体文件
* @param url 下载地址
* @param savePath 保存路径
*/
public void download(String url, String savePath) {
try {
URL link = new URL(url);
HttpURLConnection con = (HttpURLConnection) link.openConnection();
int code = con.getResponseCode();
if (code == 200) {
//获取下载总大小
int len = con.getContentLength();
if (null != onDownloadListener) {
onDownloadListener.onStart(len,savePath);
}
RandomAccessFile rf = new RandomAccessFile(savePath, "rw");
rf.setLength(len);
byte[] buf = new byte[1024];
//当次读取的数量
int num;
//当前下载的量
int count = 0;
InputStream in = con.getInputStream();
while ((num = in.read(buf)) != -1) {
rf.write(buf, 0, num);
count += num;
if (null != onDownloadListener) {
onDownloadListener.onDownloading(count);
}
}
rf.close();
in.close();
}
con.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}

public interface OnDownloadListener {
void onStart(int size,String path);

void onDownloading(int currentSize);
}

public OnDownloadListener getOnDownloadListener() {
return onDownloadListener;
}

public void setOnDownloadListener(OnDownloadListener onDownloadListener) {
this.onDownloadListener = onDownloadListener;
}
}

2 、 MediaPlayer 的解析部分,主要监听当前的下载量,如果已经大于某个值( 1k )并且当前如果没有解码成功,则开始解码,解码出错则重新解码
private void initPlayer() {
if (null == mPlayer) {
mPlayer = new MediaPlayer();
//设置准备监听
mPlayer.setOnPreparedListener(onPreparedListener);
//设置错误监听
mPlayer.setOnErrorListener(onErrorListener);
//设置播放完毕监听
mPlayer.setOnCompletionListener(onCompletionListener);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} else {
mPlayer.reset();
}
//1、让MediaPlayer进入idle状态
}

//开始解析文件
private void setDataAndPlay(String path) {
isStop = false;
//设置播放的数据源
try {
mPlayer.setDataSource(path);
//2、进入initialized状态
//准备
mPlayer.prepareAsync();
} catch (Exception e) {
isStop = true;
}
}
边下载编解码的过程
class DownloadTack extends AsyncTask<String, Integer, Object> implements MediaDownloader.OnDownloadListener {
int lenght; //记录总大小
String savePath;

@Override
protected Object doInBackground(String... params) {
new MediaDownloader(this).download(params[0], params[1]);
return null;
}

@Override
public void onStart(int size, String path) {
lenght = size;
this.savePath = path;
}

@Override
public void onDownloading(int currentSize) {
//更新进度条
if (currentSize >= 1024 && isStop) {
//开始解析
setDataAndPlay(savePath);
}
int currentRate = 100 * currentSize / lenght;
publishProgress(currentRate);
}

@Override
protected void onProgressUpdate(Integer... values) {
mSeek.setSecondaryProgress(values[0]);
}
}
关键点:解码出错时要标记好状态以便于下次再次解码
//(解码)错误监听
private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
playPos = mp.getCurrentPosition();
mp.stop();
mp.reset(); //进入idle状态
isStop = true;
return true;
}
};

以下是自己作为测试的代码:
package com.xykj.mediaplayerdemo;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.SeekBar;

import com.xykj.utils.MediaDownloader;

public class MusicPlayerActivity extends AppCompatActivity implements OnClickListener {
private static final int MSG_UPDATE_POSITION = 1;
//音乐播放对象
private MediaPlayer mPlayer;
private SeekBar mSeek;
//记录出错时的播放位置
private int playPos;
//记录是否停止了
private boolean isStop = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
findViewById(R.id.btn_play).setOnClickListener(this);
findViewById(R.id.btn_pause).setOnClickListener(this);
findViewById(R.id.btn_stop).setOnClickListener(this);
mSeek = (SeekBar) findViewById(R.id.m_seek);
mSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
if (mPlayer != null && mPlayer.isPlaying()) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
}
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (mPlayer != null) {
int pos = seekBar.getProgress(); //获取拖动到的位置
//计算该进度对应的时间轴
int currentPos = pos * mPlayer.getDuration() / 100;
mPlayer.seekTo(currentPos); //设置播放位置
if (mPlayer.isPlaying()) {
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION, 200);
}
}
}
});
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_play:
if (mPlayer == null) {
initPlayer();
new DownloadTack().execute("http://192.168.18.251:8080/MediaServer/music/m1.mp3"
, "/mnt/sdcard/" + System.currentTimeMillis() + ".mp3");
} else {

bb5a
if (!mPlayer.isPlaying()) {
mPlayer.start();
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION, 200);
}
}
break;
case R.id.btn_pause:
if (null != mPlayer && mPlayer.isPlaying()) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
mPlayer.pause();
}
break;
case R.id.btn_stop:
if (null != mPlayer) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
mPlayer.stop();
mPlayer.release();
mPlayer = null;
mSeek.setProgress(0);
}
break;
}
}

private void initPlayer() {
if (null == mPlayer) {
mPlayer = new MediaPlayer();
//设置准备监听
mPlayer.setOnPreparedListener(onPreparedListener);
//设置错误监听
mPlayer.setOnErrorListener(onErrorListener);
//设置播放完毕监听
mPlayer.setOnCompletionListener(onCompletionListener);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
} else {
mPlayer.reset();
}
//1、让MediaPlayer进入idle状态
}

//开始解析文件
private void setDataAndPlay(String path) {
isStop = false;
//设置播放的数据源
try {
mPlayer.setDataSource(path);
//2、进入initialized状态
//准备
mPlayer.prepareAsync();
} catch (Exception e) {
isStop = true;
}
}

private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
isStop = false;
//3、进入onPrepared状态(准备完毕),可以去start、pause、seekTo、stop
//获取总时间
mSeek.setMax(100);
if (playPos > 0) {
mp.seekTo(playPos);
}
mp.start();
//更新播放时间
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION, 200);
}
};

//(解码)错误监听
private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
playPos = mp.getCurrentPosition();
mp.stop();
mp.reset(); //进入idle状态
isStop = true;
return true;
}
};

//播放完毕监听
private MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mHandler.removeMessages(MSG_UPDATE_POSITION);
}
};

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == MSG_UPDATE_POSITION) {
if (mPlayer != null) {
int pos = mPlayer.getCurrentPosition(); //获取当前的播放时间
int duration = mPlayer.getDuration();
int position = 100 * pos / duration;
mSeek.setProgress(position);
sendEmptyMessageDelayed(MSG_UPDATE_POSITION, 200);
}
}
}
};

class DownloadTack extends AsyncTask<String, Integer, Object> implements MediaDownloader.OnDownloadListener {
int lenght; //记录总大小
String savePath;

@Override
protected Object doInBackground(String... params) {
new MediaDownloader(this).download(params[0], params[1]);
return null;
}

@Override
public void onStart(int size, String path) {
lenght = size;
this.savePath = path;
}

@Override
public void onDownloading(int currentSize) {
//更新进度条
if (currentSize >= 1024 && isStop) {
//开始解析
setDataAndPlay(savePath);
}
int currentRate = 100 * currentSize / lenght;
publishProgress(currentRate);
}

@Override
protected void onProgressUpdate(Integer... values) {
mSeek.setSecondaryProgress(values[0]);
}
}

@Override
protected void onStop() {
super.onStop();
if (null != mPlayer) {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
}
}


以下就是大致的实现图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多媒体 mediaplayer