前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android使用SoundPool播放语音,并实现按顺序延时播放

Android使用SoundPool播放语音,并实现按顺序延时播放

作者头像
杨永贞
发布2022-01-07 15:25:01
1.3K0
发布2022-01-07 15:25:01
举报

项目中有一个需求需要实现播报一连串的语音叫号。

如果有免费的tts文字转语音功能就好了,但是这些功能都是收费的,于是只能一个个有限的语音拼接起来。

使用SoundPool播放语音是异步的,如果不加控制没法达到效果,按顺序依次播放:请 XXX 号到XXXX 窗口 XX。

借助Rxjava很简单的就实现了这个功能,如下:

代码语言:javascript
复制
/**
 * @author yangyongzhen
 * @date 2021/6/11
 * @version 1.0.0
 * @desc  语音播报
 */
fun playTakeMealVoice(bean: OrderedHistorySecRecord){
        var orderno =  bean.orderno
        val windowid = dyPara?.windowId

        var listVoice = arrayListOf<Int>()
        val numbers = mapOf(
                "0" to R.raw.n0,
                "1" to R.raw.n1,
                "2" to R.raw.n2,
                "3" to R.raw.n3,
                "4" to R.raw.n4,
                "5" to R.raw.n5,
                "6" to R.raw.n6,
                "7" to R.raw.n7,
                "8" to R.raw.n8,
                "9" to  R.raw.n9)
        listVoice.add(R.raw.qing)
        if (orderno != null) {
            for ((index, chars) in orderno.withIndex()) {
                numbers["$chars"]?.let { listVoice.add(it) }
            }
        }
        listVoice.add(R.raw.hao)
        listVoice.add(R.raw.dao)
        if (windowid != null) {
            for ((index, chars) in windowid.withIndex()) {
                numbers["$chars"]?.let { listVoice.add(it) }
            }
        }
        listVoice.add(R.raw.chuangkou)
        listVoice.add(R.raw.qucan)
        var count = listVoice.size.toLong()
        Observable.interval(500, TimeUnit.MILLISECONDS).take(count).subscribe(object: Observer<Long> {
            override fun onComplete() {
                Log.d(TAG,"onComplete");
            }

            override fun onSubscribe(d: Disposable) {
                Log.d(TAG,"onSubscribe:")
            }

            override fun onNext(t: Long) {
                Log.d(TAG,"onNext:$t")
                SoundUtil.playMusic(iBillyView.getActivity(), listVoice[t.toInt()])
            }

            override fun onError(e: Throwable) {
                Log.d(TAG,"onError:" + e.message)
            }
        })

    }

以下是封装的SoundUtil工具类。

代码语言:javascript
复制
object SoundUtil {
    private var soundId: Int = 0
    private var soundPool: SoundPool? = null
    private val soundMap = hashMapOf<Int, Int>()

    fun playMusic(context: Context, mid: Int) {
        if (soundPool == null) {
            val mAudioAttributes = AudioAttributes.Builder().setLegacyStreamType(AudioManager.STREAM_MUSIC)
                    .build()
            soundPool = SoundPool.Builder().setMaxStreams(10).setAudioAttributes(mAudioAttributes).build()
        }
        try {
            if (soundMap.containsKey(mid)) {
                soundPool!!.play(soundMap[mid]!!, 1.0f, 1.0f, 1, 0, 1.0f)
            } else {
                soundId = soundPool!!.load(context, mid, 1)
                soundPool!!.setOnLoadCompleteListener { pool, _, _ ->
                    soundMap[mid] = soundId
                    //  加载完成
                    try {
                        pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f)
                    } catch (e: Exception) {
                    }
                }
            }
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
    }

    fun releaseMusic() {
        if (soundPool != null) {
            soundPool!!.release()
            soundPool = null
        }
        soundMap.clear()
    }
}

想打断语音播报怎么办?也很简单。

在playTakeMealVoice所在的类里面,定义个伴生对象companion object,里面声明个disposable

在每次播放前先来个 disposable?.dispose()

代码语言:javascript
复制
companion object {
        var disposable:Disposable?=null
    }
代码语言:javascript
复制
fun playTakeMealVoice(orderno:String?,winid:String?){
        Log.d(TAG,"playTakeMealVoice")
        disposable?.dispose()

在每次的订阅中,来个赋值:

代码语言:javascript
复制
......
Observable.interval(500, TimeUnit.MILLISECONDS).take(count).subscribeOn(Schedulers.io()).subscribe(object: Observer<Long> {
            override fun onComplete() {
                Log.d(TAG,"onComplete");
            }

            override fun onSubscribe(d: Disposable) {
                Log.d(TAG,"onSubscribe:")
                disposable = d //来个赋值
            }
......
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-06-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档