android使用SoundPool播放音效的方法

 更新时间:2017年11月28日 09:17:31   作者:蛋蛋松  
本篇文章主要介绍了android使用SoundPool播放音效的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

在Android开发中我们经常使用MediaPlayer来播放音频文件,但是MediaPlayer存在一些不足,例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,例如在对时间精准度要求相对较高的游戏开发中。

在游戏开发中我们经常需要播放一些游戏音效(比如:子弹爆炸,物体撞击等),这些音效的共同特点是短促、密集、延迟程度小。在这样的场景下,我们可以使用SoundPool代替MediaPlayer来播放这些音效。

SoundPool(android.media.SoundPool),顾名思义是声音池的意思,主要用于播放一些较短的声音片段,支持从程序的资源或文件系统加载。与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。另外,SoundPool还支持自行设置声音的品质、音量、播放比率等参数,支持通过ID对多个音频流进行管理。

就现在已知的资料来说,SoundPool有一些设计上的BUG,从固件版本1.0开始有些还没有修复,我们在使用中应该小心再小心。相信将来Google会修复这些问题,但我们最好还是列出来:

  1. SoundPool最大只能申请1M的内存空间,这就意味着我们只能用一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。

  2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。建议使用这两个方法的时候尽可能多做测试工作,还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。

  3. SoundPool的效率问题。其实SoundPool的效率在这些播放类中算是很好的了,但是有的朋友在G1中测试它还是有100ms左右的延迟,这可能会影响用户体验。也许这不能管SoundPool本身,因为到了性能比较好的Droid中这个延迟就可以让人接受了。

在现阶段SoundPool有这些缺陷,但也有着它不可替代的优点,基于这些我们建议大在如下情况中多使用SoundPool:1.应用程序中的声效(按键提示音,消息等)2.游戏中密集而短暂的声音(如多个飞船同时爆炸)

1.相关方法介绍:

1)构造方法:

SoundPool(int maxStreams, int streamType, int srcQuality) 参数依次是:

①指定支持多少个声音,SoundPool对象中允许同时存在的最大流的数量。

②指定声音类型,流类型可以分为STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING,STREAM_MUSIC 和 STREAM_ALARM四种类型。在AudioManager中定义。

③指定声音品质(采样率变换质量),一般直接设置为0!

在低版本中可以用上述构造方法,而API 21(Android 5.0)后这个构造方法就过时了! 而用到一个SoundPool.Builder的东东,我们要实例化SoundPool只需调用:

SoundPool.Builder spb = new SoundPool.Builder();
spb.setMaxStreams(10);
spb.setAudioAttributes(null);  //转换音频格式
SoundPool sp = spb.build();   //创建SoundPool对象

要使用上述代码的话,TargetSDK版本要设置大于等于21哦!而且如果minSDK版本小于21 会出现下面的提醒:


2)常用方法介绍:

①加载声音资源:

  1. load(Context context, int resId, int priority)
  2. load(String path, int priority)
  3. load(FileDescriptor fd, long offset, long length, int priority)
  4. load(AssetFileDescriptor afd, int priority) 上述方法都会返回一个声音的ID,后面我们可以通过这个ID来播放指定的声音

参数介绍:

  1. context:上下文
  2. resId:资源id
  3. priority:没什么用的一个参数,建议设置为1,保持和未来的兼容性
  4. path:文件路径
  5. FileDescriptor:貌似是流吧,这个我也不知道
  6. AssetFileDescriptor:从asset目录读取某个资源文件,用法:
AssetFileDescriptor descriptor = assetManager.openFd("biaobiao.mp3");

②播放控制:

play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

参数依次是:

  1. soundID:Load()返回的声音ID号
  2. leftVolume:左声道音量设置
  3. rightVolume:右声道音量设置
  4. priority:指定播放声音的优先级,数值越高,优先级越大。
  5. loop:指定是否循环:-1表示无限循环,0表示不循环,其他值表示要重复播放的次数
  6. rate:指定播放速率:1.0的播放率可以使声音按照其原始频率,而2.0的播放速率,可以使声音按照其 原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。

③资源释放:

可以调用release()方法释放所有SoundPool对象占据的内存和资源,当然也可以根据声音 ID来释放!

3.使用代码示例:

运行效果图:


