【问题标题】:MediaPlayer how to stop multiple sounds from playbackMediaPlayer如何停止播放多个声音
【发布时间】:2012-06-23 03:32:17
【问题描述】:

我有一个播放声音的按钮。 当我多次按下按钮时,它会多次播放声音。 没关系,我想要这个。 但是当我单击停止按钮时,它必须停止当前播放的所有声音。 我用过:

   while (mediaPlayer.isPlaying()){mediaPlayer.stop();}

但它不工作,声音继续播放。有人能帮我吗? 这是我的完整代码:

public class HelloSoundboard extends Activity {
MediaPlayer mediaPlayer;

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

    Button item1 = (Button)findViewById(R.id.item1);
    item1.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
           mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
           mediaPlayer.start();
       }
    });

    Button stop = (Button)findViewById(R.id.stop);
    stop.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
          while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
        //  mediaPlayer.stop();
       }
     });
 }
}

【问题讨论】:

    标签: android media-player audio


    【解决方案1】:

    SoundPool 是一个更好的选择。我强烈警告不要实例化多个MediaPlayer 实例,因为大多数系统没有资源来生成许多并行活动实例。您会发现在许多设备上,按 5 次以上的按钮会导致基于内存的崩溃。

    就停止所有活动流而言,没有内置功能,但它很容易以类似于您现有代码的方式完成。附带说明一下,有一个autoPause() 方法,它会停止所有流,但它并没有真正结束它们的播放(正如方法名称所暗示的那样)。下面是一个管理音频流的简单示例:

    //SoundPool initialization somewhere
    SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
    //Load your sound effect into the pool
    int soundId = pool.load(...); //There are several versions of this, pick which fits your sound
    
    List<Integer> streams = new ArrayList<Integer>();
    Button item1 = (Button)findViewById(R.id.item1);
    item1.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
           int streamId = pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
           streams.add(streamId);
       }
    });
    
    Button stop = (Button)findViewById(R.id.stop);
    stop.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
          for (Integer stream : streams) {
              pool.stop(stream);
          }
          streams.clear();
       }
    });
    

    MediaPlayer 实例相比,管理streamID 值列表的内存效率要高得多,您的用户会感谢您的。另外请注意,即使 streamID 不再有效,调用SoundPool.stop() 也是安全的,因此您无需检查现有播放。

    HTH

    【讨论】:

    • 需要注意的是,SoundPool 是为小音效制作的,缓冲区不能变大。我的一个声音因为太长而被切断了。所以我仍然需要使用 MediaPlayer
    【解决方案2】:

    对此我不确定,但我认为使用 SoundPool 会更好。

    “SoundPool 专为短片而设计,这些短片可以保存在内存中解压缩以便快速访问,这最适合应用或游戏中的音效”。

    “MediaPlayer 专为较长的声音文件或流而设计,最适合音乐文件或较大的文件”。

    【讨论】:

    • 谢谢,我对 SoundPool 进行了一些试验,但根本无法停止声音的播放。在 WWW 上也找不到任何相关信息,您知道如何停止 soundpool 中的所有声音吗?
    • +1 因为这是一个更好的解决方案,所以我只需要添加自己的答案来充分解释原因。
    【解决方案3】:

    你可以使用MediaPlayers的列表:

    List<MediaPlayer> mps = new ArrayList<MediaPlayer>();
    Button item1 = (Button)findViewById(R.id.item1);
    item1.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
           MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
           mp.start();
           mps.add(mp);
       }
    });
    
    Button stop = (Button)findViewById(R.id.stop);
    stop.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
          for (int i = mps.size() - 1; i >= 0; --i) { //changed ++i to --i
              if (mps.get(i).isPlaying()) {
                  mps.get(i).stop();
              }
              mps.remove(i);
          }
       }
     });
    

    【讨论】:

    • 您的代码出现以下错误: List 类型中的方法 add(MediaPlayer) 不适用于参数 (void)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 2015-03-24
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多