I am trying to implement the following, for a workout android app:
My question is, how do you combine video with Audio? For Video I use ExoPlayer. Is it good to combine ExoPlayer with SoundPool for Audio? Should I create multiple instances of ExoPlayer for both (and if so, to what do I bind the AudioPlayer Instance)?
According to this I found that the best solution was to use ExoPlayer for videos, and SoundPool for short audio speech indications.
I use an observer function in which I listen for timer events (ie tick == 4000) and use soundPool.play() each time the event happens.
For the Video, I listen to Timer Events (PLAYING, PAUSED, STOPPED) and use videoPlayer.play() as well.
See below code as an example:
private fun subscribeObservers() {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
sharedViewModel.timer.tick.collect { tick ->
// tick can only be multiple of 1000
if (tick == 0L) {
binding.startWorkoutTvTimer.text = ""
} else {
binding.startWorkoutTvTimer.text = (tick / 1000).toString()
}
if (tick == 4000L) {
sharedViewModel.soundPool?.play(sharedViewModel.countdownSoundId, 1F, 1F, 0, 0, 1F)
}
// SoundPool needs to be preloaded from previous Fragment
if (tick == 10000L) {
if (sharedViewModel.currentExercise == 0) {
sharedViewModel.soundPool?.play(sharedViewModel.beginWorkoutSoundId, 1F, 1F, 1, 0, 1F)
} else {
sharedViewModel.soundPool?.play(sharedViewModel.goSoundId, 1F, 1F, 1, 0, 1F)
}
}
}
}
launch {
sharedViewModel.timer.timerMode.collect { playerMode ->
when (playerMode) {
TimerMode.PLAYING -> {
binding.startWorkoutBtnPause.setBackgroundResource(R.drawable.ic_baseline_pause_24)
videoPlayer?.play()
}
TimerMode.PAUSED -> {
binding.startWorkoutBtnPause.setBackgroundResource(R.drawable.ic_baseline_play_arrow_24)
videoPlayer?.pause()
}
TimerMode.STOPPED -> {
}
}
}
}
}
}
}