在安卓系统中播放短音频的正确方法是什么?

45

我正在创建一个应用程序,屏幕上会有多张图片,这些图片将是按钮,点击它们将播放短音频。 我进行了研究,只能找到当前我正在使用的播放声音的方法,但它似乎不太响应。我希望声音可以快速播放,并对许多快速的点击做出响应。 我不确定在Android中是否可能实现此目标。

我用来播放声音的代码是:

    Button sound1;
MediaPlayer  firstSound;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    firstSound = MediaPlayer.create(SoundActivity.this, R.raw.click);


    sound1 = (Button) findViewById(R.id.Sound1);


    beaver.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {

            firstSound.start();

            }

    });



    }

我的延迟问题可能也与我使用媒体播放器对象的方式有关?我觉得在我的手机上应该更顺畅,欢迎提供有关在Android中播放音频的建议。

谢谢。

自从发现Sound Pool以后,我已经编辑了代码并使用它,它运行得非常完美,新代码如下:

SoundPool soundPool;
HashMap<Integer, Integer> soundPoolMap;
int soundID = 1;


Button sound1;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
    soundPoolMap = new HashMap<Integer, Integer>();
    soundPoolMap.put(soundID, soundPool.load(this, R.raw.click, 1));

    sound1 = (Button) findViewById(R.id.bBeaver);


    sound1.setOnClickListener(new View.OnClickListener() {

                public void onClick(View v) {

                    AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
              float curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
              float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
              float leftVolume = curVolume/maxVolume;
              float rightVolume = curVolume/maxVolume;
              int priority = 1;
              int no_loop = 0;
              float normal_playback_rate = 1f;
              soundPool.play(soundID, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);

            }

    });


    }

谢谢


3
您似乎没有使用您的 soundPoolMap? - Moberg
2
喜欢你的实现方式,一次就很好地工作了。 - desgraci
1
非常感谢。它运行得很好...! - Parthiban M
1
在花费了几个小时的MediaPlayer问题之后,我在五分钟内让SoundPool工作了,谢谢! - Martina
SoundPool 是正确的选择,虽然它比 MediaPlayer 稍微复杂一些。但这可以让您获得高效和快速的播放。然而,您应该使用一个库,或者自己创建一个,因为您必须利用一个单独的工作线程:https://github.com/delight-im/Android-Audio - caw
2
@Moberg 是正确的,应该使用 "soundPool.play(soundPoolMap.get(soundID)..." 而不是 "soundPool.play(soundID..." - Kresimir
3个回答

31

你可以使用SoundPool。它非常适合你想要做的事情。

你只需要一种方法来存储每个图像(或按钮)对应的音效ID。

可能需要扩展Button类以存储关联的音效ID,并使用一个公共的SoundPool在按钮被触摸时播放与ID相关联的音效。

你可以在这里阅读更多关于SoundPool的内容


1
谢谢您的建议和链接。我进一步研究了这个问题,并找到了一个教程,这帮助我实现了我想要的功能,它确实比媒体播放器好多了!非常感谢! - deucalion0
请问您能否提供教程的链接? - Moberg
@Moberg 这里有一个例子:https://dev59.com/4mQn5IYBdhLWcg3wIkMF - JoséMi

5

@Rikonator的建议是正确的,使用Soundpool更加适合你需要的功能。

如果你仍然决定使用MediaPlayer,请不要忘记使用prepareAsync()方法以防止其卡住UI线程。你可以在这里了解更多关于播放媒体的内容


1
最好阻塞在UI线程上,因为声音正在用于按钮。挂起UI可能是不好的,但声音延迟触发更奇怪。 - Tonithy

3
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.sound);

try {
    if (mp.isPlaying()) {
        mp.stop();
        mp.release();

        mp = MediaPlayer.create(getApplicationContext(), R.raw.sound);
    }

    mp.start();
} catch (Exception e) {
    e.printStackTrace();
}

1
谢谢分享。这对我有用 :) - Tomas M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接