Android应用开发中,构建高效的音频播放功能是关键环节。本文详细解析如何通过ExoPlayer实现支持倍速播放的音频管理工具类。

ExoPlayer作为Google推荐的媒体播放库,支持多种播放特性。通过以下依赖即可集成最新版本:
implementation 'com.google.android.exoplayer:exoplayer:2.17.1' //exo播放器
音频管理工具类封装了核心功能模块,包括:
/**
* 音频播放
*/
public class AudioPlayerManager {
private static final String TAG = "AudioPlayerManager";
private static AudioPlayerManager instance;
private Context context;
private SimpleExoPlayer mediaPlayer;
private DataSource.Factory dataSourceFactory;
private AudioManager manager; private AudioPlayerManager(Context context) {
this.context = context;
createPlayer();
requestAudioFocus();
} public static AudioPlayerManager getInstance(Context context) {
synchronized (AudioPlayerManager.class) {
if (instance == null) {
instance = new AudioPlayerManager(context);
}
} return instance;
} public void requestAudioFocus() {
manager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
// manager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
} public ExoPlayer getMediaPlayer() {
return mediaPlayer;
} public void setAudioFile2(String filepath) {
try {
//这是一个代表将要被播放的媒体的MediaSource
MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(filepath));
mediaPlayer.prepare(mediaSource);
mediaPlayer.setPlayWhenReady(false);
} catch (Exception e) {
e.printStackTrace();
}
} AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() {
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange){
case AudioManager.AUDIOFOCUS_LOSS:
//长时间丢失焦点,当其他应用申请的焦点为AUDIOFOCUS_GAIN时,
//会触发此回调事件,例如播放QQ音乐,网易云音乐等
//通常需要暂停音乐播放,若没有暂停播放就会出现和其他音乐同时输出声音
//释放焦点,该方法可根据需要来决定是否调用
//若焦点释放掉之后,将不会再自动获得
manager.abandonAudioFocus(afChangeListener);
PlayControlTools.setACTION_PAUSE(); //控制播放暂停
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
//短暂性丢失焦点,当其他应用申请AUDIOFOCUS_GAIN_TRANSIENT或AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE时,
//会触发此回调事件,例如播放短视频,拨打电话等。
//通常需要暂停音乐播放
playOrPause(false);
PlayControlTools.setACTION_PAUSE();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
playOrPause(false);
//短暂性丢失焦点并作降音处理
PlayControlTools.setACTION_PAUSE();
break;
case AudioManager.AUDIOFOCUS_GAIN:
//当其他应用申请焦点之后又释放焦点会触发此回调
//可重新播放音乐
// if(ConstantFd.unit_List!=null && ConstantFd.unit_List.size() > 0 && ConstantFd.control_play){
// PlayControlTools.setACTION_PLAY();
// } break;
}
}
};
//开始播放
public void start() {
int result = manager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d("TAG", "有音频焦点");
mediaPlayer.setPlayWhenReady(true);
}else {
Log.d("TAG", "无音频焦点");
// mediaPlayer.setPlayWhenReady(false);
}
}
// public void setrepeat(boolean repeat){ //循环复读
// //单次列表播放,播放完了就停止
//// Player.REPEAT_MODE_OFF;
// //循环播放单个
//// Player.REPEAT_MODE_ONE;
// //列表循环
//// Player.REPEAT_MODE_ALL;
// if(repeat){
// mediaPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
// }else {
// mediaPlayer.setRepeatMode(Player.REPEAT_MODE_OFF);
// }
//
// } //判断是否是播放状态
public boolean isPlaying() {
int playbackState = mediaPlayer.getPlaybackState();
if (playbackState == SimpleExoPlayer.STATE_READY && mediaPlayer.getPlayWhenReady()) {
return true;
}
return false;
}
//播放or暂停
public void playOrPause(boolean isplay) {
if(isplay){
int result = manager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.d("TAG", "有音频焦点");
}else {
Log.d("TAG", "无音频焦点");
}
}
mediaPlayer.setPlayWhenReady(isplay);
} //切换播放速率
public void switchSpeed(float speedIndex) {
// API 23 (6.0)以上 ,通过设置Speed改变音乐的播放速率
getMediaPlayer().setPlaybackParameters(new PlaybackParameters(speedIndex));
if (isPlaying()) {
// 判断是否正在播放,未播放时,要在设置Speed后,暂停音乐播放
} else {
// getMediaPlayer().setPlayWhenReady(false);
}
} //停止播放
public void stop(boolean reset) {
if (mediaPlayer != null) {
mediaPlayer.stop(reset);
manager.abandonAudioFocus(afChangeListener);
}
} //释放资源
public void release() {
if (mediaPlayer != null) {
mediaPlayer.release();
instance = null;
}
} //创建一个新的player
private void createPlayer() {
//创建一个DataSource对象,通过它来下载多媒体数据
dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, BuildConfig.APPLICATION_ID));
mediaPlayer = new SimpleExoPlayer.Builder(context).build();
} public void setlistener(Player.Listener listener) {
mediaPlayer.addListener(listener);
}
}
在Service或Activity中的具体实现方式如下:
private static AudioPlayerManager apm; //音频播放管理@Override
public void onCreate() {
super.onCreate();
apm = AudioPlayerManager.getInstance(TbjcPlayerService.this);
//播放
Player.Listener listener = new Player.Listener() {
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING://加载缓存且还未准备好时触发 break;
case Player.STATE_READY: //播放准备
break;
case Player.STATE_ENDED: //播放结束时触发
Log.e("TAG", "STATE_ENDED---> ");
break;
} }
};
apm.setlistener(listener);
apm.switchSpeed(1.0f);}@Override
public void onDestroy() {
super.onDestroy();
if (apm != null) {
apm.setlistener(null); // 移除器,切断引用链
apm.release(); // 释放音频资源
apm = null; // 置空,避免后续引用
}
}
本文完整呈现了Android音频播放器的核心实现方案,从ExoPlayer集成到功能封装,再到实际应用场景的完整解决方案。