Как воспроизвести звук «Tick Tick» с анимацией Android (возможно, с помощью «Android MediaPlayer / SoundPool»)?

У меня есть пользовательский вид (PieView) с вращающейся анимацией. Теперь я хотел бы воспроизводить звук tick tick tick tick... синхронно со скоростью вращения (то есть, когда скорость вращения высокая, тик-тик должен быть быстрым, когда вращение медленно, тик-тик должен быть медленным). Для этого я сначала создал mp3-файл с именем magicbox_tick.mp3, у которого есть только ОДНА (1) галочка. Затем я попытался воспроизвести звук с помощью Animation.setUpdateListener().

Сначала я попытался воспроизвести музыку с помощью MediaPlayer, но через 10 или 15 тактов он остановился. Итак, теперь я пытаюсь SoundPool играть музыку.

Соответствующий сегмент кода выглядит следующим образом:

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. 
          */
  }

}

Я никогда не делал ничего подобного, и я не знаю, как это исправить. Может кто-нибудь помочь мне? Обратите внимание, что я открыт для всех ответов, пока это работает. Вам не нужно использовать SoundPool. Итак, предположим, что если вы можете заставить его работать с Android MediaPlayer, я согласен с этим.


person Qazi Fahim Farhan    schedule 06.04.2020    source источник


Ответы (1)


Особая благодарность г-ну Mike M за его ценный комментарий. Я смог исправить это с помощью MediaPlayer. MediaPlayer.release() должен быть вызван метод. И чтобы звук синхронизировался с угловым движением, я сохранил блок if, который проверяет, больше ли угол поворота dTheta, чем угол tolerance. Итак, если кому нужно, полный код выглядит так:

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
}
person Qazi Fahim Farhan    schedule 06.04.2020