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();
}
网友评论