美文网首页
使用SoundPool播放简短提示音+连续播报

使用SoundPool播放简短提示音+连续播报

作者: 番茄tomato | 来源:发表于2019-08-26 10:29 被阅读0次

https://blog.csdn.net/hellokandy/article/details/79859670

1.简单使用

这是我需要播放的mp3文件


image.png

在一开始建立两个对象:

    //播放提示音
    private SoundPool sp;
    private int soundId;

然后在onCreat中初始化音频文件(需要花费一点时间,所以提前初始化好)

        //初始化音频文件
        sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
        soundId = sp.load(this, R.raw.notification, 1);

完成playNotification()方法:其实就只有一句话,可以直接在需要的地方调用

    public void playNotification() {//播放提示音

/*        不能在此初始化 需要花费时间 导致提示音播放不出来
SoundPool sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
        int soundId = sp.load(this, R.raw.notification, 1);*/

        sp.play(soundId, 1, 1, 0, 0, 1);

    }

2.拓展 SoundPool 进行连续播报

明确一点 SoundPool 没有播放完成的回调方法,所以只能在异步线程中播报时,根据播报时间让线程sleep。但是SoundPool 播报的一般都是比较短的音效,所以在设置合适的sleep时间后 基本上不会有声音的冲突。
针对不同的业务需求可以创建不同的播报工具类
例如 我遇到的业务需求,播报批次号码
语音 eg: "批次号 1,2,3,4"
我采用的是先将0~9语音录下来,然后根据需要播报的批次号进行拼接
根据文字在线生成mp3 (单字加上句号 一 ---> 一。)
https://app.xunjiepdf.com/

我的播报工具类BatchSortPromptPlayer
注释写的非常清楚 就不多赘述了 修改一下音频文件这些 再作一下其他细节的修改,就可以直接用了(认真看注释)

public class BatchSortPromptPlayer {
    //SoundPool播报对象
    private SoundPool soundPool;
    //存放播报音频的list
    private List<Integer> promptList = new ArrayList<>();
    private Context context;

    //特殊语音,比如出错的时候 对应的关键码
//根据业务需求自己配置
    public static final int BATCHNUM = 10;
    public static final int HASBEENSORTING = 11;
    public static final int NEEDREBACKUP = 12;
    public static final int SORTFAILD = 13;


    //构造函数中 初始化soundPool
    public BatchSortPromptPlayer(Context activitycontext) {
        this.context = activitycontext;
        soundPool = new SoundPool(15, AudioManager.STREAM_MUSIC, 0);
    }

    //调用此方法异步加载 所有音频文件
    public void loadAudioFile() {
        //加载音频文件
        Observable.create(new Observable.OnSubscribe<Object>() {
            @Override
            public void call(Subscriber<? super Object> subscriber) {

                Log.d("播放提示音", "开始加载音频");
                //prompt0~prompt9 分别对应的单音节 零~九
                promptList.add(soundPool.load(context, R.raw.prompt0, 1));
                promptList.add(soundPool.load(context, R.raw.prompt1, 1));
                promptList.add(soundPool.load(context, R.raw.prompt2, 1));
                promptList.add(soundPool.load(context, R.raw.prompt3, 1));
                promptList.add(soundPool.load(context, R.raw.prompt4, 1));
                promptList.add(soundPool.load(context, R.raw.prompt5, 1));
                promptList.add(soundPool.load(context, R.raw.prompt6, 1));
                promptList.add(soundPool.load(context, R.raw.prompt7, 1));
                promptList.add(soundPool.load(context, R.raw.prompt8, 1));
                promptList.add(soundPool.load(context, R.raw.prompt9, 1));
                //后边的音频文件为其他需要
//根据业务需求自己配置
                promptList.add(soundPool.load(context, R.raw.batch_num, 1));
                promptList.add(soundPool.load(context, R.raw.has_been_sorting, 1));
                promptList.add(soundPool.load(context, R.raw.need_rebackup, 1));
                promptList.add(soundPool.load(context, R.raw.sort_faild, 1));

                Log.d("播放提示音", "音频加载完成" + promptList.size());
            }
        }).subscribeOn(Schedulers.io())
                .subscribe();
    }

    /**
     * 播放指定提示音
     * 例 需要重新备份
     */
    public void playPrompt(int playKey) {
        Observable.create(new Observable.OnSubscribe<Object>() {
            @Override
            public void call(Subscriber<? super Object> subscriber) {
                soundPool.play(promptList.get(playKey), 1, 1, 0, 0, 1);
            }
        }).subscribeOn(Schedulers.io())
                .subscribe();
    }


    /**
     * 根据传入的批次号 播放提示音 例:“批次号5800”
     * <p>
     * String batchNum:批次号
     * 播报方式:
     * 将批次号拆开 5800->5,8,0,0
     * 单个播放
     */
    public void playPrompt(String batchNum) {
        Observable.create(new Observable.OnSubscribe<Object>() {
            @Override
            public void call(Subscriber<? super Object> subscriber) {
                //播报批次号之前 播报语音“批次号”
                soundPool.play(promptList.get(BATCHNUM), 1, 1, 0, 0, 1);
                try {
                    //“批次号”这个三个字的音频大概1秒 所以线程等待1.2秒 等播完再开始数字
                    Thread.sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //将批次号拆开 5800->5,8,0,0 单个播放
                for (char i : batchNum.toCharArray()) {
                    //这里将char转换为int  '5'->5
                    soundPool.play(promptList.get(Integer.parseInt(String.valueOf(i))), 1, 1, 0, 0, 1);
                    try {
                        //此处每个数字单音节播报之间间隔0.5秒(根据实际情况调节)
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).subscribeOn(Schedulers.io())
                .subscribe();
        /**
         * 注意线程中出错 比如本来是纯数字的批次号出现了一个字母 会导致线程内部出错 
         * 由于没有在subscribe()设置订阅者 也就没有onError处理
         * 所以会导致程序崩溃 需要严格注意传入的批次号内容
         * */
    }
    //在activity的onDestroy中释放资源
    public void releaseSoundPool() {
        promptList.clear();
        soundPool.release();//释放soundPool资源
    }

}

在activity中的用法:

BatchSortPromptPlayer batchSortPromptPlayer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
......
//实例化对象
batchSortPromptPlayer=new BatchSortPromptPlayer (this);
//紧接着开始加载音频文件(耗时操作 提前进行)
batchSortPromptPlayer.loadAudioFile();
......
}
......
public void test(){
//在需要播放语音的方法中调用:
batchSortPromptPlayer.playPrompt("1234");
//或者播放失败警告:
batchSortPromptPlayer.playPrompt(SORTFAILD);
}
.....
//最后 在onDestroy中回收资源
    @Override
    protected void onDestroy() {
        super.onDestroy();
        batchSortPromptPlayer.releaseSoundPool();
    }

相关文章

网友评论

      本文标题:使用SoundPool播放简短提示音+连续播报

      本文链接:https://www.haomeiwen.com/subject/svfrectx.html