Android 音效 & SoundPool 封装类 & 停止音效播放

项目中,需要添加点击或者状态回调的音效。
Android 有专门用于实现音效播放的类,就是 SoundPool 。

1 工具类封装

共四种音效,更多可在 init 中 自行添加。

/**
 * <pre>
 *     author : jake
 *     time   : 2019/01/10
 *     function   :   音效管理类
 *     version: 1.3.0
 * </pre>
 */

class SoundPoolManager {

    companion object {
        private var instance: SoundPoolManager? = null
            get() {
                if (field == null) {
                    field = SoundPoolManager()
                }
                return field
            }

        @Synchronized
        fun get(): SoundPoolManager {
            return instance!!
        }

        const val TASK_CLICK = 1
        const val TASK_SUCCESS = 2
        const val TASK_WRONG = 3
        const val TASK_REWARD = 4
    }


    private var soundPool: SoundPool = SoundPool(4, AudioManager.STREAM_MUSIC, 0)
    private var sourcesMap = HashMap<Int, Int>()

    init {
        sourcesMap[TASK_CLICK] = soundPool.load(RiseApp.mContext, R.raw.click, 1)
        sourcesMap[TASK_SUCCESS] = soundPool.load(RiseApp.mContext, R.raw.success, 1)
        sourcesMap[TASK_WRONG] = soundPool.load(RiseApp.mContext, R.raw.wrong, 1)
        sourcesMap[TASK_REWARD] = soundPool.load(RiseApp.mContext, R.raw.reward, 1)
    }

    fun play(type: Int) {
        // 防止type不存在
        if (sourcesMap[type] != null) {
            soundPool.play(sourcesMap[type]!!, 1.0f, 1.0f, 0, 0, 1.0f)
        }
    }
}

在触发的地方,直接使用即可

   SoundPoolManager.get().play(SoundPoolManager.TASK_CLICK)

2 音效停止播放(2019.4.23)

头一次遇到还要音效播一半,还要停止的。(音效比较多,且比较长,多次点击重复混合播放)

按照经验,肯定是通过 url 来判断是停止播放,还是开始播放新音效(两次传入相同则停止,否则则播放新的),然而发现并不生效。

后来想到,因为是一个 音效对象池,是不是播放第一个音效和播放第二个音效用不是同一个对象,从而导致调用停止方法无效的?

就是这个原因

当我们调用下面方法播放音效时,其返回值就是当前播放音效的 对象ID,且每次都不一样

soundPool.play(sourcesMap[path]!!, 1.0f, 1.0f, 0, 0, 1.0f)

所以我们只需要存储一下,上一次播放音效时的 对象ID ,然后在调用 stop 方法时,传入 对象ID 即可停止播放音效。

存储上次播放时的 音效对象ID

 lastSound = soundPool.play(sourcesMap[path]!!, 1.0f, 1.0f, 0, 0, 1.0f)

停止时传入

 soundPool.stop(lastSound)

由于,后来项目中用的不是打在APK 中的本地音效,而是下载到设备特定目录的音频文件,还有一些其他对应关系,故又重新封装了新的工具类,如下:

/**
 * <pre>
 *     author : jake
 *     time   : 2019/03/10
 *     function   :   音效管理类
 *     version: 1.0
 * </pre>
 *
 * 根据下载到本地的音效路径,播放音效
 *
 * 在音效下载完毕后,会调用初始化方法  LibrarySoundsManager
 *
 */

class LibrarySoundPoolManager {

    companion object {
        private var instance: LibrarySoundPoolManager? = null
            get() {
                if (field == null) {
                    field = LibrarySoundPoolManager()
                }
                return field
            }

        @Synchronized
        fun get(): LibrarySoundPoolManager {
            return instance!!
        }

        private var soundPool: SoundPool = SoundPool(37, AudioManager.STREAM_MUSIC, 0)
        private var sourcesMap = HashMap<String, Int>()
        private var lastSound = 0
    }

    /**
     * 预加载 图书馆音效资源
     *
     * 调用此方法时,证明图书馆音效资源已经下载完毕
     */
    fun init(content: String) {
        /**
         * 获取前端数据,并解析
         */
        val json = JSONObject(content)
        val path = json["path"].toString()
        val data = path.split("^")
        if (data != null && data.size > 0) {
            for (item in data) {
                if (!item.isEmpty() && sourcesMap[RiseWebPath.LibraryWebKey.plus("/sounds/").plus(item)] == null) {
                    sourcesMap[RiseWebPath.LibraryWebKey.plus("/sounds/").plus(item)] = soundPool.load("${RisePath.libraryDir}/sounds/$item", 1)
                }
            }
        }

    }

    /**
     * 根据下载到本地的音效路径,播放音效
     */
    fun play(path: String) {
        if (!path.isEmpty() && sourcesMap[path] != null) {
            soundPool.stop(lastSound)
            lastSound = soundPool.play(sourcesMap[path]!!, 1.0f, 1.0f, 0, 0, 1.0f)
        }
    }

    /**
     * 停止播放所有音效
     */
    fun stop() {
        soundPool.stop(lastSound)
    }
}

具体各个参数的含义,可参考这篇文章,说的蛮详细的。

うずまき ナルト
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 转载请注明出处(https://www.jianshu.com/p/5f538820e370),您的打赏是小编继续...
    福later阅读 29,615评论 8 73
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,782评论 4 61
  • 最近在公司的状态,很是一般,对项目没有刚开始那会儿的激情,只因心中在纠结到底要不要去深圳。 目前的公司不差,待遇也...
    tzzzy阅读 406评论 0 0
  • 每天下午四点,准点吃面包[呲牙] 近日,我们的生活毫无规律中找到了一丝小习惯。下午小憩之后,我会自觉地研磨豆子,煮...
    实习村姑童小姐阅读 336评论 0 4
  • 刚才给闺女听写,我说,我喜欢清新的空气和阳光,闺女问是“喜欢”还是“爱”,仔细看书,纠正道,是“爱”昂,都差不多的...
    杭杭出状元阅读 150评论 0 7

友情链接更多精彩内容