美文网首页
使用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