转载自

Android MediaPlayer使用方法简单介绍

播放音频

  android中播放音频可以使用MediaPlayer类来实现,一下是它的一些方法:

              方法名             功能描述
            setDataSource()        设置要播放的音频文件的位置。
            prepare()            在开始播放之前调用这个方法完成准备工作。
            start()               开始或继续播放音频。
            pause()               暂停播放音频。
            reset()              将 MediaPlayer 对象重置到刚刚创建的状态。
            seekTo()             从指定的位置开始播放音频。
            stop()                     停止播放音频。调用这个方法后的 MediaPlayer 对象无法再播放音频。
            release()             释放掉与 MediaPlayer 对象相关的资源。
            isPlaying()             判断当前 MediaPlayer 是否正在播放音频。
            getDuration()           获取载入的音频文件的时长。

 在安卓系统中,播放音频最简单的方法是使用内置的媒体播放器(MediaPlayer类)。MediaPlayer既可以播放本地文件,也可以播放来自URL的网络数据流。
1)如何获得MediaPlayer实例:
可以使用直接new的方式:
MediaPlayer mp = new MediaPlayer();
也可以使用create的方式,如:
MediaPlayer mp = MediaPlayer.create(this, R.raw.test);//这时就不用调用setDataSource了
 
2) 如何设置要播放的文件:
MediaPlayer要播放的文件主要包括3个来源:
a. 用户在应用中事先自带的resource资源
例如:MediaPlayer.create(this, R.raw.test);
b. 存储在SD卡或其他文件路径下的媒体文件
例如:mp.setDataSource("/sdcard/test.mp3");
 
c. 网络上的媒体文件
例如:mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");
 
MediaPlayer的setDataSource一共四个方法:
setDataSource (String path)
setDataSource (FileDescriptor fd)
setDataSource (Context context, Uri uri)
setDataSource (FileDescriptor fd, long offset, long length)
 
其中使用FileDescriptor时,需要将文件放到与res文件夹平级的assets文件夹里,然后使用:
AssetFileDescriptor fileDescriptor = getAssets().openFd("rain.mp3");
m_mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(), fileDescriptor.getLength());
来设置datasource
 
3)对播放器的主要控制方法:
Android通过控制播放器的状态的方式来控制媒体文件的播放,其中:
prepare()和prepareAsync() 提供了同步和异步两种方式设置播放器进入prepare状态,需要注意的是,如果MediaPlayer实例是由create方法创建的,那么第一次启动播放前不需要再调用prepare()了,因为create方法里已经调用过了。
start()是真正启动文件播放的方法,
pause()和stop()比较简单,起到暂停和停止播放的作用,
seekTo()是定位方法,可以让播放器从指定的位置开始播放,需要注意的是该方法是个异步方法,也就是说该方法返回时并不意味着定位完成,尤其是播放的网络文件,真正定位完成时会触发OnSeekComplete.onSeekComplete(),如果需要是可以调用setOnSeekCompleteListener(OnSeekCompleteListener)设置监听器来处理的。
release()可以释放播放器占用的资源,一旦确定不再使用播放器时应当尽早调用它释放资源。
 
reset()可以使播放器从Error状态中恢复过来,重新会到Idle状态。在重置MediaPlayer的时候使用,重置完,重新setDataResource prepare start,播放下一首
 
4)设置播放器的监听器:
MediaPlayer提供了一些设置不同监听器的方法来更好地对播放器的工作状态进行监听,以期及时处理各种情况,
如: setOnCompletionListener(MediaPlayer.OnCompletionListener listener)、
setOnErrorListener(MediaPlayer.OnErrorListener listener)等,设置播放器时需要考虑到播放器可能出现的情况设置好监听和处理逻辑,以保持播放器的健壮性。

1、创建MediaPlayer实例

有两种创建MediaPlayer实例的办法,

办法1:

MediaPlayer player = MediaPlayer.Create(this, Resource.Raw.test);

用MediaPlayer.Create创建实例时可直接指定数据源。

办法2:

MediaPlayer player = new MediaPlayer();

2、数据源

有3种。

(1)播放raw文件夹下的资源文件

应用程序自带的音乐资源一般保存到raw文件夹下,下面的代码演示了如何播放Resource/raw下的媒体文件:

MediaPlayer mPlayer=MediaPlayer.Create(this, Resource.Raw.MyAudio);

mPlayer.Start();

注意:这种方式主要适用于播放应用程序自带的容量较小的资源文件,例如接听电话时播放的音乐、按键音、开机启动音、信息提示音等都可以随应用程序一块发布。

(2)播放来自文件系统的媒体文件

