SoundPoolUtil工具类播放声音

  • 内容
  • 相关

一、作用

    省内存播放声音

二、使用

    1、导包 implementation 'org.xutils:xutils:3.3.36'

    2、在需要的地方插入

//加载ogg格式的音频 asset/Sounds下music.ogg
int soundId = PlaySound.loadFile("file:///android_asset/Sounds/music.ogg");
//播放
PlaySound.play(soundId);

三、注意和详解

    1、加载后不能立即播放,因为SoundPool加载需要一点准备(时间很短)

    2、建议使用线程和OGG格式的音频,不建议WAV

    3、加载的音频尽量<6s,根据官方文档,因设备不同播放的时长也不同,音频过长只能播放一部分,它只有1MB的内存使用

    4、每个音频文件大小要小于100k;可以修改音频码率来压缩音频大小,把 128kbps改成32kbps

    5、使用soundId 只能暂停一次声音,你要调用停止在流ID ,而不是 soundId 。一个soundId指特定声音的资源,但在流ID是指声音播放的单个实例。所以,如果你玩同样的声音3次,你有一个soundId和三个streamIds。

mStreamId = SoundPoolUtil.play(soundId);
//正确
SoundPoolUtil.stop(mStreamId);
//错误
SoundPoolUtil.stop(soundId);

    6、创建一个SoundPool详解

public SoundPool(int maxStream, int streamType, int srcQuality) 
maxStream —— 同时播放的流的最大数量
streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值

    7、加载音频资源详解

可以通过四种途径来记载一个音频资源:
    1.通过一个AssetFileDescriptor对象
    int load(AssetFileDescriptor afd, int priority) 

    2.通过一个资源ID
    int load(Context context, int resId, int priority) 

    3.通过指定的路径加载
    int load(String path, int priority)

    4.通过FileDescriptor加载
    int load(FileDescriptor fd, long offset, long length, int priority) 

    8、播放控制详解

有以下几个函数可用于控制播放:
    1.播放指定音频的音效,并返回一个streamID
    final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
      priority —— 流的优先级,值越大优先级高,影响当同时播放数量超出了最大支持数时SoundPool对该流的处理;
      loop —— 循环播放的次数,0为值播放一次,-1为无限循环,其他值为播放loop+1次(例如,3为一共播放4次).
      rate —— 播放的速率,范围0.5-2.0(0.5为一半速率,1.0为正常速率,2.0为两倍速率)

    2.暂停指定播放流的音效(streamID 应通过play()返回
    final void pause(int streamID)

    3.继续播放指定播放流的音效(streamID 应通过play()返回
    final void resume(int streamID)

    4.终止指定播放流的音效(streamID 应通过play()返回
    final void stop(int streamID)

这里需要注意的是: 
    1.play()函数传递的是一个load()返回的soundID——指向一个被记载的音频资源 ,如果播放成功则返回一个非0的streamID——指向一个成功播放的流 ;同一个soundID 可以通过多次调用play()而获得多个不同的streamID (只要不超出同时播放的最大数量);

    2.pause()、resume()和stop()是针对播放流操作的,传递的是play()返回的streamID ;

    3.play()中的priority参数,只在同时播放的流的数量超过了预先设定的最大数量是起作用,管理器将自动终止优先级低的播放流。如果存在多个同样优先级的流,再进一步根据其创建事件来处理,新创建的流的年龄是最小的,将被终止;

    4.无论如何,程序退出时,手动终止播放并释放资源是必要的。

    9、更多设置详解

其实就是paly()中的一些参数的独立设置:
    1.设置指定播放流的循环.
    final void setLoop(int streamID, int loop) 

    2.设置指定播放流的音量.
    final void setVolume(int streamID, float leftVolume, float rightVolume) 

    3.设置指定播放流的优先级,上面已说明priority的作用.
    final void setPriority(int streamID, int priority) 

    4.设置指定播放流的速率,0.5-2.0.
    final void setRate(int streamID, float rate) 

    10、释放资源详解

1.卸载一个指定的音频资源.
final boolean unload(int soundID)
 
2.释放SoundPool中的所有音频资源.
final void release() 

四、代码

import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioAttributes;
import android.media.SoundPool;

import org.xutils.x;

import java.io.IOException;

public class PlaySoundUtil {
    static final String assetPrefix = "file:///android_asset";
    static SoundPool _soundPool = null;
    static int _priority = 0;

    public static int loadFile(String path) {
        SoundPool soundPool = getSoundPool();

        int soundId = 0;
        if (path.startsWith(assetPrefix)) {
            String assetpath = path.substring(assetPrefix.length()+1);
            AssetManager assets = x.app().getAssets();
            try {
                AssetFileDescriptor afd = assets.openFd(assetpath);
                soundId = soundPool.load(afd, 1);
            } catch (IOException e) {
                e.printStackTrace();
                soundId = 0;
            }
        } else {
            soundId = soundPool.load(path, 1);
        }
        return soundId;
    }

    public static boolean play(int id) {
        SoundPool soundPool = getSoundPool();
        int ret = soundPool.play(id, 1.0f, 1.0f, _priority, 0, 1.0f);

        _priority++;
        if (_priority < 0)
            _priority = 0;
        return (ret != 0);
    }

    public static void stop(int id) {
        SoundPool soundPool = getSoundPool();
        soundPool.pause(id);
    }

    private static SoundPool getSoundPool() {
        if (_soundPool == null) {
            _soundPool = new SoundPool.Builder()
                    .setAudioAttributes(new AudioAttributes.Builder()
                            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                            .build())
                    .setMaxStreams(1)
                    .build();
        }
        return _soundPool;
    }

}

 

本文标签:

版权声明:若无特殊注明,本文皆为《admin_H》原创,转载请保留文章出处。

本文链接:SoundPoolUtil工具类播放声音 - https://blog.bnist.com/post/15

发表评论

电子邮件地址不会被公开。 必填项已用*标注

未显示?请点击刷新

允许邮件通知
Sitemap