当点击按钮的时候会,"Duang"一下,这里演示了两种load的方法,分别是raw和assests!

关键代码:

MainActivity.java:

private void initSP() throws Exception{
    //设置最多可容纳5个音频流,音频的品质为5
    mSoundPool = new SoundPool(5, AudioManager.STREAM_SYSTEM, 5);
    soundID.put(1, mSoundPool.load(this, R.raw.duang, 1));
    soundID.put(2 , mSoundPool.load(getAssets().openFd("biaobiao.mp3") , 1)); //需要捕获IO异常
    soundID.put(3, mSoundPool.load(this, R.raw.duang, 1));
    soundID.put(4, mSoundPool.load(this, R.raw.duang, 1));
    soundID.put(5, mSoundPool.load(this, R.raw.duang, 1));
  }

  @Override
  public void onClick(View v) {
    switch (v.getId()){
      case R.id.btn_play1:
        mSoundPool.play(soundID.get(1), 1, 1, 0, 0, 1);
        break;
      case R.id.btn_play2:
        mSoundPool.play(soundID.get(2), 1, 1, 0, 0, 1);
        break;
      case R.id.btn_play3:
        mSoundPool.play(soundID.get(3), 1, 1, 0, 0, 1);
        break;
      case R.id.btn_play4:
        mSoundPool.play(soundID.get(4), 1, 1, 0, 0, 1);
        break;
      case R.id.btn_play5:
        mSoundPool.play(soundID.get(5), 1, 1, 0, 0, 1);
        break;
      case R.id.btn_release:
        mSoundPool.release();  //回收SoundPool资源
        break;
    }

代码非常简单,另外如果你点击了最后一个按钮的话,SoundPool就会被释放,然后再其他按钮 就不会Duang了哦~

4.OnLoadCompleteListener监听声音文件是否加载完毕

嗯,这个是临时想起的,写完在写另一篇的时候突然想起,用法也很简单,我们可以 往上面的代码中添加OnLoadCompleteListener这个东东,然后重写onLoadComplete()方法 ,最后为SoundPool对象设置这个东东即可!

mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
  @Override
  public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
    Toast.makeText(MainActivity.this,"加特技准备完毕~",Toast.LENGTH_SHORT).show();
  }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android自定义View图片按Path运动和旋转

    Android自定义View图片按Path运动和旋转

    这篇文章主要为大家详细介绍了Android自定义View图片按Path运动和旋转,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Android自定义对话框Dialog的简单实现

    Android自定义对话框Dialog的简单实现

    这篇文章主要为大家详细介绍了Android自定义对话框Dialog的简单实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • Android实现上下菜单双向滑动效果

    Android实现上下菜单双向滑动效果

    这篇文章主要为大家详细介绍了Android实现上下菜单双向滑动效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Android5.0以上实现全透明的状态栏方法(仿网易云界面)

    Android5.0以上实现全透明的状态栏方法(仿网易云界面)

    下面小编就为大家分享一篇Android5.0以上实现全透明的状态栏方法(仿网易云界面),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Flutter学习之Navigator的高级用法分享

    Flutter学习之Navigator的高级用法分享

    这篇文章主要为大家详细介绍了Flutter中之Navigator的高级用法的相关知识,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-02-02
  • Android实现网易云音乐的旋转专辑View

    Android实现网易云音乐的旋转专辑View

    这篇文章主要为大家详细介绍了Android实现网易云音乐的旋转专辑View,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • Android空心圆及层叠效果实现代码

    Android空心圆及层叠效果实现代码

    这篇文章主要为大家详细介绍了Android空心圆及层叠效果实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • Android应用架构思想分析

    Android应用架构思想分析

    本篇文章是一个Android应用开发的老程序员写的关于Android应用架构思想分析的详细内容,希望对你有启发。
    2018-06-06
  • Android开发实现录屏小功能

    Android开发实现录屏小功能

    这篇文章主要介绍了Android开发实现录屏小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • Android 使用腾讯X5浏览器上传图片的示例

    Android 使用腾讯X5浏览器上传图片的示例

    这篇文章主要介绍了Android 使用腾讯X5浏览器上传图片的示例,帮助大家更好的理解和学习使用Android开发,感兴趣的朋友可以了解下
    2021-04-04

最新评论