指播放Android默认的系统标准文件夹下、Assets文件夹下、SD卡中的媒体文件,这些文件都属于文件系统。

以下描述了使用MediaPlayer从文件系统中播放音频的步骤:

  • 初始化MediaPlayer对象。
  • 通过SetDataSource方法(同步方式)或者SetDataSourceAsync方法(异步方式)设置要播放的文件。
  • 调用Prepare方法(同步方式)或者PrepareAsync方法(异步方式)初始化播放器。
  • 调用Start方法开始音频播放。
  • 注意采用这种方式时,播放顺序非常重要:先设置数据源、同步播放设备,最后再调用Start方法播放。

利用MediaPlayer与surfaceView相结合实现视频播放的效果

  1. 加载本地资源
  1. /**加载本地资源
  2. * 主要步骤:
  3. * 1.创建MediaPlayer播放器
  4. * 1.MediaPlayer.create(this,"本地资源文件");
  5. * 2.得到SurfaceHolder对象,surfaceView.getHolder()
  6. * 3.surfaceHolder绑定生命周期 surfaceHodler.addCallBack(new CallBack(){...})
  7. * 4.在surfaceHolder监听的回调里面,与视频播放器进行绑定(surfaceCreated)
  8. * mediaPlayer.setDisplay(surfaceHolder)
  9. * 5.视频播放器播放视频
  10. * mediaPlayer.start();
  11. */
  1. 加载网络资源
  1. /**
  2. * 加载网络资源
  3. *主要步骤:
  4. * 1.创建MediaPlayer播放器
  5. * new MediaPlayer();
  6. * 2.设置数据源
  7. * mediaPlayer.setDataSource(context,uri);
  8. * // meidaPlayer.setDataSource(path)
  9. * 3. .得到SurfaceHolder对象,surfaceView.getHolder()
  10. * 4.surfaceHolder绑定生命周期 surfaceHodler.addCallBack(new CallBack(){...})
  11. * 5.在surfaceHolder监听的回调里面,与视频播放器进行绑定(surfaceCreated)
  12. * mediaPlayer.setDisplay(surfaceHolder)
  13. * 6.准备
  14. * mediaPlayer.prepareAsync()//异步准备
  15. * mediaPlayer.prepare()//同步准备
  16. * 7.设置准备监听器
  17. * mediaPlayer.setOnPreparedListener(new PreparedListener(){});
  18. * 8.在准备监听器里开启mediaPlayer
  19. * mediaPlayer.start();
  20. *
  21. *
  22. * //注意:
        1.加载网络资源出现了bug,原因:设置异步准备时,会调用准备监听器来开启媒体播放器,同时主线程也会继续执行,通过播放器获取时长时,会出现媒体播放器无效的错误,因为播放器还没有开启播放.
          解决:将异步准备后的操作都放在准备监听里面实现,
        2.meidiaPlayer调用stop方法后可以再次播放视频,但需要用reset让meidiaPlayer对象回到初始状态,再重新设置资源
  23. *
  24. */

xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context="fanggao.qf.surfaceview_vedioplayer.MainActivity">
  7. <FrameLayout
  8. android:id="@+id/fl_layout"
  9. android:layout_width="match_parent"
  10. android:layout_height="300dp">
  11. <SurfaceView
  12. android:id="@+id/surfaceView"
  13. android:layout_width="match_parent"
  14. android:layout_height="300dp" />
  15. <ImageView
  16. android:id="@+id/iv_play"
  17. android:layout_width="match_parent"
  18. android:layout_height="match_parent"
  19. android:src="@android:drawable/ic_media_play"/>
  20. </FrameLayout>
  21. <LinearLayout
  22. android:layout_width="match_parent"
  23. android:layout_height="50dp"
  24. android:layout_below="@id/fl_layout">
  25. <ImageView
  26. android:id="@+id/iv_play_controll"
  27. android:layout_width="wrap_content"
  28. android:layout_height="match_parent"
  29. android:src="@android:drawable/ic_media_play"/>
  30. <SeekBar
  31. android:id="@+id/sb_progress"
  32. android:layout_width="0dp"
  33. android:layout_height="match_parent"
  34. android:layout_weight="1"/>
  35. <TextView
  36. android:id="@+id/tv_time"
  37. android:layout_width="wrap_content"
  38. android:layout_height="match_parent"
  39. android:text="00:00:00/00:00:00"
  40. android:gravity="center_vertical"/>
  41. </LinearLayout>
  42. </RelativeLayout>

