android音频音乐播放soundpool

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a5nan/article/details/77503172

音频播放类

在Android开发中我们经常使用MediaPlayer来播放音频文件,但是除了MediaPlayer以外还有SoundPool和AudioTrack可以播放音频:

MediaPlayer类——开发者最熟悉的类,常用于播放长音频,拥有更完整的封装和状态控制,但是缺点也很明显:资源占用量较高、延迟时间较长、不支持多个音频同时播放;

AudioTrack类——不同于MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。而AudioTrack只能播放PCM数据流。但事实上,两种本质上是没啥区别的,MediaPlayer在播放音频时,在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,最后由AudioFlinger进行混音,传递音频给硬件播放出来。利用AudioTrack播放只是跳过Mediaplayer的解码部分而已。Mediaplayer的解码核心部分是基于OpenCORE 来实现的,支持通用的音视频和图像格式,codec使用的是OpenMAX接口来进行扩展。因此使用audiotrack播放mp3文件的话,要自己加入一个音频解码器,如libmad。否则只能播放PCM数据,如大多数WAV格式的音频文件。优势就是可以边读取边播放,大音频必用

SoundPool类——使用音效池的概念来管理多个短促的音效,常用播放游戏,点击声音等短音频。与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。另外,SoundPool还支持自行设置声音的品质、音量、播放比率等参数,支持通过ID对多个音频流进行管理。SoundPool加载音乐文件使用了独立的线程,不会堵塞UI主线程的操作。缺陷:需要提前加载数据,没有播放完毕监听。今天主要说的就是这个类。

构造方法

SoundPool提供了一个构造器,该构造器可以用来指定它总共支持多少个声音以及声音的品质等。

在API 21以前需要直接使用构造方法如下所示,第一个参数表示音效池的容量,第二个参数表示音效类型,第三个参数表示声音品质

SoundPool pool = new SoundPool(20,AudioManager.STREAM_SYSTEM,5);

API 21及以后,Android其大部分控件的创建都采用了建造者模式,也就是这样

SoundPool pool = new SoundPool.Builder().setMaxStreams(20).build();

这样的模式使得创建过程清晰,不像直接调用构造方法不容易看懂参数含义。

load方法

当我们创建完成SoundPool对象之后,我们就可以使用load方法加载声音了,SoundPool提供了4种重载

1,从指定文件路径去加载声音,第二个参数代表优先级,下同

public int load(String path, int priority)

2,从对应的资源id加载声音

public int load(Context context, int resId, int priority)

3,根据文件描述去加载一个声音

public int load(AssetFileDescriptor afd, int priority)

4,根据文件描述加载一个声音的部分

public int load(FileDescriptor fd, long offset, long length, int priority)

上面4个方法加载声音之后,都会返回该声音的的ID,以后程序就可以通过该声音的ID 来播放指定声音。

播放

在上面load以后会的到一个int类型的soundID返回值,这个返回值就是代表了声音的ID,于是当我们需要播放声音的时候,可以使用ID。

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

上面方法第一个参数就是声音的ID,第二个参数为左声道音量(最大值为1.0F),第三个参数为右声道音量,第四个参数为优先级,第五个参数为是否循环播放(0为不循环,-1为循环),第六个参数为播放速度(取值范围为0.5F-2.0F,正常值为1F)

监听方法

AndroidSDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解媒体文件是否加载完毕,我们重载onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法就可以获得。如果没有load完就play的话会报错。

示例代码:

public SoundPool pool;
pool = new SoundPool.Builder().setMaxStreams(20).build();//API21以后的方法
soundId = pool.load(this, R.raw.dog, 1);//加载
pool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f);//播放

pool.release();//释放内存
pool=null;



猜你喜欢

转载自blog.csdn.net/a5nan/article/details/77503172