在 Android 视频播放器 (一):使用VideoView播放视频 我们讲了一下如何使用VideoView播放视频,了解了基本的播放器的一些知识和内容。也知道VideoView内部封装的就是MediaPlayer,本文就介绍如何使用MediaPlayer播放视频。

一、简介

MediaPlayer是Android中的一个多媒体播放类,其提供的API能满足简单的大部分音视频的播放需求。

下面简单介绍一下MediaPlayer:

  • MediaPlayer是使用Surface进行视频的展示的。
  • MediaPlayer只支持mp4、avi、3gp格式的视频,支持格式相对单一。
  • MediaPlayer可以播放网络视频,支持的网络视频的协议为:Http协议和RTSP协议两种。

二、MediaPlayer 使用方法

MediaPlayer 的提供的方法如下:

  • void setDataSource(String path) :通过一个具体的路径来设置MediaPlayer的数据源,path可以是本地的一个路径,也可以是一个网络路径
  • void setDataSource(Context context, Uri uri): 通过给定的Uri来设置MediaPlayer的数据源,这里的Uri可以是网络路径或是一个ContentProvider的Uri。
  • void setDataSource(MediaDataSource dataSource) :通过提供的MediaDataSource来设置数据源
  • void setDataSource(FileDescriptor fd): 通过文件描述符FileDescriptor来设置数据源
  • int getCurrentPosition() :获取当前播放的位置
  • int getAudioSessionId() :返回音频的session ID
  • int getDuration() :得到文件的时间
  • TrackInfo[] getTrackInfo() :返回一个track信息的数组
  • boolean isLooping (): 是否循环播放
  • boolean isPlaying(): 是否正在播放
  • void pause () :暂停
  • void start () :开始
  • void stop () : 停止
  • void prepare(): 同步的方式装载流媒体文件。
  • void prepareAsync(): 异步的方式装载流媒体文件。
  • void reset(): 重置MediaPlayer至未初始化状态。
  • void release (): 回收流媒体资源。
  • void seekTo(int msec): 指定播放的位置(以毫秒为单位的时间)
  • void setAudioStreamType(int streamtype) :指定流媒体类型
  • void setLooping(boolean looping) :设置是否单曲循环
  • void setNextMediaPlayer(MediaPlayer next) : 当前这个MediaPlayer播放完毕后,MediaPlayer next开始播放
  • void setWakeMode(Context context, int mode):设置CPU唤醒的状态。
  • setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) :网络流媒体的缓冲变化时回调
  • setOnCompletionListener(MediaPlayer.OnCompletionListener listener) :网络流媒体播放结束时回调
  • setOnErrorListener(MediaPlayer.OnErrorListener listener) :发生错误时回调
  • setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当装载流媒体完毕的时候回调。

Android通过MediaPlayer控制播放器的状态的方式来控制媒体文件的播放,其中:

  • prepare()和prepareAsync() 提供了同步和异步两种方式设置播放器进入prepare状态,需要注意的是,如果MediaPlayer实例是由create方法创建的,那么第一次启动播放前不需要再调用prepare()了,因为create方法里已经调用过了。
  • start()是真正启动文件播放的方法,
  • pause()和stop()比较简单,起到暂停和停止播放的作用,
  • seekTo()是定位方法,可以让播放器从指定的位置开始播放,需要注意的是该方法是个异步方法,也就是说该方法返回时并不意味着定位完成,尤其是播放的网络文件,真正定位完成时会触发OnSeekComplete.onSeekComplete(),如果需要是可以调用setOnSeekCompleteListener(OnSeekCompleteListener)设置监听器来处理的。
  • release()可以释放播放器占用的资源,一旦确定不再使用播放器时应当尽早调用它释放资源。
  • reset()可以使播放器从Error状态中恢复过来,重新会到Idle状态。

使用MediaPlayer播放视频的步骤如下:

  1. 创建MediaPlayer对象,并让它加载指定的视频文件;
  2. 在界面布局文件中定义SurfaceView控件,或在程序中创建SurfaceView控件,并为SurfaceView的SurfaceHolder添加Callback监听器;
  3. 调用MediaPlayer对象的setDisney(SurfaceHolder sh)方法将所播放的视频图像输出到指定的SurfaceView控制;
  4. 调用MediaPlayer的start()、stop()、pause()方法来控制视频播放。
