忙了两天终于得空写点东西,感慨良多,今天主要总结一下,这个SoundPool的使用,以及注意事项。
首先,SoundPool的定位,她是一个音效播放的执行者,这跟MediaPlayer的最终效果是一样的,她们都是用来播放音乐的。
今天,我们主讲一下,SoundPool这个类。附带的说一说她与MediaPlayer的区别。
下面我们说一下SoundPool播放音频的实现步骤:
1. new出一个实例 ;
new SoundPool(int maxStream, int streamType, int srcQuality);
maxStream —— 同时播放的流的最大数量
streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值
比如说,
new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
创建了一个最多支持4个流同时播放的,类型标记为音乐的SoundPool。
2.加载
一般把多个声音放到HashMap中去,比如
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundPoolMap = new HashMap<Integer, Integer>();
soundPoolMap.put(1, soundPool.load(this, R.raw.ring, 1));
当然,我们也可以加载单个的Music,那我们怎么实现播放指定的Music呢?
有关载入音效的方法,有以下几种方法:
1
int load(Context context, int resId, int priority) //从APK资源载入(就是说,在你码代码的时候工程中的文件。比如,我在res/raw这个文件夹中放了一个ring.mp3,那,resIdential就是 R.raw.ring)
2
int load(FileDescriptor fd, long offset, long length, int priority) //从FileDescriptor对象载入
3
int load(AssetFileDescriptor afd, int priority) //从Asset对象载入
4
int load(String path, int priority) //从完整文件路径名载入
5
6
所有的最后一个参数 priority 是优先级。这里用于播放多个文件时,系统会优先处理。
3,播放
play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate);
其中soundID,就是刚刚load方法得到的那个int型参数,leftVolume和rightVolume表示左右音量,priority表示优先级,loop表示循环次数,rate表示速率,如
//速率最低0.5最高为2,1代表正常速度
sp.play(soundId, 1, 1, 0, 0, 1);
4,停止
停止可以使用 pause(int streamID) 方法,这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量,而id从0开始。
OK,这就是一个SoundPool的流程,可是,有人要问了,为什么我按这个流程写下来,却没有播放呢?
不饶弯子,因为,在play之前Soundpool没有初始化完毕,那我们如何知道,Soundpool的load已经完毕了呢?Android提供了检测是否初始化完毕的方法,SoundPool.OnLoadCompleteListener;但是这个方法是从SDK2.2才开始有的。所以找错之前,先看看自己的平台。。。
下面讲下两个播放形式的利弊:
一,使用MediaPlayer来播放音频文件存在一些不足:
例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。
这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,所有,一般的游戏开发都是用的Soundpool。
在没有了解Soundpool之前,我也是使用的普通的MediaPlayer进行文件播放,但这个方法不适合用于游戏开发,因为游戏里面经常要同时播放几个音乐文件,用过MediaPlayer的朋友都该知道,它是不支持实时播放多个声音的,而且还会出现或多或少的延迟,尤其是在快速连续播放声音(比如连续猛点按钮)时,会非常明显,长的时候会出现3~5秒的延迟,【使用MediaPlayer.seekTo() 这个方法来解决此问题】;
相对于使用SoundPool存在的一些问题:
1. SoundPool是为播放小文件而存在的。一般限定Soundpool播放文件的大小为1M。
2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
3. 音频格式建议使用OGG格式。使用WAV格式的音频文件存放游戏音效,经过反复测试,在音效播放间隔较短的情况下会出现异常关闭的情况(有说法是SoundPool目前只对16bit的WAV文件有较好的支持)。后来将文件转成OGG格式,问题得到了解决。
4.在使用SoundPool播放音频的时候,如果在初始化中就调用播放函数进行播放音乐那么根本没有声音,不是因为没有执行,而是SoundPool需要一准备时间!这就是刚刚我们说的用OnLoadCompleteListener来解决的问题。如果你非得是1.6甚至更低的话,那建议在播放的时候,将play放到一个点击事件中去,当然在这个中也要注意一下两点。
a、 别忘记绑定操作! mp.setOnCompletionListener(this);
b、如果你设置了循环播放 mp.setLooping(true); 的话,那么永远都不会监听到播放完成的状态!!
下面分享一下源码,
01
import android.app.Activity;
02
import android.media.AudioManager;
03
import android.media.SoundPool;
04
import android.os.Bundle;
05
import android.os.Handler;
06
import android.os.Message;
07
import android.view.View;
08
import android.view.View.OnClickListener;
09
import android.widget.Button;
10
import android.media.SoundPool.OnLoadCompleteListener;</p>
11
public class DemoActivity extends Activity implements SoundPool.OnLoadCompleteListener{
12
13
private Button button;
14
private SoundPool sndPool;
15
private int hitOkSfx;
16
private static final int SOUND_LOAD_OK = 1;
17
private final Handler mHandler = new MyHandler() ;
18
@Override
19
public void onCreate(Bundle savedInstanceState) {
20
super.onCreate(savedInstanceState);
21
setContentView(R.layout.main);
22
button = (Button)findViewById(R.id.button1);
23
sndPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 0);
24
sndPool.setOnLoadCompleteListener(this);
25
hitOkSfx = sndPool.load(this, R.raw.ring, 1);
26
button.setOnClickListener(new OnClickListener() {
27
@Override
28
public void onClick(View v) {
29
// TODO Auto-generated method stub
30
sndPool.play(hitOkSfx, 10, 10, 0, 0, (float)1);//播放铃声
31
}
32
});
33
}
34
@Override
35
protected void onDestroy() {
36
// TODO Auto-generated method stub
37
sndPool.release();
38
sndPool.stop(hitOkSfx);
39
super.onDestroy();
40
41
}
42
private class MyHandler extends Handler {
43
public void handleMessage(Message msg){
44
switch( msg.what){
45
case SOUND_LOAD_OK:
46
sndPool.play(hitOkSfx, 10, 10, 0, 0, (float)1);//播放铃声
47
break;
48
}
49
}
50
}
51
@Override
52
public void onl oadComplete(SoundPool soundPool, int sampleId, int status) {
53
// TODO Auto-generated method stub
54
Message msg = mHandler.obtainMessage(SOUND_LOAD_OK); ;
55
msg.arg1 = sampleId ;
56
mHandler.sendMessage(msg);
57
}
58
59
}
这个就到这里了吧。。。
标签:int,sndPool,SoundPool,开发,import,Android,播放,android From: https://blog.51cto.com/u_548275/6886115