How to play animation(videoView) and mediaPlayer at the same time?

21 Views Asked by At

I am working on a foreground service which when created, creates MediaPlayer and an Activity whose View has a custom button that should repeat an animation every 2 seconds. The animation is an mp4 file without sound and uses VideoView to be played.

The problem is that they both play at the same time and the audio of mediaPlayer after some time stops and gets played again from start (no exception or error log is thrown). At first I thought it's because of the repetition, but from what I was able to find, the thread stopping should be a correct. And so from my point of view the problem seems to be either the Thread sleeping or the video attemping to take the audio priority. The repeatition of song works as intended if the video is not playing.

And so how to play animation and mediaPlayer at the same time correctly?

MediaPlayer: (stopped and released in onDestroy())

private void playMusic(@RawRes int raw) {
    am = ((AudioManager) getSystemService(Context.AUDIO_SERVICE));

    final AudioAttributes attributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_ALARM)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build();

    focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
            .setAudioAttributes(attributes)
            .setAcceptsDelayedFocusGain(true)
            .setOnAudioFocusChangeListener(focusChange -> {
                if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                    if (mediaPlayer != null && !mediaPlayer.isPlaying()) {
                        Log.w(MainActivity.logName + activityName, "Alarm focus gained, starting it!");
                        mediaPlayer.start();
                    }
                } else {
                    Log.i(MainActivity.logName + activityName, "Alarm focus lost, snoozing!");
                    //todo snooze
                }
            })
            .build();

        mediaPlayer = MediaPlayer.create(this, defaultRingtone,null, attributes, am.generateAudioSessionId());

    mediaPlayer.setOnCompletionListener(mp -> {
        if (!mediaPlayer.isPlaying())
            mediaPlayer.start();
    });

    final int audioFocusRequest = am.requestAudioFocus(focusRequest);

    if (audioFocusRequest == AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
        mediaPlayer.start();
    else
        Log.e(MainActivity.logName + activityName, "Error, unable to gain audio focus to start alarm!");
}

Animation/VideoView

private void setIdleAnimation() {
    waveAnim.setAudioFocusRequest(AudioManager.AUDIOFOCUS_NONE);
    waveAnim.setMediaController(null);
    waveAnim.setVideoURI(ResUtil.getRaw(context, R.raw.wave_effect));
    idleAnimation = new IdleAnimation(waveAnim, button, buttonWidth);
  
  //        new Thread(() -> {
  //            while (true)
  //                try {
  //                    Thread.sleep(2000);
  //                    if (!isButtonPressed)
  //                        new Handler(Looper.getMainLooper())
  //                                .post(() -> idleAnimation.start());
  //                } catch (InterruptedException e) {
  //                    e.printStackTrace();
  //                }
  //        }).start();
  
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            if (!isButtonPressed) {
                idleAnimation.start();
            }
            new Handler(Looper.getMainLooper()).postDelayed(this, 2000);
        }
    });
}

Animation:

public class IdleAnimation {

private final VideoView waveAnim;
private Button button;
private final int buttonWidth;
/**
 * We stop the animation if the user has pressed on the button.
 */
private boolean isStopped = false;

public IdleAnimation(VideoView waveAnim, Button button, int buttonWidth) {
    this.waveAnim = waveAnim;
    this.button = button;
    this.buttonWidth = buttonWidth;
    create();
}

/**
 * Idle animation holders
 */
private ValueAnimator animToSmall;
private ValueAnimator animFirstUp;
private ValueAnimator animFirstDown;
private ValueAnimator animSecondUp;

private final ValueAnimator.AnimatorUpdateListener updateListener = animation -> {
    int animatedValue = (int) animation.getAnimatedValue();
    button.getLayoutParams().width = animatedValue;
    button.getLayoutParams().height = animatedValue;
    button.requestLayout();
};

private interface AnimationEndListener extends Animator.AnimatorListener {
    @Override
    default void onAnimationStart(Animator animation) {}
    @Override
    default void onAnimationCancel(Animator animation) {}
    @Override
    default void onAnimationRepeat(Animator animation) {}
}

public void unblock() {
    isStopped = false;
}

public void start() {
    animToSmall.start();
}

public void stop() {
    isStopped = true;
    animToSmall.end();
    animFirstUp.end();
    animFirstDown.end();
    animSecondUp.end();
}

public void create() {
    animToSmall = createAnimation(buttonWidth, buttonWidth - 35, 450);
    animToSmall.addListener((AnimationEndListener) animation -> {
        if (!isStopped) {
            animFirstUp.start();
            waveAnim.start();
        }
    });

    animFirstUp = createAnimation(buttonWidth - 35, buttonWidth - 25, 400);
    animFirstUp.addListener((AnimationEndListener) animation -> {
        if (!isStopped)
            animFirstDown.start();
        else {
            waveAnim.pause();
            waveAnim.seekTo(0);
        }
    });

    animFirstDown = createAnimation(buttonWidth -25, buttonWidth - 30, 100);
    animFirstDown.addListener((AnimationEndListener) animation -> {
        if (!isStopped)
            animSecondUp.start();
        else {
            waveAnim.pause();
            waveAnim.seekTo(0);
        }
    });

    animSecondUp = createAnimation(buttonWidth - 30, buttonWidth, 350);
}

private ValueAnimator createAnimation(int fromValue, int toValue, int duration) {
    final ValueAnimator animator = ValueAnimator.ofInt(fromValue, toValue)
            .setDuration(duration);
    animator.setInterpolator(new AccelerateDecelerateInterpolator());
    animator.addUpdateListener(updateListener);
    return animator;
}
}

Logs:

    PlayerBase                          V  baseStop() piid=14423
    MediaPlayer                         I  [HSM] stayAwake false uid: 10427, pid: 4489
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  Message: MEDIA_PLAYBACK_COMPLETE(2), ext1=0, ext2=0x0
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    PlayerBase                          V  baseStop() piid=14415
    PlayerBase                          V  baseStart() piid=14415
    MediaPlayer                         I  [HSM] stayAwake true uid: 10427, pid: 4489
    MediaPlayerNative                   D  Action:start, CurrentState:MEDIA_PLAYER_STARTED
    MediaPlayer                         I  [HSM] stayAwake false uid: 10427, pid: 4489
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    PlayerBase                          V  baseStart() piid=14423
    MediaPlayer                         I  [HSM] stayAwake true uid: 10427, pid: 4489
    MediaPlayerNative                   D  Action:start, CurrentState:MEDIA_PLAYER_STARTED
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  Message: Unknown MediaEventType(6), ext1=0, ext2=0x0
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  Message: Unknown MediaEventType(6), ext1=0, ext2=0x0
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  Message: MEDIA_PLAYBACK_COMPLETE(2), ext1=0, ext2=0x0
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    PlayerBase                          V  baseStop() piid=14423
    MediaPlayer                         I  [HSM] stayAwake false uid: 10427, pid: 4489
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    PlayerBase                          V  baseStart() piid=14423
    MediaPlayer                         I  [HSM] stayAwake true uid: 10427, pid: 4489
    MediaPlayerNative                   D  Action:start, CurrentState:MEDIA_PLAYER_STARTED
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  Message: Unknown MediaEventType(6), ext1=0, ext2=0x0
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
    MediaPlayerNative                   D  [notify] : [1170] callback app listenerNotNull=1, send=1
0

There are 0 best solutions below