下图是一个MediaPlayer对象被支持的播放控制操作驱动的声明周期和状态。其中,椭圆代表MediaPlayer可能驻留的状态,弧线表示驱动MediaPlayer在各个状态之间迁移的播放控制操作。这里有两种类型的弧线。由单箭头开始的弧线代表同步方法调用,而以双箭头开头的弧线代表异步方法调用。

三、使用MediaPlayer实现视频播放

下面我们将展示如何使用MediaPlayer播放香港卫视的视频流:

1. 声明权限

需要在AndroidManifest.xml添加权限。

  1. <uses-permission android:name="android.permission.INTERNET" />

2. 编写SurfaceView布局

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout 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=".MainActivity">
  7. <LinearLayout
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content">
  10. <SurfaceView
  11. android:id="@+id/surface_view"
  12. android:layout_width="match_parent"
  13. android:layout_height="195dp" />
  14. </LinearLayout>
  15. </android.support.constraint.ConstraintLayout>

3. 编写播放视频代码

  1. public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
  2.  
  3. SurfaceView surfaceView;
  4.  
  5. SurfaceHolder surfaceHolder;
  6.  
  7. MediaPlayer mediaPlayer;
  8.  
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13.  
  14. surfaceView = findViewById(R.id.surface_view);
  15.  
  16. surfaceHolder = surfaceView.getHolder();
  17.  
  18. surfaceHolder.addCallback(this);
  19.  
  20. mediaPlayer = new MediaPlayer();
  21.  
  22. try {
  23. mediaPlayer.setDataSource("http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8");
  24. } catch (IOException e) {
  25. e.printStackTrace();
  26. }
  27. mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  28. @Override
  29. public void onPrepared(MediaPlayer mp) {
  30. mp.start();
  31. }
  32. });
  33. }
  34.  
  35. @Override
  36. public void surfaceCreated(SurfaceHolder holder) {
  37. Surface surface = holder.getSurface();
  38. mediaPlayer.setSurface(surface);
  39. mediaPlayer.prepareAsync();
  40. }
  41.  
  42. @Override
  43. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  44.  
  45. }
  46.  
  47. @Override
  48. public void surfaceDestroyed(SurfaceHolder holder) {
  49.  
  50. }
  51. }

四、MediaPlayer使用注意事项

  1. 在使用start()播放流媒体之前,需要装载流媒体资源。这里最好使用prepareAsync()用异步的方式装载流媒体资源。因为流媒体资源的装载是会消耗系统资源的,在一些硬件不理想的设备上,如果使用prepare()同步的方式装载资源,可能会造成UI界面的卡顿,这是非常影响用于体验的。因为推荐使用异步装载的方式,为了避免还没有装载完成就调用start()而报错的问题,需要绑定MediaPlayer.setOnPreparedListener()事件,它将在异步装载完成之后回调。异步装载还有一个好处就是避免装载超时引发ANR((Application Not Responding)错误。

    1. mediaPlayer = new MediaPlayer();
    2. mediaPlayer.setDataSource(path);
    3. mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    4. // 通过异步的方式装载媒体资源
    5. mediaPlayer.prepareAsync();
    6. mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
    7. @Override
    8. public void onPrepared(MediaPlayer mp) {
    9. // 装载完毕回调
    10. mediaPlayer.start();
    11. }
    12. });
  1. 使用完MediaPlayer需要回收资源。MediaPlayer是很消耗系统资源的,所以在使用完MediaPlayer,不要等待系统自动回收,最好是主动回收资源

    1. if (mediaPlayer != null && mediaPlayer.isPlaying()) {
    2. mediaPlayer.stop();
    3. mediaPlayer.release();
    4. mediaPlayer = null;
    5. }

