上一回我们讲了如何去录制一个音频文件。这次我们讲讲如何播放一个音频文件。录制音频,一般我们在聊天发送语音,或者语音上传的时候会用到。那既然需要录制,那一定是要有播放功能的。同时,我们播放音频,音乐也是需要播放功能。所以今天我就说说音频的播放功能。
1.媒体播放器MediaPlayer简介
既然是播放音频,那就要用到MediaPlayer。MediaPlayer是Android自带的音频和视频播放器,可用于播放MediaRecorder录制的媒体文件,包括amr,aac,mp4,3gp,还有mp3,wav,mid,ogg等音频文件,以及mkv,mov,avi等视频文件。
2.MediaPlayer常用方法(播音与放映通用)
- reset:重置播放器。
- prepare:准备播放。
- start:开始播放
- pause:暂停播放。
- stop:停止播放。
- setOnPreparedListener:设置准备播放监听器。需要实现接口MediaPlayer.OnPreparedListener的onPrepared方法。
- setOnCompletionListener:设置结束播放监听器。需要实现接口MediaPlayer.OnCompletionListener的onCompletion方法。
- setOnSeekCompleteListener:设置播放拖动监听器。需要实现接口MediaPlayer.OnSeekCompleteListener的onSeekComplete方法。
- create:创建指定Uri的播放器。
- setDataSource:设置播放数据来源的文件路径。create与setDataSource两个方法只需调用一个。
- setVolume:设置音量。两个参数分别是左声道和右声道的音量,取值在0~1之间。
- setAudioStreamType:设置音频流的类型。音频流类型的取值说明见表1。
表1 | ||
AudioManager类的铃声类型 | 铃声名称 | 说明 |
STREAM_VOICE_CALL | 通话音 | |
STREAM_SYSTEM | 系统音 | |
STREAM_RING | 铃音 | 来电与收短信的铃声 |
STREAM_MUSIC | 媒体音 | 音频、视频、游戏等的声音 |
STREAM_ALARM | 闹钟音 | |
STREAM_NOTIFICATION | 通知音 |
- setLooping:设置是否循环播放。true表示循环播放,false表示只播放一次。
- isPlaying:判断是否正在播放。
- seekTo:拖动播放进度到指定位置。该方法可与拖动条SeekBar配合使用。
- getCurrentPosition:获取当前播放进度所在的位置。
- getDuration:获取播放时长,单位毫秒。
3.示例代码
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ProgressBar
android:id="@+id/pro_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bt_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="开始" />
<Button
android:id="@+id/bt_pause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="暂停" />
</LinearLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends WaterPermissionActivity implements View.OnClickListener, MediaPlayer.OnCompletionListener {
private String voicePath;
private ProgressBar pro_bar;
private Button bt_start;
private Button bt_pause;
private MediaPlayer mMediaPlayer;
private Handler mHandler;
private boolean isComplete = true;//是否完成
@Override
protected MvcBaseModel getModelImp() {
return null;
}
@Override
protected int getContentLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initWidget() {
pro_bar = findViewById(R.id.pro_bar);
bt_start = findViewById(R.id.bt_start);
bt_pause = findViewById(R.id.bt_pause);
bt_start.setOnClickListener(this);
bt_pause.setOnClickListener(this);
requestPermission(WRITE_EXTERNAL_STORAGE);
}
@Override
protected void doSDWrite() {
requestPermission(READ_EXTERNAL_STORAGE);
}
@Override
protected void doSDRead() {
//初始化音源路径
getPath();
//初始化媒体播放器
init();
}
/**
* 录制前创建一个空文件并获取路径
*/
private void getPath() {
List<String> list = new ArrayList<>();
list.add("record");
String dirPath = PathGetUtil.getLongwayPath(this, list);
File fileVoice = new File(dirPath, "voice1616667408548.amr");
voicePath = fileVoice.getPath();
}
/**
* 初始化MediaPlayer
*/
private void init() {
mHandler = new Handler();
mMediaPlayer = new MediaPlayer();//创建一个媒体播放器
mMediaPlayer.setOnCompletionListener(this);//设置媒体播放器的播放完成监听器
//定时器
mHandler.postDelayed(r, 100);//延时100毫秒
}
/**
* 播放音频
*/
private void play() {
try {
isComplete = false;
//重置媒体播放器
mMediaPlayer.reset();
//设置音频类型为音乐
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//设置媒体数据的文件路径
mMediaPlayer.setDataSource(voicePath);
//媒体播放器准备就绪
mMediaPlayer.prepare();
//媒体播放器开始播放
mMediaPlayer.start();
//设置进度条
pro_bar.setMax(mMediaPlayer.getDuration());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_start:
if (pro_bar.getProgress()!=0) {
//暂停开始
mMediaPlayer.start();
} else {
//普通开始
play();
}
break;
case R.id.bt_pause:
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
break;
}
}
@Override
public void onCompletion(MediaPlayer mp) {
isComplete = true;
ToastUtil.toastWord(this, "播放完成");
}
private Runnable r = new Runnable() {
@Override
public void run() {
if (mHandler != null) {
if (isComplete) {
pro_bar.setProgress(0);
} else {
pro_bar.setProgress(mMediaPlayer.getCurrentPosition());
}
mHandler.postDelayed(this, 500);
}
}
};
}