Android开发在线音频播放器之章节一 AudioPlayerManager

Android开发在线音频播放器之章节一 AudioPlayerManager

使用Exo播放器,可支持倍速条件

arduino 复制代码
implementation 'com.google.android.exoplayer:exoplayer:2.17.1' //exo播放器

音频管理工具类包含音频焦点管理、播放暂停、请求音频焦点、设置播放文件、判断播放状态、设置播放监听等功能。

typescript 复制代码
/**
 * 音频播放
 */
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中使用

java 复制代码
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; // 置空,避免后续引用
    }   
}
相关推荐
Refrain_zc7 小时前
Android开发Room数据库使用(可复制)
java
大波V57 小时前
claude-code cli 跳过登录
java·服务器·前端
小江的记录本7 小时前
【Kafka核心】Kafka 3.0+ KRaft模式(替代ZooKeeper)核心原理与优势
java·数据库·分布式·后端·zookeeper·kafka·rabbitmq
Refrain_zc7 小时前
Android开发在线音频播放器之章节二页面PlayActivity
java
Dicky-_-zhang7 小时前
分布式锁实战:Redis与ZooKeeper对比选型与实现方案
java·jvm
Refrain_zc7 小时前
Android 应用内的APK 安装(可复制)
java
杨运交7 小时前
[020][缓存模块]基于 BeanCreator 的缓存管理器创建器模式设计与实践
java·spring·缓存
risc1234567 小时前
DocumentsWriterDeleteQueue 的核心设计思想
java·全文检索·lucene
风味蘑菇干7 小时前
Stream基础题目
java·算法