Android 视频播放器 (二):使用MediaPlayer播放视频的更多相关文章

  1. Android 视频播放器切换到下个视频时残留上个视频画面的解决办法

    最近在做一个Android视频播放器,遇到一个问题:切换到下一个视频时,中间会停留上一个视频的残存画面.   这是怎么回事?   我在网上找了很多资料,终于找到了原因:我是用自定义一个surfacev ...

  2. android中使用surfaceview+MediaPlayer播放视频

    Android中播放视频主要有两种方式: 使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型 使用android自带的VideoView,这种方法 ...

  3. 【Android 多媒体应用】使用 MediaPlayer 播放视频

    1.MainActivity.java import android.media.AudioManager; import android.media.MediaPlayer; import andr ...

  4. Android 视频播放器 (一):使用VideoView播放视频

    一.简介 作为Android开发,我们不可避免的会接触到视频播放,VideoView做为最简单的播放器,我们是不应该不会的. 下面简单介绍一下VideoView: VideoView是使用MediaP ...

  5. Android应用开发学习笔记之播放视频

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 在Android中,我们可以通过使用VideoView类或者MediaPlayer类来播放视频. 一.使用Video ...

  6. android视频播放器开发

    http://blog.csdn.net/u010181592/article/details/49301703 http://blog.csdn.net/qq_33291295/article/de ...

  7. Android 视频播放器 (三):使用NBPlayer播放直播视频

    一.前言 在 Android 音视频开发学习思路 中,我们不断的学习和了解音视频相关的知识,随着知识点不断的学习,我们现在应该做的事情,就是将知识点不断的串联起来.这样才能得到更深层次的领悟.通过整理 ...

  8. Android 视频播放器 (四):使用ExoPlayer播放视频

    一.简介 ExoPlayer是一个Android应用层的媒体播放器,它提供了一套可替换Android MediaPlayer的API,可以播放本地或者是线上的音视频资源.ExoPlayer支持一些An ...

  9. Android 视频播放器 VideoView 的使用,播放本地视频 和 网络 视频

    1.布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:and ...

随机推荐

  1. 一、selenium 环境搭建

    本教程演示是在window系统上演示,linux.mac 系统以后会更新. 1.准备工作 1.python2或者python3安装包,官网:https://www.python.org/downloa ...

  2. grunt压缩js代码

    安装node.js的环境和grunt插件在上一篇已经将过,点击这里跳到上一篇 所以我们直接从压缩插件的安装开始讲 起 1.安装uglify插件 目录结构如下: 命令行:npm install grun ...

  3. Android自动化之Monkey测试(二)

    本文主要从以下方面进行分享. 一.查看应用包名二.Monkey启动三.Monkey停止四.Monkey命令五.日志分析 一.查看应用包名 大多数时候,我们都是对特定的应用进行monkey测试,因此需要 ...

  4. sqlserv 配置 CLR

    转载地址:http://www.cnblogs.com/Brambling/p/8000911.html   //clr 配置 https://docs.microsoft.com/zh-cn/sql ...

  5. CentOS 7 下安装oracle 11g碰到的一些问题

    OUI预检查时会报错,安装时会报两个不符合项目 1 compat-libstdc++ 提示未安装 奇怪这个,yum install compat-libstdc++ 老是提示找不到包,其实正确的安装方 ...

  6. Appium+Python自动化 2 定位元素方式

    1.找到 Android SDK安装路径tools 下面的 uiautomatorviewer.bat,如下截图 2.点击uiautomatorviewer.bat进行启动,左上角一共四个按钮,作用分 ...

  7. xbee PRO S2C的多固件烧写

    XBee and XBee-PRO ZB 嵌入式射频模块是与ZigBee/IEEE 802.15.4兼容的解决方案,可以满足低成本低功耗无线传感网络的特殊需求.该模块易于使用,极低的功耗,以及提供设备 ...

  8. mac 清理

    1.iOS DeviceSupport   -- ~/Library/Developer/Xcode/iOS DeviceSupport 这个可重新生成!在连接旧设备调试时,会重新自动生成. 2.iP ...

  9. iOS模拟器:Undefined symbols for architecture x86_64

    描述:为了适配iPhone 5s的64位处理器,在编译选项中加入了arm64架构.但是发现工程在真机上可以编译通过但是在模拟器上却未编过. 问题解决:经研究在编译选项中再加入x86_64架构,重新编译 ...

  10. C语言函数指针与 c#委托和事件对比

    C语言: 函数指针可以节省部分代码量,写类似具有多态的函数,比如要比较最大值,如果不用函数指针就只能写比较某一类型比如int类型的max函数,这个max无法比较string的大小.函数指针的意义就不多 ...