Android Audio——使用SoundPool播放自定义音效

SoundPool 一般用来播放密集,急促而又短暂的音效。

SoundPool 对象可以看作是一个可以从 APK 中导入资源 或者从文件系统中载入文件的样本集合。

它利用 MediaPlayer 服务为音频解码为一个原始16位 PCM流。这个特性使得应用程序可以进行流压缩,而无须忍受在播放音频时解压所带来的 CPU 负载和延时。SoundPool 使用音效池的概念来管理多个播放流,如果超过流的最大数目, SoundPool 会基于优先级自动停止先前播放的流,另外,SoundPool 还支持自行设置声音的品质、 音量、 播放比率等参数。

在我们车机能想到的使用场景就是播放beep音和警告音等用户提示音。

常用方法:

方法描述

SoundPool(int maxStreams, int streamType, int srcQuality)

构造函数

int load(Context context, int resId, int priority)

int load(String path, int priority)

int load(FileDescriptor fd, long offset, long length, int priority)

int load(AssetFileDescriptor afd, int priority)

加载声音资源,返回一个声音的ID,后面我们可以通过这个ID来播放指定的声音

int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

播放

void setVolume(int streamID, float volume)

设置音量

void setPriority(int streamID, int priority)

设置优先级

void pause(int streamID)

暂停

void resume(int streamID)

重播

void stop(int streamID)

停止

void release() 

释放资源

参数介绍:

maxStreams 同时播放流的最大数量,当播放的流的数目大于此值,则会选择性停止优先级较低的流

streamType 流类型,比如 STREAM_MUSIC

srcQuality 采样率转换器质量,目前没有什么作用,默认填充0

context:上下文

resId:资源id

priority:没什么用的一个参数,建议设置为1,保持和未来的兼容性

path:文件路径

FileDescriptor:貌似是流吧,这个我也不知道

AssetFileDescriptor:从asset目录读取某个资源文件,用法: AssetFileDescriptor descriptor = - assetManager.openFd(“biaobiao.mp3”);

soundID:Load()返回的声音ID号

leftVolume:左声道音量设置

rightVolume:右声道音量设置

priority:指定播放声音的优先级,数值越高,优先级越大。

loop:指定是否循环:-1表示无限循环,0表示不循环,其他值表示要重复播放的次数

rate:指定播放速率:1.0的播放率可以使声音按照其原始频率,而2.0的播放速率,可以使声音按照其 原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。

代码:

工具类:

public class SoundPlayerUtils {
    private static final String TAG = "SoundPlayerUtils";


    public enum RingerTypeEnum {
        SOUND_ONE,
        SOUND_TWO,
        SOUND_THREE,
        SOUND_FOUR
    }
    private Context context;


    private SoundPool soundPool;
    private AudioManager audioManager;
    private int streamId;
    private int soundId;
    private boolean loop;
    private RingerTypeEnum ringerTypeEnum;
    private boolean isRingModeRegister = false;
    private int ringMode = -1;


    private static SoundPlayerUtils instance = null;
    private RingModeChangeReceiver ringModeChangeReceiver;


    public static SoundPlayerUtils getInstance() {
        if(instance == null) {
            synchronized (SoundPlayerUtils.class) {
                if(instance == null) {
                    instance = new SoundPlayerUtils();
                }
            }
        }
        return instance;
    }


    public SoundPlayerUtils() {
        this.context = MyApp.CONTEXT;//全局上下文对象,getApplicationContext();
    }


    public synchronized void play(RingerTypeEnum type) {
        Log.e(TAG, "play type->" + type.name());
        this.ringerTypeEnum = type;
        int ringId = 0;
        switch (type) {
            case SOUND_ONE:
                ringId = R.raw.sound_01;
                loop = false;//是否重复播放铃声
                break;
            case SOUND_TWO:
                ringId = R.raw.sound_02;
                loop = true;
                break;
            case SOUND_THREE:
                ringId = R.raw.sound_03;
                loop = false;
                break;
            case SOUND_FOUR:
                ringId = R.raw.sound_04;
                loop = true;
                break;
        }


        if(ringId != 0) {
            play(ringId);
        }
    }


    public void stop() {
        Log.e(TAG, "stop");
        if (soundPool != null) {
            if (streamId != 0) {
                soundPool.stop(streamId);
                streamId = 0;
            }
            if (soundId != 0) {
                soundPool.unload(soundId);
                soundId = 0;
            }
        }
        if (isRingModeRegister) {
            registerVolumeReceiver(false);
        }
    }


    private void play(int ringId) {
        initSoundPool();
        if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
            soundId = soundPool.load(context, ringId, 1);
        }
    }


    private void initSoundPool() {
        stop();
        if (soundPool == null) {
            soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
            soundPool.setOnLoadCompleteListener(onLoadCompleteListener);


            audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
            ringMode = audioManager.getRingerMode();
        }
        registerVolumeReceiver(true);
    }


    SoundPool.OnLoadCompleteListener onLoadCompleteListener = new SoundPool.OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
            if (soundId != 0 && status == 0) {
                if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
                    int curVolume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
                    streamId = soundPool.play(soundId, curVolume, curVolume, 1, loop ? -1 : 0, 1f);
                }
            }
        }
    };


    private void registerVolumeReceiver(boolean register){
        if (ringModeChangeReceiver == null) {
            ringModeChangeReceiver = new RingModeChangeReceiver() ;
        }


        if (register) {
            isRingModeRegister = true;
            IntentFilter filter = new IntentFilter() ;
            filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION) ;
            context.registerReceiver(ringModeChangeReceiver, filter) ;
        } else {
            context.unregisterReceiver(ringModeChangeReceiver);
            isRingModeRegister = false;
        }
    }


    private class RingModeChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (ringMode != -1 && ringMode != audioManager.getRingerMode()
                    && intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
                ringMode = audioManager.getRingerMode();
                play(ringerTypeEnum);
            }
        }
    }
}

Activity:

public class MainActivity extends BaseActivity {
    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }


    @Override
    protected void initView() {

    }


    @OnClick({R.id.btn_sound_one,R.id.btn_sound_two,R.id.btn_sound_three,R.id.btn_sound_four})
    public void clicked(View view) {
        switch (view.getId()) {
            case R.id.btn_sound_one:
                SoundPlayerUtils.getInstance().play(SoundPlayerUtils.RingerTypeEnum.SOUND_ONE);
                break;


            case R.id.btn_sound_two:
                SoundPlayerUtils.getInstance().play(SoundPlayerUtils.RingerTypeEnum.SOUND_TWO);
                break;


            case R.id.btn_sound_three:
                SoundPlayerUtils.getInstance().play(SoundPlayerUtils.RingerTypeEnum.SOUND_THREE);
                break;


            case R.id.btn_sound_four:
                SoundPlayerUtils.getInstance().play(SoundPlayerUtils.RingerTypeEnum.SOUND_FOUR);
                break;
        }
    }

}

  布局:

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.hjq.bar.TitleBar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:background="@color/teal_200"
        android:layout_height="?android:attr/actionBarSize"
        app:title="SoundPool 播放音频"
        app:titleStyle="bold"
        app:titleSize="18sp"
        app:backButton="false"
        app:titleColor="@color/white"/>

    <Button
        android:id="@+id/btn_sound_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="音频 1" />

    <Button
        android:id="@+id/btn_sound_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="音频 2" />

    <Button
        android:id="@+id/btn_sound_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="音频 3" />

    <Button
        android:id="@+id/btn_sound_four"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="音频 4" />
</LinearLayout>

最后需要新建 raw 目录,将所需要播放的音频文件放入

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值