SoundPool 音频播放 详解 示例
官方文档
API 介绍
SoundPool(int maxStreams, int streamType, int srcQuality) This constructor was deprecated in API level 21. use SoundPool.Builder instead to create and configure a SoundPool instance- maxStream:同时播放的流的最大数量
- streamType:流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
- srcQuality:采样率转化质量,当前无效果,使用0作为默认值
- static void deprecateStreamTypeForPlayback(int streamType, String className, String opName)
- Use to generate warning or exception in legacy code paths that allowed passing stream types to qualify audio playback. 用于在旧代码路径中生成警告或异常,允许传递流类型限定音频播放。
- int soundID load(Context context, int resId, int priority) Load the sound from the specified APK resource.
- Note that the extension is dropped. For example, if you want to load a sound from the raw resource file "explosion.mp3", you would specify "R.raw.explosion" as the resource ID. Note that this means you cannot have both an "explosion.wav" and an "explosion.mp3" in the res/raw directory. 请注意,扩展名被删除。 例如,如果要从raw资源文件“explosion.mp3”加载声音,则应该指定“R.raw.explosion”作为资源ID。 请注意,这意味着您在res / raw目录中不能同时拥有“explosion.wav”和“explosion.mp3”文件。
- int priority: the priority of the sound. Currently has no effect. Use a value of 1 for future compatibility.
- Returns: a sound ID. This value can be used to play or unload the sound.
- int soundID load(String path, int priority) Load the sound from the specified path.
- int soundID load(AssetFileDescriptor afd, int priority) Load the sound from an asset file descriptor.
- int soundID load(FileDescriptor fd, long offset, long length, int priority) Load the sound from a FileDescriptor.
- This version is useful if you store multiple sounds in a single binary. The offset specifies the offset from the start of the file and the length specifies the length of the sound within the file. 如果您将多个声音存储在单个二进制文件中,则此版本很有用。 offset指定从文件开头的偏移量,length指定文件中声音的长度。
- final int streamID play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) Play a sound from a sound ID.
- final void pause(int streamID) Pause a playback stream. 暂停播放
- Pause the stream specified by the streamID. This is the value returned by the play() function. If the stream is playing, it will be paused. If the stream is not playing (e.g. is stopped or was previously paused), calling this function will have no effect. 暂停streamID指定的流。 这是play()函数返回的值。 如果流正在播放,它将被暂停。 如果流未播放(例如,停止或先前已暂停),则调用此功能将不起作用。
- final void resume(int streamID) Resume a playback stream. 继续播放
- Resume the stream specified by the streamID. This is the value returned by the play() function. If the stream is paused, this will resume playback. If the stream was not previously paused, calling this function will have no effect.
- final void stop(int streamID) Stop a playback stream. 终止播放
- Stop the stream specified by the streamID. This is the value returned by the play() function. If the stream is playing, it will be stopped. It also releases any native resources associated with this stream. If the stream is not playing, it will have no effect.
- final void setLoop(int streamID, int loop) Set loop mode. 设置指定播放流的循环次数
- A loop value of -1 means loop forever, a value of 0 means don't loop, other values indicate the number of repeats, e.g. a value of 1 plays the audio twice. If the stream does not exist, it will have no effect.
- final void setPriority(int streamID, int priority) Change stream priority. 设置指定播放流的优先级
- Change the priority of the stream specified by the streamID. This is the value returned by the play() function. Affects the order in which streams are re-used to play new sounds. If the stream does not exist, it will have no effect.
- final void setRate(int streamID, float rate) Change playback rate. 设置指定播放流的播放速率
- The playback rate allows the application to vary the playback rate (pitch) of the sound. A value of 1.0 means playback at the original frequency. A value of 2.0 means playback twice as fast, and a value of 0.5 means playback at half speed. If the stream does not exist, it will have no effect.
- final void setVolume(int streamID, float leftVolume, float rightVolume) Set stream volume. 设置指定播放流的音量大小
- Sets the volume on the stream specified by the streamID. This is the value returned by the play() function. The value must be in the range of 0.0 to 1.0. If the stream does not exist, it will have no effect.
- final void autoPause() Pause all active streams.
- Pause all streams that are currently playing. This function iterates through all the active streams and pauses any that are playing. It also sets a flag so that any streams that are playing can be resumed by calling autoResume(). 暂停正在播放的所有流。 此函数遍历所有活动流并暂停播放任何正在播放的流。 它还设置一个标志,以便可以通过调用autoResume()来恢复正在播放的任何流。
- final void autoResume() Resume all previously active streams.
- Automatically resumes all streams that were paused in previous calls to autoPause().
- final boolean unload(int soundID) Unload a sound from a sound ID. 卸载一个指定的音频资源
- Unloads the sound specified by the soundID. This is the value returned by the load() function. Returns true if the sound is successfully unloaded, false if the sound was already unloaded.
- final void release() Release the SoundPool resources. 释放所有资源
- Release all memory and native resources used by the SoundPool object. The SoundPool can no longer be used and the reference should be set to null.
- void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) Sets the callback hook for the OnLoadCompleteListener.
- void onLoadComplete(SoundPool soundPool, int sampleId, int status) Called when a sound has completed loading.
- SoundPool.Builder() Constructs a new Builder with the defaults format values.
- If not provided, the maximum number of streams is 1 , and the audio attributes have a usage value of USAGE_MEDIA (see setAudioAttributes(AudioAttributes) to change them).
- SoundPool.Builder setAudioAttributes(AudioAttributes attributes) Sets the AudioAttributes.
- Sets the AudioAttributes. For examples, game applications will use attributes built with usage information set to USAGE_GAME.
- AudioAttributes:A class to encapsulate a collection of attributes describing information about an audio stream. 封装描述有关音频流的信息的属性集合的类。
- SoundPool.Builder setMaxStreams(int maxStreams) Sets the maximum of number of simultaneous streams that can be played simultaneously.
- SoundPool build()
加载与播放方法
- 通过一个资源ID,int load(Context context, int resId, int priority)
- 通过指定的路径,int load(String path, int priority)
- 通过一个AssetFileDescriptor对象,int load(AssetFileDescriptor afd, int priority)
- 通过FileDescriptor,int load(FileDescriptor fd, long offset, long length, int priority)
final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
- soundID int: a soundID returned by the load() function
- leftVolume float: left volume value (range = 0.0 to 1.0) 左声道的音量
- rightVolume float: right volume value (range = 0.0 to 1.0)
- priority int: stream priority (0 = lowest priority) 流的优先级
- loop int: loop mode (0 = no loop, -1 = loop forever)
- rate float: playback rate (1.0 = normal playback, range 0.5 to 2.0) 播放的速率
- int non-zero streamID if successful, zero if failed
个人对SoundPool的认识与总结
如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:
- 1) 延时时间较长,且资源占用率高。
- 2) 不支持多个音频同时播放。
Android中除了MediaPlayer播放音频之外还提供了SoundPool来播放音效,SoundPool使用【音效池】的概念来管理多个短促的音效,例如它可以开始就加载20个音效,以后在程序中按音效的ID进行播放。SoundPool主要用于播放一些较短的声音片段,与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。SoundPool和其他声音播放类相比,其特点是可以自行设置声音的品质、音量、播放比率等参数。并且它可以同时管理多个音频流,每个流都有独自的ID,对某个音频流的管理都是通过ID进行的。实际使用SoundPool播放声音时需要注意:
- SoundPool最大只能申请1M的内存空间,这就意味着我们只能用一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
- SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
- 流的加载过程是一个将音频解压为原始16位PCM数据的过程,由一个后台线程来进行异步处理,所以初始化后不能立即播放,需要等待一点时间。
- SoundPool的效率在这些播放类中算是很好的了,但也不是绝对不存在延迟问题,尤其在那些性能不太好的手机中,SoundPool的延迟问题可能会很严重。
- 1、一个SoundPool可以管理多个音频资源,通过load()函数,成功则返回非0的soundID
- 2、一个SoundPool可以同时播放多个音频资源,通过play()函数,成功则返回非0的streamID
- 3、pause()、resume()和stop()等操作是针对streamID(播放流)的
- 4、当设置为无限循环时,需要手动调用stop()来终止播放
- 5、播放流的优先级(play()中的priority参数),只在同时播放数超过设定的最大数时起作用
- 6、程序中不用考虑播放流的生命周期,无效的soundID/streamID不会导致程序错误
演示示例
public class SoundPoolActivity extends ListActivity {
private SoundPool soundPool;
private List<Integer> soundIdList = new ArrayList<>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"0、raw:s10_bgm.ogg",
"1、raw:cf_bgm1.mp3",
"2、SD卡:s10_bgm.ogg",
"3、URL:s10_bgm.ogg,网络URL,不能播放",
"4、AssetFileDescriptor:assets目录",
"5、AssetFileDescriptor:raw目录",
"6、FileDescriptor:不能播放",
"7、FileDescriptor:不能播放",};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
soundPool = new SoundPool.Builder()
.setMaxStreams(5)
.setAudioAttributes(new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build())
.build();
soundPool.setOnLoadCompleteListener((soundPool1, sampleId, status) -> {
Log.i("bqt", "【onLoadComplete】" + sampleId + " " + status);//status : 0 = success
});
Context context = this.getApplicationContext();//不管使用哪个Context,退出当前Activity后都会且会在延迟几秒钟后停止播放
for (int i = 0; i < 8; i++) {
soundIdList.add(-1);
}
//通过一个资源ID:Context context, int resId, int priority
soundIdList.set(0, soundPool.load(context, R.raw.s1_ding, 0));
soundIdList.set(1, soundPool.load(context, R.raw.cf_bgm1, 0));
//通过指定的路径:String path, int priority
soundIdList.set(2, soundPool.load(Environment.getExternalStorageDirectory() + File.separator + "s10_bgm.ogg", 0));
soundIdList.set(3, soundPool.load("http://www.baiqiantao.xyz/s10_bgm.ogg", 0));//网络路径,不能播放
//通过FileDescriptor:FileDescriptor fd, long offset, long length, int priority
try {
AssetFileDescriptor afd = getAssets().openFd("s10_bgm.ogg");
Log.i("bqt", "【afd】" + afd.getStartOffset() + "," + afd.getLength() + "," + afd.getDeclaredLength());//43868,42987,42987
soundIdList.set(4, soundPool.load(afd, 0));
AssetFileDescriptor afd2 = getResources().openRawResourceFd(R.raw.s1_ding);
Log.i("bqt", "【afd2】" + afd2.getStartOffset() + "," + afd2.getLength() + "," + afd2.getDeclaredLength());//4300928,60647,60647
soundIdList.set(5, soundPool.load(afd2, 0));
} catch (IOException e) {
e.printStackTrace();
}
//通过FileDescriptor:FileDescriptor fd, long offset, long length, int priority
try {
FileDescriptor fd = getAssets().openFd("s1_fire.ogg").getFileDescriptor();
Log.i("bqt", "【是否有效 1】" + fd.valid());//true
soundIdList.set(6, soundPool.load(fd, 0, 1, 0));//Unable to load sample 【onLoadComplete】5 -2147483648
} catch (IOException e) {
e.printStackTrace();
}
FileDescriptor fd2 = getResources().openRawResourceFd(R.raw.s1_fire).getFileDescriptor();
Log.i("bqt", "【是否有效 2】" + fd2.valid());//true
soundIdList.set(7, soundPool.load(fd2, 0, 1, 0));//Unable to load sample 【onLoadComplete】5 -2147483648
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
int soundID = soundIdList.get(position);
Toast.makeText(this, "" + soundID, Toast.LENGTH_SHORT).show();
soundPool.play(soundID, 1, 1, 1, 0, 1);
}
}
SoundPool 音频播放 详解 示例的更多相关文章
- 【机器学习】【条件随机场CRF-2】CRF的预测算法之维特比算法(viterbi alg) 详解 + 示例讲解 + Python实现
1.CRF的预测算法条件随机场的预测算法是给定条件随机场P(Y|X)和输入序列(观测序列)x,求条件概率最大的输出序列(标记序列)y*,即对观测序列进行标注.条件随机场的预测算法是著名的维特比算法(V ...
- 【Handler】Looper 原理 详解 示例 总结
核心知识点 1.相关名词 UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue Handler:作用就是发送与处理信息, ...
- SoundPool 音频播放 API 详解【示例】
demo地址:https://github.com/baiqiantao/PermissionTest.git 一个大坑:SoundPool最多只能播放时长10s左右.大小70kb左右(这些值是我多次 ...
- AAC音频格式详解
关于AAC音频格式基本情况,可参考维基百科http://en.wikipedia.org/wiki/Advanced_Audio_Coding AAC音频格式分析 AAC音频格式有ADIF和ADTS: ...
- MediaPlayer 状态机 API 详解 示例
简介 public class android.media.MediaPlayer extends Object implements VolumeAutomation 可能需要的权限: One ma ...
- Android音频焦点详解(上)
转载请注明出处:http://www.cnblogs.com/landptf/p/6384112.html 2017年开年第一篇博客,很早就想总结一下Android音频的相关知识.今天我们先来看一下音 ...
- Python爬虫实战案例:取喜马拉雅音频数据详解
前言 喜马拉雅是专业的音频分享平台,汇集了有声小说,有声读物,有声书,FM电台,儿童睡前故事,相声小品,鬼故事等数亿条音频,我最喜欢听民间故事和德云社相声集,你呢? 今天带大家爬取喜马拉雅音频数据,一 ...
- Python爬虫:爬取喜马拉雅音频数据详解
前言 喜马拉雅是专业的音频分享平台,汇集了有声小说,有声读物,有声书,FM电台,儿童睡前故事,相声小品,鬼故事等数亿条音频,我最喜欢听民间故事和德云社相声集,你呢? 今天带大家爬取喜马拉雅音频数据,一 ...
- monkey基本命令参数详解示例
Monkey基本命令参数 参数名 基本功能 举例 -p 参数-p用于约束限制,用此参数指定一个或多个包(Package,即App).指定 包之后,Monkey将只允许系统启动指定的APP.如果不指定包 ...
随机推荐
- 解决Mac上Android开发时adb连接不到手机问题
今天在Mac OS上进行Android开发的时候,打开eclipse连接不到手机MX4问题 1. 插入手机打开 Terminal,输入 system_profiler SPUSBDataType 2 ...
- Js点餐加减数量
<button class="add-on" onclick="chgNum(1,'del')" ><i class="icon-m ...
- 死亡的协议--- Pieter Hintjens (ZeroMQ作者)
过去几年中用zeromq写过几个系统系统.对ZeroMQ强大和灵活印象非常深刻.在阅读zeromq guide文档时候.发现作者整理各种通信模式非常经典和实用,可以作为分布式通信的教科书来看.第一次见 ...
- python函数参数的pack与unpack
python函数参数的pack与unpack 上周在使用django做开发的时候用到了mixin(关于mixin我还要写一个博客专门讨论一下,现在请参见这里),其中又涉及到了一个关于函数参数打包(pa ...
- HDU 2955(01背包问题)
M - 01背包 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descript ...
- android host
74.125.20.31 market.android.com 74.125.20.31 developer.android.com 74.125.20.31 android.googlesource ...
- pojShredding Company
http://poj.org/problem?id=1416 #include<cstdio> #include<cstring> #define MAXN 100 using ...
- h.264 Mode Decision
Mode Decision(模式选择)决定一个宏块以何种类型进行分割.宏块的分割类型有以下几种: //P_Skip and B_Skip means that nothing need to be e ...
- ISO7816协议的块传输协议
1.块传输协议中的前三个字节是强制必须有的 NAD节点地址: 当终端支持多个卡槽,终端和这些卡槽以总线的方式通讯时,该字节有用,其他情况下,默认为0 bit1-3:定义了源地址 bit5-7:定义了目 ...
- 【HDOJ】1329 Hanoi Tower Troubles Again!
水题,搞清楚hanoi的定义就好做了. /* 1329 */ #include <cstdio> #include <cstring> #include <cstdlib ...