案列分析:

  1. /**
  2. * 1.初始化控件
  3. * 0.初始化媒体播放器
  4. * 1.准备资源,并创建播放器
  5. * 1.找到surfaceView,并创建生命周期
  6. * 1.创建surfaceView
  7. * 1.surfaceView跟视频播放控件绑定
  8. * 2.销毁surfaceView
  9. * 释放资源
  10. * 2.播放图标显示
  11. * 3.控制台显示播放图标
  12. * 2.初始化事件
  13. * 1.点击播放按钮-变为播放
  14. * 1.当前播放按钮隐藏
  15. * 2.控制条显示暂停图标
  16. * 3.视频开始播放
  17. *
  18. * 2.点击控制台
  19. * 1.点击播放
  20. * 1.控制台显示暂停图标
  21. * 2.隐藏当前的播放按钮
  22. * 3.视频开始播放
  23. * 2.点击暂停
  24. * 1.控制台按钮显示播放图标
  25. * 2..当前播放按钮显示
  26. * 3.视频暂停播放
  27. * 3.拖到进度条
  28. * 1.跳到对应的位置播放
  29. * 2.更新时间
  30. *
  31. * 3.初始化动态视图
  32. * 2.更新控制台显示
  33. * 1..拿到视频总长度
  34. * 1.开启线程
  35. * 1.更新seekBar进度
  36. * 1.拿到当前进度
  37. * 2.计算当前seekBar的值
  38. * 3.发送到主线程
  39. * 4.更新
  40. * 1.更新seekBar的值
  41. * 2.更新时间进度
  42. * 1s更新一次
  43. * 3.播放完成设置监听
  44. * 4.释放资源
  45. */

