欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android --- MediaPlayer的使用详解

程序员文章站 2022-07-07 11:13:26
...

Android的MediaPlayer包含了Audio和Video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlaer来实现的。

首先看看MediaPlaer的生命周期

Android --- MediaPlayer的使用详解

实现流程 : Application–>Framework MediaPlayer.java–>jni–>Library MediaPlayer.cpp–> 解码 –>Driver–> 硬件

生命周期

Idle–>setDataSource–>Initialized–>prepare/prepareAsyn–>prepared–>start 、 pause 、 stop 、 seekTo

播放

private void play(String path){
    if (null == mediaPlayer){
    mediaPlayer = new MediaPlayer();
    //设置准备监听
    mediaPlayer.setOnPreparedListener(onPreparedListener);
    //设置错误监听
mediaPlayer.setOnErrorListener(onErrorListener);
    //设置播放完毕监听
    mediaPlayer.setOnCompletionListener(onCompletionListener);
     } else {
            mediaPlayer.reset();
     }
     //1、让MediaPlayer进入idle状态
     //设置播放的数据源
     try {
         mediaPlayer.setDataSource(path);
         //2、进入initialized状态
         //准备
         mediaPlayer.prepareAsync();
     } catch (IOException e) {
         e.printStackTrace();
     }
}

private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //3 、进入 onPrepared 状态 ( 准备完毕 ) ,可以去 start 、 pause 、 seekTo 、 stop
        mp.start();
    }
};

控制:

case R.id.btn_play:
    if(mPlayer == null){
        play("/mnt/sdcard/Music/zmr.mp3");
    } else {
        if(!mPlayer.isPlaying()){
            mPlayer.start();
        }
    }
    break;

case R.id.btn_pause:
    if(null != mPlayer && mPlayer.isPlaying()){
        mPlayer.pause();
    }
    break;

case R.id.btn_stop:
    if(null != mPlayer){
        mPlayer.stop();
        mPlayer.release();
        mPlayer = null;
    }
    break;

mPlayer.isPlaying() 检测是否正在播放中
mPlayer.release() 释放资源,建议停止时使用
mPlayer.getDuration() 获取播放的音乐的总时间
mPlayer.getCurrentPosition() 获取当前播放的时间
mPlayer.seekTo(pos) 设置播放位置

关于播放进度

可以使用 Handler 的延迟发送消息的方式循环获取当前时间,更新进度条

1 、准备完毕时设置最大值

private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        //3 、进入 onPrepared 状态 ( 准备完毕 ) ,可以去 start 、 pause 、 seekTo 、 stop
        // 获取总时间
        mSeek.setMax(mp.getDuration());
        mp.start();
        // 更新播放时间
        mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
    }
};

2 、定义 Handler 接收消息时更新,并且控制下一次获取的时间 ( 循环 )

private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if(msg.what == MSG_UPDATE_POSITION){
            if(mPlayer != null){
                int pos = mPlayer.getCurrentPosition(); // 获取当前的播放时间
                mSeek.setProgress(pos);
                sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
            }
        }
    }
};

注意:播放控制中的进度更新

// 暂停时停止更新
if (null != mPlayer && mPlayer.isPlaying()) {
    mHandler.removeMessages(MSG_UPDATE_POSITION);
    mPlayer.pause();
}

// 播放时恢复更新
if (!mPlayer.isPlaying()) {
    mPlayer.start();
    mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
}

// 停止时 ( 停止更新 ) 重置进度条
if (null != mPlayer) {
    mHandler.removeMessages(MSG_UPDATE_POSITION);
    mPlayer.stop();
    mPlayer.release();
    mPlayer = null;
    mSeek.setProgress(0);
}

拖动进度条的控制

mSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if(mPlayer!=null && mPlayer.isPlaying()){
            mHandler.removeMessages(MSG_UPDATE_POSITION);
        }
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if(mPlayer!=null){
            int pos = seekBar.getProgress(); // 获取拖动到的位置
            mPlayer.seekTo(pos); // 设置播放位置
            if(mPlayer.isPlaying()){
                mHandler.sendEmptyMessageDelayed(MSG_UPDATE_POSITION,200);
            }
        }
    }
});

Activity界面跳转的另外一种写法
在布局按钮中添加Tag标记

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.xykj.mediademo.MainActivity">

    <Button
        android:id="@+id/btn_2_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="音乐播放器"
        android:tag="com.xykj.mediademo.MusicPlayerActivity"/>
</LinearLayout>

在MainActivity 中的写法

    @Override
    public void onClick(View v) {
        try {
            Class cls = Class.forName((String)(v.getTag()));
            Intent it = new Intent(this,cls);
            startActivity(it);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

这样也可以实现点击跳转!!