Как воспроизвести звук 'Tick Tick' с анимацией Android (возможно, с `Android MediaPlayer / SoundPool`)? - PullRequest
0 голосов
/ 06 апреля 2020

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

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

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

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, я в порядке с этим.

1 Ответ

0 голосов
/ 06 апреля 2020

Особая благодарность мистеру Майку М за его ценный комментарий. Я смог это исправить используя MediaPlayer. MediaPlayer.release() метод должен быть вызван. И чтобы синхронизировать звук с движением angular, я сохранил блок 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
}
...