源代码:

  1. public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,View.OnClickListener,SeekBar.OnSeekBarChangeListener,MediaPlayer.OnCompletionListener{
  2. /*显示视频资源*/
  3. private SurfaceView surfaceView;
  4. /*拖动条显示当前进度*/
  5. private SeekBar sb_progress;
  6. /*surface的控制器,用来操纵surfaceView。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。*/
  7. private SurfaceHolder holder;
  8. /*媒体播放器播放音频*/
  9. private MediaPlayer mediaPlayer;
  10. //显示暂停播放图标
  11. private ImageView imgPlay;
  12. //控制台显示暂停播放图标
  13. private ImageView imgControll;
  14. /*视频总长度*/
  15. private int duration;
  16. /*handler发送的成功的标识*/
  17. private final int UPDATE_PROGRESS = 0;
  18. /*让线程开始和结束的标记*/
  19. private boolean flag;
  20. /*设置显示的图片*/
  21. private TextView tvTime;
  22. /*更新进度条和时间*/
  23. private Handler handler = new Handler(){
  24. @Override
  25. public void handleMessage(Message msg) {
  26. switch (msg.what){
  27. case UPDATE_PROGRESS:
  28. int currentPosition = (int) msg.obj;
  29. Log.i("tag", "handleMessage: "+currentPosition);
  30. //更新seekBar
  31. sb_progress.setProgress(currentPosition);
  32. //更新时间
  33. updateTime(currentPosition,duration);
  34. break;
  35. default:
  36. break;
  37. }
  38.  
  39. }
  40. };
  41. private UpdateThread updateThread;
  42.  
  43. /**
  44. * 更新时间
  45. * @param currentPosition
  46. * @param duration
  47. */
  48. private void updateTime(int currentPosition, int duration) {
  49. tvTime.setText(formatTime(currentPosition)+"/"+formatTime(duration));
  50. }
  51.  
  52. /**
  53. * 格式化时间
  54. * @param time
  55. * @return
  56. */
  57. private String formatTime(int time) {//格式化时间为00:00:00
  58. //两位数,小于两位数自动补0 例 09:09:00
  59. String format = "%02d:%02d:%02d";
  60. //time为ms
  61. int hour = time/1000/3600;
  62. int minute = time/1000%3600/60;
  63. int second = time/1000%60;
  64. return String.format(format,hour,minute,second);
  65. }
  66. @Override
  67. protected void onCreate(Bundle savedInstanceState) {
  68. super.onCreate(savedInstanceState);
  69. setContentView(R.layout.activity_main);
  70. //初始化视频资源
  71. mediaPlayer =MediaPlayer.create(this,R.raw.hello);
  72. initView();
  73. initEvent();
  74.  
  75. //获取视频的总长度(ms)
  76. duration = mediaPlayer.getDuration();
  77. //为seekBar设置初始值
  78. sb_progress.setMax(duration);
  79.  
  80. }
  81.  
  82. /**
  83. * 进度条拖动监听
  84. * @param seekBar
  85. * @param progress
  86. * @param fromUser
  87. */
  88. @Override
  89. public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  90.  
  91. }
  92.  
  93. @Override
  94. public void onStartTrackingTouch(SeekBar seekBar) {
  95.  
  96. }
  97.  
  98. @Override
  99. public void onStopTrackingTouch(SeekBar seekBar) {
  100. //播放器跳到对应位置
  101. mediaPlayer.seekTo(seekBar.getProgress());
  102. }
  103.  
  104. /**
  105. * 播放完成的时候监听
  106. * @param mp
  107. */
  108. @Override
  109. public void onCompletion(MediaPlayer mp) {
  110. //重置
  111. int position = 0;
  112. //让视频跳到最开始并暂停
  113. mp.seekTo(position);
  114. Message obtain = Message.obtain();
  115. obtain.what = UPDATE_PROGRESS;
  116. obtain.obj = position;
  117. handler.sendMessage(obtain);
  118. imgPlay.setVisibility(View.VISIBLE);
  119. imgControll.setImageResource(android.R.drawable.ic_media_play);
  120. }
  121.  
  122. class UpdateThread extends Thread{
  123. @Override
  124. public void run(){
  125. while(flag){
  126. //获得当前的进度
  127. int currentPosition = mediaPlayer.getCurrentPosition();
  128. Message message = Message.obtain();
  129. message.what = UPDATE_PROGRESS;
  130. //计算seekbar的值
  131. message.obj = currentPosition;
  132. //handler发送进度
  133. handler.sendMessage(message);
  134. //1s一次
  135. SystemClock.sleep(1000);
  136. }
  137. }
  138. }
  139.  
  140. private void initEvent() {
  141. //暂停按钮点击监听,点击播放视频或者暂停视频
  142. imgControll.setOnClickListener(this);
  143. imgPlay.setOnClickListener(this);
  144. //拖动监听,跳到对应的位置
  145. sb_progress.setOnSeekBarChangeListener(this);
  146. //播放完成监听,重置播放器,进度
  147. mediaPlayer.setOnCompletionListener(this);
  148. }
  149.  
  150. private void initView() {
  151. surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
  152. sb_progress = (SeekBar) findViewById(R.id.sb_progress);
  153. imgPlay= (ImageView) findViewById(R.id.iv_play);
  154. imgControll = (ImageView) findViewById(R.id.iv_play_controll);
  155. tvTime = (TextView) findViewById(R.id.tv_time);
  156. //surfaceView绑定生命周期
  157. holder = surfaceView.getHolder();
  158. holder.addCallback(this);
  159. //设置默认值
  160. imgPlay.setVisibility(View.VISIBLE);
  161. imgControll.setImageResource(android.R.drawable.ic_media_play);
  162. }
  163.  
  164. /**
  165. * surfaceViewa绑定生命周期需要回调的方法
  166. * @param holder
  167. */
  168. @Override
  169. public void surfaceCreated(SurfaceHolder holder) {
  170. //播放器绑定surfaceView
  171. mediaPlayer.setDisplay(holder);
  172. //开启线程
  173. updateThread = new UpdateThread();
  174. updateThread.start();
  175. flag = true;
  176. }
  177.  
  178. @Override
  179. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  180.  
  181. }
  182.  
  183. @Override
  184. public void surfaceDestroyed(SurfaceHolder holder) {
  185. //关闭线程,释放资源
  186. flag = false;
  187. if(mediaPlayer != null){
  188. mediaPlayer.stop();
  189. mediaPlayer.release();
  190. mediaPlayer = null;
  191. }
  192. }
  193.  
  194. @Override
  195. public void onClick(View v) {
  196. switch (v.getId()){
  197. case R.id.iv_play:
  198. imgPlay.setVisibility(View.GONE);
  199. imgControll.setImageResource(android.R.drawable.ic_media_pause);
  200. mediaPlayer.start();
  201. break;
  202. case R.id.iv_play_controll:
  203. if(mediaPlayer.isPlaying()){//正在播放--暂停按钮
  204. imgPlay.setVisibility(View.VISIBLE);
  205. imgControll.setImageResource(android.R.drawable.ic_media_play);
  206. mediaPlayer.pause();
  207. }else{//暂停播放
  208. imgPlay.setVisibility(View.GONE);
  209. imgControll.setImageResource(android.R.drawable.ic_media_pause);
  210. mediaPlayer.start();
  211. }
  212. break;
  213. }
  214. }
  215.  
  216. @Override
  217. protected void onDestroy() {
  218. //
  219. super.onDestroy();
  220. }
  221. }

效果:

