Android流媒体播放器

转载 2012年03月29日 19:35:20
Android流媒体播放器
2011-09-22 13:39:31
标签:android 流媒体播放器 移动开发
今天比较开心,看到论坛上很多人都在询问如何写网络流媒体播放器?是否需要两个播放器轮流交替?因为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);
                            }
                   }
         }
 
}
 

相关文章推荐

Android流媒体播放器

  • 2012年11月23日 19:00
  • 658KB
  • 下载

基于Android平台的流媒体播放器的设计

随着移动通信技术和多媒体技术的迅速发展,融合手机,网络,多媒体技术为一体的视频监控技术也有了长足的进步,通过移动通信网络提供的流媒体服务已成为了可能,全球移动的用户数非常庞大,因此移动流媒体服务具有巨...

android流媒体播放器

  • 2012年08月13日 16:28
  • 792KB
  • 下载

基于ffmpeg的android流媒体播放器

  • 2014年03月19日 09:30
  • 2.5MB
  • 下载

Android流媒体播放器介绍

Android原生流媒体播放Android原生SDK当中有提供流媒体播放API,ViewoView,播放流媒体也挺简单的,但是它支持的流媒体协议有限,例如先前博客里面提到的RTMP,就是不支持的,关于...

Android Studio上手,基于VideoView的本地文件及流媒体播放器

本文描述了Android Studio如何创建工程,以及如何利用VideoView写一个播放本地和网络视频的APP。...
  • fm0517
  • fm0517
  • 2015年06月09日 15:10
  • 15968

EasyPlayer安卓Android流媒体播放器实现直播过程中客户端快照功能

对于一个裸的RTSP URL,存放在播放列表上略显单调与枯燥。大家可以看到EasyPlayer在播放完视频后会保存一帧图片到列表上。那么这个功能是如何做到的呢? 如果自己实现解码的话,比如使用ffm...

Android流媒体播放器

今天比较开心,看到论坛上很多人都在询问如何写网络流媒体播放器?是否需要两个播放器轮流交替?因为Android没有提供像J2me那样的流创建的形式,总之还是不太好写,最近也在研究android流媒体播放...
  • j2eevic
  • j2eevic
  • 2011年02月27日 22:08
  • 1463

EasyPlayer Android RTSP流媒体播放器结构浅析

EasyPlayer 是一款小而美的RTSP安卓播放器。具有起播快、延迟底、兼容性好的特点,而且支持抓拍、录像等实用功能。 好了,我就在此简单介绍一下播放器的代码结构吧!播放简单来说,EasyPla...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android流媒体播放器
举报原因:
原因补充:

(最多只允许输入30个字)