【问题标题】:How do I know if a sound is finished playing in android?我如何知道声音是否在 android 中播放完毕?
【发布时间】:2010-11-30 23:37:54
【问题描述】:

我如何知道声音是否已播放完毕?

我想播放 2 个声音,但我想播放一个声音,然后等到第一个声音完成后再开始第二个声音。

另外,如果我想在声音结束后做其他事情,比如在视图翻转器中显示他的下一个视图,我可以这样做吗?

现在我正在使用 SoundPool 播放我的声音。

【问题讨论】:

    标签: android soundpool


    【解决方案1】:

    使用 MediaPlayer 类和 OnCompletionListener

    【讨论】:

    • SoundPool 没有办法做到这一点吗?我需要 SoundPool 的低延迟。
    • 同意 Dahlgren MediaPlayer 是要走的路。您可以使用 prepare() 预加载声音,然后在准备好获得低延迟播放时使用 start()。
    • 我可以使用 MediaPlayer 加载 20 多个声音,还是必须有 20 多个 MediaPlayer 实例。
    【解决方案2】:

    只是一个想法...获取 ogg/wav 声音播放时间长度并使用您自己的 SoundObject 类和计时器成员。 在一些更新功能中更新它。 如果 timer > maxtime + threshold,则将其标记为已完成。

    【讨论】:

      【解决方案3】:

      我解决这个问题的方法是创建一个包含图像、声音和延迟的动画序列。然后我可以将它们排队,这样我就可以显示图像,并伴随声音,然后切换到另一个图像。我使用 SoundPlayer 和自定义视图(不是视图翻转器,虽然你可能可以)来做到这一点

      诀窍是您不能简单地暂停线程以延迟,您需要使用处理程序向自己发送消息以在将来更新 UI。

      这里是处理程序

      handler = new Handler() {
      
                  /* (non-Javadoc)
                   * @see android.os.Handler#handleMessage(android.os.Message)
                   */
                  @Override
                  public void handleMessage(Message msg) {
                      if (msg.what == NEXT_ITEM_MSG) {
                          showNext();
                      }
                      else if (msg.what == SEQUENCE_COMPLETE_MSG) {
                          // notify the listener
                          if (animationCompleteListener != null) {
                              animationCompleteListener.onAnimationComplete();
                          }
                      }
                  }
              };
      

      showNext() 方法只是抓取序列中的下一项,更新图像视图,播放声音,然后为处理程序安排一条消息,以便在序列之后调用 showNext。

      private void showNext() {
              if (mRunning) {
                  // Get the first item
                  AnimatedSequenceItem item = currentSequence.getNextSequenceItem();
                  if (item == null) {
                      Message msg = handler.obtainMessage(SEQUENCE_COMPLETE_MSG);
                      handler.sendMessage(msg);
                      return;
                  }
                  // Show the first image
                  showImage(item.getImageResId());
                  // Play the sound
                  int iSoundResId = item.getSoundResId();
                  if (iSoundResId != -1) {
                      playSound(iSoundResId);
                  }
      
                  // schedule a message to advance to next item after duration
                  Message msg = handler.obtainMessage(NEXT_ITEM_MSG);
                  handler.sendMessageDelayed(msg, item.getDuration());
              }
          }
      

      当然,所有这些都需要您确定延迟并对其进行硬编码,但根据我的经验,无论如何您都需要为游戏这样做。在很多情况下,我希望延迟比声音长。这是实际排队项目的代码。

      battleSequence.addSequenceItem(R.drawable.brigands, 
                         R.raw.beep, 
                         2000);
      battleSequence.addSequenceItem(R.drawable.black,
                                     winning ? R.raw.enemy_hit : R.raw.player_hit, 
                                     1500);
      

      通过这种方法,我可以使用各种逻辑来添加动画项、更改持续时间、循环动画等...只需进行一些微调即可正确处理延迟。

      希望这会有所帮助。

      【讨论】:

        【解决方案4】:

        抱歉,回复太晚了。但是我使用了来自 mediaplayer 的 isPlaying() API 来等待第一首歌曲完成。

        while(mediaPlyaer.isPlaying()){
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-27
          • 2017-06-23
          • 2014-07-12
          • 1970-01-01
          相关资源
          最近更新 更多