Android音视频开发之MediaPlayer使用教程

 更新时间:2022年04月06日 09:05:07   作者:JulyYu  
Android多媒体框架支持播放提供了MediaPlayerAPI,可以通过MediaPlayer来实现媒体文件播放。可以说MediaPlayer是非常方便使用的多媒体播放器。本文将详细讲解MediaPlayer的使用,需要的可以参考一下

MediaPlayer

Android多媒体框架支持播放提供了MediaPlayerAPI,可以通过MediaPlayer来实现媒体文件播放。可以说MediaPlayer是非常方便使用的多媒体播放器,只需要简单设置就能实现对音频和视频播放功能,其内部帮助开发者实现了播放对象获取解码以及播放功能。

简单使用

MediaPlayer支持多种资源形式:本地资源、内部URI、外部网址。

//播放器实例化
mediaPlayer = new MediaPlayer();
//准备播放素材
Uri uri = Uri.fromFile(new File("sdcard/DCIM","Camera/test.mp4"));
try {
    //播放器载入资源
    mediaPlayer.setDataSource(this,uri);
} catch (IOException e) {
    e.printStackTrace();
}
//播放器异步准备
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //播放操作
        mediaPlayer.start();
    }
});
//播放窗口展示
SurfaceView surfaceView = new SurfaceView(this);
surfaceView.post(new Runnable() {
    @Override
    public void run() {
        mediaPlayer.setSurface(surfaceView.getHolder().getSurface());
    }
});

以上代码示例就是MediaPlayer简单使用过程。其中prepareAsync()是异步操作需要在回调setOnPreparedListener方法了解最终播放器准备结果然后再执行播放操作。当然播放器也支持同步准备prepare方法,但推荐使用异步操作,因为资源获取过程可能会涉及到解码数据会是耗时操作,同步操作很有可能造成ANR错误。

缺陷

MediaPlayer虽然有内部状态,某些操作只有在特定状态下正确操作才能生效。若在非指定状态下操作或许会导致播放器发生异常更有可能发生崩溃的情况。但播放器的内部状态机并没有暴露接口给开发者,无法随时能够获取到目前播放器当前状态。

AndroidMediaPlayer播放器封装

因为缺陷原因直接使用MediaPlayer就不能很好的去管理状态。因此可以自行对MediaPlayer进行封装使用,可以将功能进行整理并且增加状态管理和方便错误统一处理等逻辑。

状态机编写

根据MediaPlayer状态图预设几种状态类型以暂存播放器内部状态。

private static final int IDLE = 0; // 空闲状态
private static final int INIT = 3;// 初始化状态
private static final int PREPARING = 4;// 准备状态
private static final int PREPARED = 5;// 准备状态
private static final int STARTED = 6;// 开始状态
private static final int PAUSED = 7;// 暂停状态
private static final int STOPPED = 8;// 停止状态

private static final int END = 9; // 结束状态
private static final int ERROR = 10;// 错误状态

内部类

使用mPlayerStatus暂存播放器状态

@IntDef({IDLE,
        END,
        ERROR,
        INIT,
        PREPARED,
        STARTED,
        PAUSED,
        STOPPED,
})
public @interface STATUS {
}

MediaPlayer mMediaPlayer;
Context mContext;
@STATUS
int mPlayerStatus = IDLE;

初始化函数

初始化函数实例化播放器并注册基本播放所需要的回调函数

public AndroidMediaPlayer(Context context) {
    mContext = context;
    mMediaPlayer = new MediaPlayer();
    mMediaPlayer.setOnErrorListener(this);
    mMediaPlayer.setOnCompletionListener(this);
    mMediaPlayer.setOnPreparedListener(this);
    mPlayerStatus = INIT;
}

方法和回调

封装播放器基础方法可供播放调用并且进行状态机判断,若不在可操作范围内则不可执行对应操作。同时对于资源设置方法通过原生api可以看到有许多在形式,但这里就只是用URI来做入参了。