MediaPlayer简单使用,绑定surfaceView实现播放视频的功能的更多相关文章

  1. 使用MediaPlayer类和SurfaceView来播放视频

    MediaPlayer可以播放视频,只需需要SurfaceView的配合,SurfaceView主要用于显示MediaPlayer播放的视频流媒体的画面渲染. SurfaceView是配合MediaP ...

  2. 运用surfaceView与MediaPlayer实现播放视频的功能

    该程序运用了surfaceView与MediaPlayer结合,实现播放视频,surfaceView详情请见 SurfaceView的使用 使用了第三方包Volly里面的方法StringQueue下载 ...

  3. android SurfaceView中播放视频 按视频的原始比例播放

    OnPreparedListener mediaPlayerOnPreparedListener = new OnPreparedListener() { @Override public void ...

  4. Android--SurfaceView播放视频

    前言 本篇博客讲解一下如何在Android下,使用SurfaceView播放一个视频流媒体.之前有讲到如何使用MediaPlayer播放音频流媒体,其实MediaPlayer还可以播放视频,只需需要S ...

  5. android 98 MediaPlayer+SurfaceView播放视频

    package com.itheima.videoplayer; import java.io.IOException; import android.media.MediaPlayer; impor ...

  6. WPF播放视频

    在现在的项目中需要使用到播放视频的功能,本来打算使用VLC来做的.后来发现WPF 4.0之后新增了MediaElement类,可以实现视频播放. <Grid> <Grid.RowDe ...

  7. [转]Android WebView播放视频(包括全屏播放),androidwebview

    Android WebView播放视频(包括全屏播放),androidwebview 最近项目开发中用到了WebView播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里 ...

  8. 使用MediaPlayer和SurfaceView播放视频

    使用VideoView播放视频简单.方便,丹有些早期的开发者更喜欢使用MediaPlayer来播放视频,但由于MediaPlayer主要用于播放音频,因此它没有提供图像输出界面,此时 需要借助于Sur ...

  9. Android MediaPlayer和SurfaceView播放视频

    昨天介绍了VideoView播放视频,今天再介绍一种播放视频的方法MediaPlayer和SurfaceView,MediaPlayer播放音频,SurfaceView来显示图像,具体步骤如下: 1. ...

随机推荐

  1. Dapper基础用法

    假如你喜欢原生的Sql语句,又喜欢ORM的简单,那你一定会喜欢上Dapper这款ROM.点击下载Dapper的优势:1,Dapper是一个轻型的ORM类.代码就一个SqlMapper.cs文件,编译后 ...

  2. 软件工程第一次个人项目——词频统计by11061153柴泽华

    一.预计工程设计时间 明确要求: 15min: 查阅资料: 1h: 学习C++基础知识与特性: 4-5h: 主函数编写及输入输出部分: 0.5h: 文件的遍历: 1h: 编写两种模式的词频统计函数: ...

  3. JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)

    JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/beans)中建立数据库连接 2)进行sql操作 3)断开数据库连接 ...

  4. Android实例-屏幕操持常亮(XE8+小米2)

    相关资料: http://www.bubuko.com/infodetail-163304.html 结果: 1.打开权限Wake lock为True. 第三方单元: unit Android.JNI ...

  5. oracle中DECODE与CASE的用法区别

    对于CASE与DECODE其实并没有太多的区别,他们都是用来实现逻辑判断.Oracle的DECODE函数功能很强,灵活运用的话可以避免多次扫描,从而提高查询的性能.而CASE是9i以后提供的语法,这个 ...

  6. UVALive 7278 Game of Cards (sg函数)

    Game of Cards 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/G Description Alice and Bob ...

  7. mysql优化(一)

    1.选取最适用的字段属性  MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得 ...

  8. [Xcode使用 - 3] 复制Xcode5.1.1中的项目模板到Xcode6.1

         由于Xcode6中精简了许多的项目和文件模板,导致开发非常不方便,所以这里简单介绍了怎么复制旧版本Xcode中的模板到新的Xcode中      这里要复制的是项目模板Empty Appli ...

  9. php-fpm占用系统资源分析

    故障检测 1.别的先不管,先top看一下cpu.ram.swap哪个比较紧张. 由上图分析,可以看出共有602个进程,其中有601个进程休眠了.这好像有点不对劲,内核进程也就80个左右,加上memca ...

  10. Tomcat参数配置

    一.调整JVM参数 JAVA_OPTS= -server -Xms256m -Xmx1024m 注: -server: 启用服务器模式 一定要作为第一个参数,如果CPU多,服务器机建议使用此项 -Xm ...