Android多媒体功能开发(7)——使用SoundPool类播放音频

使用SoundPool的基本流程是:创建一个SoundPool对象、载入要播放的音频、播放某个音频、停止播放某个音频。

一个SoundPool对象可以载入多个音频,每个音频载入后对应一个SoundID。播放某个音频时用SoundID指定要播放的音频,并返回播放该音频的ChannelID。要停止播放某个音频,需要通过其ChannelID,注意不是SoundID!使用SoundPool播放音频的示意图如下:

下面用SoundPool编写一个播放音效的应用,可以单次、循环播放音效,界面如下:


有的设备上循环播放参数无效,可以采用Thread来实现。应用主要代码如下:

SoundPool类的主要方法包括:

1)构造函数:SoundPool(int maxStreams, int streamType, int srcQuality)。第一个参数maxStreams指定同时支持多少个声音,即Channel数量;第二个参数streamType指定声音类型,一般游戏中用AudioManager.STREAM_MUSIC;第三个参数srcQuality指定声音品质,目前没用,给0即可。

2)载入音频的load方法一共有4个,这里只列出最常用的两个:

int load(Context context, int resld, int priority):从 resld 所对应的资源加载音频

int load(String path, int priority):从path对应的文件去加载音频

priority参数,目前没用,Android建议设为1,保持和未来的兼容性;加载音频之后都会返回该声音的ID,以后可以通过ID来播放指定音频。

3)播放音频:int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)。第一个参数soundID指定播放哪个声音;第二三个参数leftVolume、rightVolume指定左、右的音量;第四个参数priority指定播放声音的优先级,数值越大,优先级越高;第五个参数loop指定是否循环,0为不循环,-1为循环;经测试目前无效;第六个参数rate指定播放的比率,数值可从0.5到2, 1为正常比率;返回播放该音频的ChannelID,也叫StreamID,用此ID来对播放进行控制,如停止、暂停等。

4)卸载音频:boolean unload(int soundID)。卸载soundID指定的音频,成功返回true。

5)释放所有资源:void release()。

例子的完整代码如下:

public class MainActivity extends AppCompatActivity {
    int[] soundResId = {R.raw.fly, R.raw.fire, R.raw.explode};	// 音频资源
    SoundPool soundPool;
    int[] soundId;		// soundPool为每个装入的音频资源生成的SoundID
    int flyStreamId;	// soundPool播放fly音频时使用的Channel,通过Channel控制音效播放
    PlayThread playThread;	// 因为SoundPool的循环播放功能无效,所以用Thread来实现循环播放

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        setContentView(ll);

        soundId = new int[soundResId.length];
        soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 100);	// 创建SoundPool对象
        for(int i=0; i<soundResId.length; i++)
            soundId[i] = soundPool.load(this, soundResId[i], 1);	// 依次载入音频资源,生成的SoundID存入soundId数组,播放时使用

        Button btnFire = new Button(this);
        btnFire.setText("Fire");
        ll.addView(btnFire);
        btnFire.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                soundPool.play(soundId[1], 1, 1, 1, 0, 1);	// 播放fire音频,其SoundID存放在soundId[1]
            }
        });
        Button btnExplode = new Button(this);
        btnExplode.setText("Explode");
        ll.addView(btnExplode);
        btnExplode.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                soundPool.play(soundId[2], 1, 1, 1, 0, 1);	// 播放explode音频,其SoundID存放在soundId[2]
            }
        });

        Button btnStartFly = new Button(this);
        btnStartFly.setText("Start Fly");
        ll.addView(btnStartFly);
        btnStartFly.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                flyStreamId = soundPool.play(soundId[0], 1, 1, 1, -1, 1f);	// 控制循环播放的参数无效
                //playThread = new PlayThread(soundId[0], 3000);	// 启用一个线程,每隔3000毫秒播放一次fly音频,其长度大约为3000毫秒
                //playThread.start();
            }
        });
        Button btnStopFly = new Button(this);
        btnStopFly.setText("Stop Fly");
        ll.addView(btnStopFly);
        btnStopFly.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                soundPool.stop(flyStreamId);
                //playThread.stopPlay();
            }
        });
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();
        soundPool.release();
    }

    class PlayThread extends Thread {
        boolean flag;
        int soundId;
        int streamId;
        int duration;
        public PlayThread(int sId, int d){
            soundId = sId;
            duration = d;
        }
        public void run(){
            flag = true;
            while(flag){
                streamId = soundPool.play(soundId, 1, 1, 1, 0, 1f);	// 播放音频soundId
                try {
                    sleep(duration);				// 等待该音频的播放时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        public void stopPlay(){
            soundPool.stop(streamId);	// 立即停止SoundPool的streamId频道的播放
            flag = false;				// 停止播放循环
        }
    }
}

猜你喜欢

转载自blog.csdn.net/nanoage/article/details/127363509