//资源入参
public void setSource(Uri uri){
    try {
        mMediaPlayer.setDataSource(mContext,uri);
        mMediaPlayer.prepareAsync();
        mPlayerStatus = PREPARING;
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// 设置可视化窗口
public void setSurface(Surface surface){
    mMediaPlayer.setSurface(surface);
}
//开始播放
public void start(){
    mMediaPlayer.start();
    mPlayerStatus = STARTED;
}
//暂停
public void pause(){
    if(mPlayerStatus > PAUSED) return;
    mMediaPlayer.pause();
    mPlayerStatus = PAUSED;
}
//停止
public void stop(){
    if(mPlayerStatus > STOPPED) return;
    mMediaPlayer.stop();
    mPlayerStatus = STOPPED;
}
//释放
public void release(){
    if(mPlayerStatus >= INIT){
        mMediaPlayer.release();
        mMediaPlayer = null;
        mPlayerStatus = END;
    }
}
// 错误回调
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    mPlayerStatus = ERROR;
    return false;
}
// 播放回调
@Override
public void onCompletion(MediaPlayer mp) {

}
// 准备成功回调
@Override
public void onPrepared(MediaPlayer mp) {
    mPlayerStatus = PREPARED;
}

小结

MediaPlayer作为官方提供封装的播放器在使用上并没有什么难度,可以说开发者直接开箱即用。或许对于简单开发视频播放已经足够了,能够播放本地文件或是网络文件等都能支持。但对于深入理解MediaPlayer可能还远远不够,后续去读读源码来了解内部实现。之后要自行实现编解码来播放音视频等能力去处理和添加其他效果的时候,那时MediaPlayer或许就捉襟见肘了。

到此这篇关于Android音视频开发之MediaPlayer使用教程的文章就介绍到这了,更多相关Android MediaPlayer内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解android在mob平台实现qq登陆和分享

    详解android在mob平台实现qq登陆和分享

    这篇文章主要介绍了详解android在mob平台实现qq登陆和分享,对接入第三方平台SDK感兴趣的同学们,可以参考下
    2021-04-04
  • Android 中SwipeRefreshLayout与ViewPager滑动事件冲突解决方法

    Android 中SwipeRefreshLayout与ViewPager滑动事件冲突解决方法

    这篇文章主要介绍了Android 中SwipeRefreshLayout与ViewPager滑动事件冲突解决方法的相关资料,需要的朋友可以参考下
    2017-04-04
  • webview添加参数与修改请求头的user-agent实例

    webview添加参数与修改请求头的user-agent实例

    这篇文章主要介绍了webview添加参数与修改请求头的user-agent实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Android左右滑出菜单实例分析

    Android左右滑出菜单实例分析

    想在首页加个从左滑动出来的菜单,我查阅网上资料,并自己摸索,实现了左、右两边都能滑出菜单,并且,左、右菜单中,都可以加ListView等这类需要解决GestureDetector冲突的问题
    2013-06-06
  • Android Camera开发手电筒功能

    Android Camera开发手电筒功能

    这篇文章主要介绍了Android Camera开发手电筒功能的相关资料,需要的朋友可以参考下
    2016-07-07
  • Flutter Android端启动白屏问题的解决

    Flutter Android端启动白屏问题的解决

    Flutter 应用在 Android 端上启动时会有一段很明显的白屏现象,白屏的时长由设备的性能决定,设备性能越差,白屏时间越长。这篇文章主要介绍了Flutter Android端启动白屏问题的解决。感兴趣的小伙伴们可以参考一下
    2018-07-07
  • android实现年龄段选择器

    android实现年龄段选择器

    这篇文章主要为大家详细介绍了android实现年龄段选择器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • android 定时启动\取消小例子

    android 定时启动\取消小例子

    本文为大家讲解下android实现定时启动\取消的具体实现方式,感兴趣的朋友可以参考下哈
    2013-06-06
  • android实现文件下载功能

    android实现文件下载功能

    这篇文章主要为大家详细介绍了android实现文件下载功能,android在网络上下载文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Android编程学习之抽象类AbsListView用法实例分析

    Android编程学习之抽象类AbsListView用法实例分析

    这篇文章主要介绍了Android编程学习之抽象类AbsListView用法,较为详细的分析了抽象类AbsListView的功能、结构、定义及使用注意事项等,需要的朋友可以参考下
    2015-10-10

最新评论