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

Posted 特立独行的猫a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android使用SoundPool播放语音,并实现按顺序延时播放相关的知识,希望对你有一定的参考价值。

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

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

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

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

/**
 * @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工具类。

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()
    }
}

 

以上是关于Android使用SoundPool播放语音,并实现按顺序延时播放的主要内容,如果未能解决你的问题,请参考以下文章

蓝牙延迟和 Android 音频提示

Android中使用SoundPool来播放音频

Android开发之SoundPool使用详解

如何使用 Android 动画播放“滴答滴答”声音(可能使用“Android MediaPlayer / SoundPool”)?

Xamarin.Android 使用SoundPool进行音频播放

为啥我的 SoundPool 声音第一次在 Android 上没有播放?