Android 平台中关于音频播放有以下两种方式:
2. MediaPlayer —— 适合比较长且对时间要求不高的情况
本篇是讲解SoudPool播放音乐
一、创建一个SoundPool对象
二、加载音乐文件资源,得到代表音频文件的id, 加载过程是一个将音频解压为原始16位PCM数据的过程,由一个后台线程来进行异步处理,所以不会阻塞所在线程,但是加载音乐文件会花一段时间,因此不能立即播放,需要等待一点时间等加载完后才能播放。加载音乐文件可以使用SoundPool类中的下面四种方法来完成,即使用四个SoundPoole类中重载的四个load函数来加载
(方法1)int load(Context context, int resId, int priority)
(方法2)int load(AssetFileDescriptor afd, int priority)
参数datagramSocket对象的创建参考下面的构造函数
DatagramSocket()://邦定本地任何port和绑定本地ip的的DatagramSocket
DatagramSocket(int aPort)//绑定端口为aPort和绑定本地ip的DatagramSocket
DatagramSocket(int aPort, InetAddress addr);绑定端口aPort和绑定addr中封装的ip的DatagramSocket
DatagramSocket(SocketAddress localAddr);绑定localAddr中封装的port和ip的DatagramSocket,如果失败返回
null
(方法3) int load(String path, int priority)
(方法4) int load(FileDescriptor fd, long offset, long length, int priority)
三、播放控制(SoundPool类中提供有相应的函数控制播放音乐)
(1)播放音乐
final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop,floatrate)
播放指定音频的音效,并返回一个streamID,如果失败返回0;
参数soundId: 即SoundPool对象load函数的返回值
参数priority:音频的优先级,值越大优先级高,影响当同时播放数量超出了最大支持数时SoundPool对该流的处理;SoundPool类的构造函数SoundPool(int maxStream, int StreamType, int srcuality)中参数maxStream指定了SoundPool对象能同时播音乐文件的最大数量maxStream,所以当使用SoundPool对象循环调用play播放音乐,如果调用数量超过了maxStream,则就会根据paly中的priority设置的权限来确定哪些被播放,哪些不会被播放。
参数loop: 循环播放的次数,0为值播放一次,-1为无限循环,其他值为播放loop+1次(例如,3为一共播放次)。
参数rate:播放的速率,范围0.5-2.0(0.5为一半速率,1.0为正常速率,2.0为两倍速率)
参数leftVolume:左声道音量, 值在0.0f到1.0之前
参数rightVolume:左声道音量, 值在0.0f到1.0之前
例:
AudioManager mgr = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = streamVolumeCurrent/streamVolumeMax;
int streamID1 = soundPool.play(soundId1, volume, volume, 1, 0, 1.0f);//播放1次音乐
int streamID2 = soundPool.play(soundId2, volume, volume, 1, 2, 1.0f);//循环播放3次音乐
int streamID3 = soundPool.play(soundId3, volume, volume, 1, 2, 1.0f);//循环播无限次音乐
*以上play函数中第一个参数是SoundPool对象的load函数的返回值
(2)暂停soundID1的播放
soundPool.pause(streamID );
(3)恢复soundID1的播放
soundPool.resume(streamID );
(4)终止播放
soundPool.stop(streamID );
*API中指出,即使使用无效的soundID /streamID (操作失败或指向无效的资源)来调用相关函数也不会导致错误,例如,streamID代表的音频之前已经stop了,再调用一次stop也不会报错,但也不产生任何的效果。
其实就是paly()中的一些参数的独立设置:
final void setLoop(int streamID, int loop)
设置指定播放流的循环.
final void setVolume(int streamID, float leftVolume, float rightVolume)
设置指定播放流的音量.
final void setPriority(int streamID, int priority)
设置指定播放流的优先级,上面已说明priority的作用.
final void setRate(int streamID, float rate)
设置指定播放流的速率,0.5-2.0.
(5) 释放资源
可操作的函数有:
final boolean unload(int soundID)
卸载一个指定的音频资源.
final void release()
释放SoundPool中的所有音频资源
以上篇幅详细讲解了SoundPool播放音乐的知识点,下面整体举一个
最简单的例子(我们假设下面的代码是在Activity的子类中写的)
代码1:创建SoundPool对象,最多能同时播放的音乐为3个
SoundPool soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0)
代码2: 加载音乐文件
int soundID = soundPool.load(this, R.raw.dingdong, 1);
(*假设在项目的/res/raw/目录下有音乐文件dingdong.ogg
代码3:播放音乐,左右音道音量大小为volume,播放优先级为1,播放次数(0+1)次,并且以正常速度播放
AudioManager mgr = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = streamVolumeCurrent/streamVolumeMax;
int streamID1 = soundPool.play(soundId1, volume, volume, 1, 0, 1.0f)
代码4:暂停soundID的播放
soundPool.pause(streamID);
代码5:终止播放
soundPool.stop(streamID);
代码6:释放load函数加载的音乐资源
unload(soundID)