如何使用 Android 动画播放 'Tick Tick' 声音(可能使用 `Android MediaPlayer / SoundPool`)?
How to Play 'Tick Tick' Sound with Android Animation (possibly with `Android MediaPlayer / SoundPool`)?
我有一个带有旋转动画的自定义视图 (PieView
)。现在我想播放 tick tick tick tick...
声音与旋转速度同步(即旋转速度快时,tick tick 应该快,旋转慢时,tick tick 应该慢)。
为此,我首先创建了一个名为 magicbox_tick.mp3
的 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
一起工作,我同意。
特别感谢Mike M先生的宝贵意见。我能够使用 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
}
我有一个带有旋转动画的自定义视图 (PieView
)。现在我想播放 tick tick tick tick...
声音与旋转速度同步(即旋转速度快时,tick tick 应该快,旋转慢时,tick tick 应该慢)。
为此,我首先创建了一个名为 magicbox_tick.mp3
的 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
一起工作,我同意。
特别感谢Mike M先生的宝贵意见。我能够使用 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
}