I have a song list and I want to play it in order. So after the song ends, it plays the next song. Here's what I try so far in my MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
var flag = 0
//play the first song
player = MediaPlayer.create(this,songResources.getValue(songList[0]).rawId)
player.start()
//play the next song in order after each of the song ends
player.setOnCompletionListener {
flag++
player = MediaPlayer.create(this,songResources.getValue(songList[flag]).rawId)
player.start()
}
After the first song ends, the second song starts playing. But after the second song ends, the third song didn't start playing. How can I fix this?
It looks like you just need to set your flag variable as a class level variable (i.e. not inside the onCreate() function).
Try declaring private var flag = 0 above onCreate() and see if that works.
Related
So I have my code like this
var flag = 0
player = MediaPlayer.create(this,songResources.getValue(songList[flag]).rawId)
player.start()
player.setOnCompletionListener {
flag++
player = MediaPlayer.create(this,songResources.getValue(songList[flag]).rawId)
player.start()
player.setOnCompletionListener {
flag++
player=MediaPlayer.create(this,songResources.getValue(songList[flag]).rawId)
player.start()
player.setOnCompletionListener {
//and so on, and so forth.
//assume this is the last song on the list.
//set flag back to 0 and the rest is just like above code
flag = 0
player=MediaPlayer.create(this,songResources.getValue(songList[flag]).rawId)
player.start()
player.setOnCompletionListener {// just like above code}
}
}
}
Basically the purpose of the code is after each song in the list ends, it starts the next one. I want to simplify it with for loop, but the problem is, all of the song suddenly playing without waiting the previous song finish. Is there a way to simplify it?
You can use recursion the achieve that, by creating a playSong function which takes the list of songs and the index of the song that are going to play and when that song completed this function is going to call itself with the next index, like that:
fun playSong(songList: List<Int>, flag: Int) {
player = MediaPlayer.create(this, songResources.getValue(songList[flag]).rawId)
player.start()
player.setOnCompletionListener {
playSong(player, list, if (flag == list.lastIndex) 0 else flag + 1)
}
}
if (flag == list.lastIndex) 0 else flag + 1: This means if the completed song is the last song => play the first one; else => play the next one.
In my app there is a "Start" button.
The desire result is whenever the media player is playing,the text of the button should be change to "Stop", and when the music stops the button text should change back to "Start".
I tried doing "Do While Loop" as a solution, but even when media player isn't playing,the text is changed.
Is this the right solution ?
Why does it work even when mainViewModel.mediaPlayer.isPlaying is false?
This is what I tried:
private fun trackPlayButtonTransformation() {
do {
rootView.speakButton.text = "Stop"
} while (mainViewModel.mediaPlayer.isPlaying)
}
mainViewModel.mediaPlayer:
var mediaPlayer = MediaPlayer()
Thanks!
In a do while, the first instruction is ran no matter what, therein lies your problem. Do a regular while
private fun trackPlayButtonTransformation() {
while (mainViewModel.mediaPlayer.isPlaying) {
rootView.speakButton.text = "Stop"
}
}
Even this is clearly missing, you want to set the text to Play if the condition is'nt met.
You should probably use an actionListener on the button itself, and do a switch
const button = findById...... You should be able to find that easily.
button.addEventListener('click', buttonIsClicked())
private buttonIsClicked () {
if ( mainViewModel.mediaPlayer.isPlaying ) {
// stop that song
// change the text
}
else {
// play that song
// change the text
}
}
this is a rought draft, but this kind of is how I would do a play button.
I try to play and pause an audio file on the same button in my recyclerView adapter. But if I press my "playbtn" it just play and not pause.
Here is my function:
fun playmusic(position: Int) {
val post = posts[position]
mp = MediaPlayer()
mp.setDataSource(post.audioUrl)
mp.prepareAsync()
mp.setOnPreparedListener { player ->
if (player.isPlaying)
player.pause()
else{
player.start()
}
}
}
Here is my clickListner:
playbtn.setOnClickListener {
playmusic(postPosistion)
Toast.makeText(context, "You play ${postPosistion + 1}", Toast.LENGTH_SHORT).show()
}
Every View object has a method called setTag/getTag, this is used to store small info about the state of the view.
In your 'play' button's click listener, you can set tag with your custom state, it could be anything, an integer, a string, or even a sealed class states. After then, it's just simple if-else logic, in your if condition, check if the getTag as T(the type of object you previously-stored), matches playing state, then pause else play.
I have a list of songs i put manually inside my app and it currently have 3 functions: start, pause and stop (using ImageViews).
The problem is that i can play multiple songs at the same time that is not supposed to be like that. I really cant find the issue here and hope someone can help.
This is a demonstration on my problem
I want it to STOP currently playing song when another song is being clicked on.
Here is my code for my play button:
viewholder.playB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (currentSong == null || song != currentSong) {
currentSong = song;
mediaPlayer = MediaPlayer.create(context, song.getSong());
}
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewholder.playB.setImageResource(R.drawable.play_black);
} else {
mediaPlayer.start();
viewholder.playB.setImageResource(R.drawable.pause_black);
}
}
});
Instead of always creating a new instance of MediaPlayer every time the event onClick is called, you should create a single instance and reused it.
To play a new song don't forget to reset your player first. Here is an example:
mPlayer.reset();
mPlayer.setDataSource(context, song.getSong());
I am working in android. I am creating a mediaPlayer which is running audio files. i have 10 buttons. i have assigned different url to each button. So when i press button1 then song of url with respect to button 1 is playing. and then i click on 2nd button then song of button 2 is also playing with song 1. but i want to stop song of button 1 when i press button 2.
this is the code i am using for this functionality:-
public void onClick(View v)
{
MediaPlayer mediaPlayer=new MediaPlayer();
if (mediaPlayer.isPlaying())
{
mediaPlayer.stop();
mediaPlayer.release();
}
int i = Integer.parseInt((v.getTag()).toString());
String str=urls[i];
try {
mediaPlayer.setDataSource(str);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e)
{
e.printStackTrace();
}
}
please check my code and let me know what is mistake done by me.
you have construct a new MediaPlayer object each time the user click you view
how could it be in the running state !!!
calling release() method on a MediaPlayer object it is in thre End state
Once the MediaPlayer object is in the End state, it can no longer be used and there is no way to bring it back to any other state.
but in case you want to reuse a MediaPlayer object you should call the
call the following method in the same order
reset()
make the mediaPlayer enter the Idle state
setDataSource()
set your data source note : the mediaplayer shoud be in the idle state
prepare()
start()