简体   繁体   English

如何使用 Android Animation(可能使用“Android MediaPlayer / SoundPool”)播放“滴答声”?

[英]How to Play 'Tick Tick' Sound with Android Animation (possibly with `Android MediaPlayer / SoundPool`)?

I have a custom view ( PieView ) that is has a rotating animation.我有一个自定义视图 ( PieView ),它有一个旋转的 animation。 Now I would like to play tick tick tick tick... sound synchronously with the rotation speed (that is, when the rotation speed is fast, the tick tick should be fast, when rotation is slow, the tick tick should be slow).现在我想播放tick tick tick tick...与旋转速度同步的声音(即旋转速度快时滴答声应该快,旋转慢时滴答声应该慢)。 To do this, first I created an mp3 file named magicbox_tick.mp3 that has only ONE (1) tick.为此,首先我创建了一个名为magicbox_tick.mp3的 mp3 文件,它只有一 (1) 个刻度。 Next I tried to play the sound with Animation.setUpdateListener() .接下来我尝试使用Animation.setUpdateListener()播放声音。

First I tried to play music with MediaPlayer but after some 10 or 15 ticks, it stoped.首先,我尝试使用MediaPlayer播放音乐,但在 10 或 15 个滴答声之后,它停止了。 So now I am trying SoundPool to play the music.所以现在我正在尝试SoundPool播放音乐。

The relevant code segment looks like this:相关代码段如下所示:

public PieView extends View {
  // ... constructors, other methods etc
  private SoundPool soundPool;
  private int soundId;

  void init(){  // called inside those constructors
        SoundPool soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
        soundId = soundPool.load(getContext(), R.raw.magicbox_tick, 1);
  }

  public void rotateTo(){
    animate()..setInterpolator(new DecelerateInterpolator())
                .setDuration(mDuration)
                .setListener(someListener)
                .rotation(targetAngle)
                .setUpdateListener(animation -> {
                    myPlaySound();  // <----------------------- This is the sound playing code
                })
                .start();
  }

  void myPlaySound(){
          soundPool.play(soundId, 1, 1, 0, 0, 1); // this doesnot play the `tick` sound
          // previously I used MediaPlayer like this:
         /*
            MediaPlayer mp = new MediaPlayer.create(getContext(), R.raw.magicbox_tick);
            mp.play(); 
               // these 2 line, after some 10 ticks, stopped working. 
          */
  }

}

I have never done anything like this, and I don't know how to fix this.我从来没有做过这样的事情,我不知道如何解决这个问题。 Can anyone help me?谁能帮我? Please note that I am open to all answers as long as it works.请注意,只要可行,我对所有答案持开放态度。 You don't have to use SoundPool .您不必使用SoundPool So suppose if you can make it work with android MediaPlayer , I am ok with that.因此,假设您可以使其与 android MediaPlayer一起使用,我可以接受。

Special thanks to Mr Mike M for his valuable comment.特别感谢Mike M先生的宝贵意见。 I was able to fix it using MediaPlayer .我能够使用MediaPlayer修复它。 MediaPlayer.release() method should be called.应该调用MediaPlayer.release()方法。 And to make the sound synced with the angular motion, I kept an if block that checks if the rotation dTheta is greater than tolerance angle.为了使声音与 angular 运动同步,我保留了一个 if 块来检查旋转dTheta是否大于tolerance角度。 So, if anyone needs it, the complete code looks like this:因此,如果有人需要,完整的代码如下所示:

public PieView extends View{
     private float omega0; // holds the previous rotation
    /**
     * @brief: plays a music using mediaPlayer
     * @input:
     * @output: void, plays a music
     * */
    private void myPlayTick() {
        float omega1 = Math.abs(getRotation());
        float dOmeda = 0;
        if(omega1>omega0){
            dOmeda = omega1 - omega0;
        }else{
            dOmeda = omega0-omega1;
        }
        if(dOmeda > threshold){
            omega0 = omega1; // update previous rotation
            final MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.magicbox_tick);
            mp.start();
            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    releaseMediaPlayer(mp);
                }
            });
        }
    }

    /**
     * @brief: releases mediaPlayer resource so that other mediaPlayers can use sound hardware resources
     * @input: MediaPlayer object
     * @output: void
     * */
    private void releaseMediaPlayer(MediaPlayer mediaPlayer) {
        try {
            if (mediaPlayer != null) {
                if (mediaPlayer.isPlaying())
                    mediaPlayer.stop();
                mediaPlayer.release();
                mediaPlayer = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


 public void rotateTo(){
    animate()..setInterpolator(new DecelerateInterpolator())
                .setDuration(mDuration)
                .setListener(someListener)
                .rotation(targetAngle)
                .setUpdateListener(animation -> {
                   myPlayTick();                  
                })
                .start();
  }
     // ... rest of the code, such as constructors, etc
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM