今天比较开心,看到论坛上很多人都在询问如何写网络流媒体播放器?是否需要两个播放器轮流交替?因为Android没有提供像J2me那样的流创建的形式,总之还是不太好写,最近也在研究android流媒体播放,这里提供一个很早之前写的demo,以供大家相互学习和参考。


/**

* Android提供的接口仍然是不能直接通过流创建Player,但是Android提供了很全面的文件系统接口,现在用一种新的方法来解决: <br>

* <1>,把下载下来的数据先写到临时的文件中 <br>

* <2>,用临时文件创建Player<br>

* todo: <br>

* <1>,清理没有用的临时文件。<br>

* <2>,暂停逻辑的优化。---抛出异常。。。。<br>

* <3>,分段下载的逻辑处理,这和<2>有关系。<br>

* <4>,整体优化

*

* @author shenrenkui

*

*/

public class AudioPlayer implements OnErrorListener, OnBufferingUpdateListener,

MediaPlayer.OnCompletionListener {

private static final String TAG = "AudioPlayer";

private MediaPlayer mPlayer;

private String current;

private static final int MIN_BUFF = 100 * 1024;

private int totalKbRead = 0;

private Handler handler = new Handler();

private File DLTempFile;

private File BUFFTempFile;

private final String TEMP_DOWNLOAD_FILE_NAME = "tempMediaData";

private final String TEMP_BUFF_FILE_NAME = "tempBufferData";

private final String FILE_POSTFIX = ".dat";

private final int PER_READ = 1024;

private boolean pause;

private boolean stop;

private final int UNKNOWN_LENGTH = -1;

private Handler mHandler = null;



public void setHandler(Handler handler) {

mHandler = handler;

}



public void play(final String path) {

downloadOver = false;

totalKbRead = 0;

try {

Log.v(TAG, "playing: " + path);

if (path.equals(current) && mPlayer != null) {

mPlayer.start();

return;

}

current = path;

mPlayer = null;

new PlayThread(current).start();

} catch (Exception e) {



}

}



private void setListener() {

if (mPlayer != null) {

mPlayer.setOnErrorListener(this);

mPlayer.setOnBufferingUpdateListener(this);

mPlayer.setOnCompletionListener(this);

}

}



/**

* 下载数据,分段下载

* todo:联网方式和分段

* @param mediaUrl

* @param start

* @param end

*/

private void playFromNet(String mediaUrl, int start, int end) {

URLConnection cn = null;

FileOutputStream out = null;

InputStream is = null;

try {

cn = new URL(mediaUrl).openConnection();

cn.connect();

is = cn.getInputStream();

int mediaLength = cn.getContentLength();

if (is == null) {

return;

}

deleteTempFile(true);

DLTempFile = File.createTempFile(TEMP_DOWNLOAD_FILE_NAME,

FILE_POSTFIX);

out = new FileOutputStream(DLTempFile);

byte buf[] = new byte[PER_READ];

int readLength = 0;

while (readLength != -1 && !stop) {

if (pause) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

continue;

}

readLength = is.read(buf);

if (readLength > 0) {

try {

out.write(buf, 0, readLength);

totalKbRead += readLength;

} catch (Exception e) {

Log.e(TAG, e.toString());

}

}

dealWithBufferData();

}

if (totalKbRead == mediaLength) {

downloadOver = true;

dealWithLastData();

// 删除临时文件

if (DLTempFile != null && DLTempFile.exists()) {

DLTempFile.delete();

}

}

} catch (MalformedURLException e) {

Log.e(TAG, e.toString());

} catch (IOException e) {

Log.e(TAG, e.toString());

} finally {

if (out != null) {

try {

out.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (is != null) {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}



private boolean downloadOver = false;

private boolean wasPlayed = false;



private void dealWithBufferData() {

if (mPlayer == null || !wasPlayed) {

if (totalKbRead >= MIN_BUFF) {

try {

startMediaPlayer();

} catch (Exception e) {

}

}

} else if (mPlayer.getDuration() - mPlayer.getCurrentPosition() <= 1000) {

deleteTempFile(true);

transferBufferToMediaPlayer();

}

}



private void startMediaPlayer() {

try {

deleteTempFile(true);

BUFFTempFile = File.createTempFile(TEMP_BUFF_FILE_NAME,

FILE_POSTFIX);

FileSystemUtil.copyFile(DLTempFile, BUFFTempFile);

mPlayer = new MediaPlayer();

setListener();

mPlayer.setDataSource(BUFFTempFile.getAbsolutePath());

mPlayer.prepare();

mPlayer.start();

wasPlayed = true;

} catch (IOException e) {



}

}



private void transferBufferToMediaPlayer() {

try {

boolean wasPlaying = mPlayer.isPlaying();

int curPosition = mPlayer.getCurrentPosition();

mPlayer.pause();

BUFFTempFile = File.createTempFile(TEMP_BUFF_FILE_NAME,

FILE_POSTFIX);

FileSystemUtil.copyFile(DLTempFile, BUFFTempFile);

mPlayer = new MediaPlayer();

mPlayer.setDataSource(BUFFTempFile.getAbsolutePath());

mPlayer.prepare();

mPlayer.seekTo(curPosition);

boolean atEndOfFile = mPlayer.getDuration()

- mPlayer.getCurrentPosition() <= 1000;

if (wasPlaying || atEndOfFile) {

mPlayer.start();

}

} catch (Exception e) {

}

}



private void dealWithLastData() {

Runnable updater = new Runnable() {

public void run() {

transferBufferToMediaPlayer();

}

};

handler.post(updater);

}



public void onCompletion(MediaPlayer mp) {

if (mHandler != null) {

mHandler.sendEmptyMessage(Preferences.MEDIA_ENDED);

}

}



public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {

if (mediaPlayer != null) {

mediaPlayer.stop();

mediaPlayer.release();

}

if (mHandler != null) {

mHandler.sendEmptyMessage(Preferences.MEDIA_ERROR);

}

return true;

}



public void onBufferingUpdate(MediaPlayer arg0, int percent) {

Log.d(TAG, "onBufferingUpdate called ---> percent:" + percent);

if (mHandler != null) {

mHandler.sendEmptyMessage(Preferences.EMDIA_BUFF_CHANGE);

}

}



private class PlayThread extends Thread {

private String url;



PlayThread(String url) {

this.url = url;

}



public void run() {

if (!URLUtil.isNetworkUrl(url)) {

mPlayer = new MediaPlayer();

setListener();

try {

// if (url.startsWith("content://")) {

// mPlayer.setDataSource(MediaPlayService.this, Uri

// .parse(url));

// } else {

mPlayer.setDataSource(url);

// }

mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

setVolume(0f);

mPlayer.prepare();

mPlayer.start();

} catch (IllegalArgumentException e) {

Log.e(TAG, e.toString());

} catch (IllegalStateException e) {

Log.e(TAG, e.toString());

} catch (IOException e) {

Log.e(TAG, e.toString());

}

} else {

playFromNet(url, 0, UNKNOWN_LENGTH);

}

}

}



}

更多相关文章

  1. 在Android中创建和使用数据库
  2. 解决 Android(安卓)在Eclipse 开发中 Class Not Found 的问题
  3. android中AVD的使用
  4. 获取Android(安卓)SDK 源代码并在Eclipse中关联查看的方法(for s
  5. Android开发实例源代码批量下载
  6. Android存储-SQLite数据库存储数据(三)
  7. android流媒体播放器
  8. ArcGIS for Android(安卓)支持模拟器开发
  9. Android应用程序窗口(Activity)的运行上下文环境(Context)的创建过程

随机推荐

  1. Android真的很火吗?
  2. Android(安卓)UI系列
  3. Android(安卓)RelativeLayout 相对布局解
  4. 深入解读Linux与Android的相互关系
  5. android makefile(转载)
  6. Android教程之一:Window下搭建Android开发
  7. Android教程之一:Window下搭建Android开发
  8. Android魔术——手把手教你实现水晶球波
  9. Android(安卓)启动流程
  10. Android的BUG - 广为人知的诟病:频繁重启