【Android】mediaPlayer和 soundPool的区别使用 & mediaPlayer使用prepareAsync()解决异步问题

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

背景

在一个小游戏项目中涉及到音频播放的功能
其中有反馈在这里插入图片描述

代码研究

原来是旧有逻辑使用了SoundPool的代码逻辑该逻辑会导致上述情况。
在这里插入图片描述
在这里插入图片描述

解决方式是使用mediaPlayer实现
改装时候的代码

public class AudioPlayer {

    private MediaPlayer mediaPlayer;

    private HashMap<String, String> namePathMap = new HashMap<>();
    private String savePath = CommonUtils.getDataBaseFile(CommonUtils.getApplication()) + "/audio/";
    private Handler handler = new Handler(Looper.getMainLooper());
    //实例化AudioManager对象控制声音
    private AudioManager am;
    //最大音量
    private float audioMaxVolume;
    //当前音量
    private float audioCurrentVolume;
    private float volumeRatio;

    public AudioPlayer() {
        // 设置音效使用场景
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        //实例化AudioManager对象控制声音
        am = (AudioManager)CommonUtils.getApplication().getSystemService(Context.AUDIO_SERVICE);
        //最大音量
        audioMaxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        //当前音量
        audioCurrentVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
        volumeRatio = audioCurrentVolume / audioMaxVolume;
        // 准备是耗时的故异步处理
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.start();
            }
        });
    }
    String path = null;
    public void playSound(String name, boolean isPlay, String url, boolean isLoop, int volume){
        if (mediaPlayer == null) {
            AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();
            mediaPlayer = new MediaPlayer();
        }
        if(mediaPlayer.isPlaying() == isPlay && path == namePathMap.get(url)){
            return;
        }
        path = namePathMap.get(url);
        mediaPlayer.setLooping(isLoop);
        mediaPlayer.setVolume(volumeRatio * volume / 100, volumeRatio * volume / 100);
        if (path == null) {
            // 下载
            CommonUtils.downloadFile(url, savePath, new ICommonCallback<String>() {
                @Override
                public void onResult(int errorCode, String object) {
                    if (errorCode == 0 && !TextUtils.isEmpty(object)) {
                        namePathMap.put(url, object);
                        path = object;
                        play(path,isPlay);
                    }
                }
            });
        } else {
            play(path,isPlay);
        }
    }
    private void play(String path,boolean isPlay){
        try {
            mediaPlayer.setDataSource(path);
            if (isPlay) {
                mediaPlayer.prepareAsync();
                return;
            } else {
                mediaPlayer.stop();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public void changeSoundVolume(String name, int volume) {
        if (mediaPlayer == null) {
            return;
        }
        mediaPlayer.setVolume(volumeRatio * volume / 100, volumeRatio * volume / 100);
    }

    public void release() {
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    public void pause() {
        if (mediaPlayer != null) {
            mediaPlayer.pause();
        }
    }

    public void resume() {
        if (mediaPlayer != null) {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
    }
}

在使用prepareAsync()要注意对回调设置

 // 准备是耗时的故异步处理
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.start();
            }
        });

这里的逻辑是准备好就可以播放了。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: android

“【Android】mediaPlayer和 soundPool的区别使用 & mediaPlayer使用prepareAsync()解决异步问题” 的相关文章