【问题标题】:2 audios playing at the same time in mediapalyer in android在android的媒体播放器中同时播放2个音频
【发布时间】:2021-09-05 07:38:43
【问题描述】:

请帮忙!!

我在回收站视图中使用媒体播放器,问题是当点击不同项目的播放按钮时,它们都会同时播放。如何停止之前的音频并开始新的音频?

这是适配器代码:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>  {
    final MediaPlayer mediaPlayer = new MediaPlayer();


 public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int position) {
        try {
            mediaPlayer.reset();
            mediaPlayer.setDataSource(item.get(position).getAudio());
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }

viewHolder.play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mediaPlayer.isPlaying()) {
                        mediaPlayer.pause();
                        viewHolder.play.setImageResource(R.drawable.play);

                } else {
                    mediaPlayer.start();
                    viewHolder.play.setImageResource(R.drawable.pause);
                }

我想一个答案是使用标志。但我不知道如何实现。

【问题讨论】:

    标签: android android-recyclerview android-mediaplayer


    【解决方案1】:

    同时播放多个音频,因为MediaPlayer 对象有多个实例,因为它在每次调用onBindViewHolder() 时都会被实例化;即RecyclerView 的每一行都有一个唯一的对象。

    要解决这个问题,您只需要为所有音频使用一个对象,因此转移

    final MediaPlayer mediaPlayer = new MediaPlayer();
    

    成为适配器类的直接字段。

    更新:

    现在改变播放按钮点击的逻辑

    public void onBindViewHolder(@NonNull MyAdapter.ViewHolder viewHolder, int position) {
    
        viewHolder.play.setOnClickListener(new View.OnClickListener() {
            @Override
                public void onClick(View view) {
                
                    if (mediaPlayer.isPlaying()) {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        viewHolder.play.setImageResource(R.drawable.play);
                    } 
                    
                    try {
                        mediaPlayer.reset();
    mediaPlayer.setDataSource(item.get(position).getAudio());
                        mediaPlayer.prepare();
                        mediaPlayer.start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    
                    viewHolder.play.setImageResource(R.drawable.pause);
                                
                }
            }
    
    }
    

    更新 2:

    尝试将播放按钮代码转移到 ViewHolder 而不是onBindViewHolder,而不是position,使用getAbsoluteAdapterPosition()

    public static class ViewHolder extends RecyclerView.ViewHolder {
    
        //.....
        
        public ViewHolder(View itemView) {
            super(itemView);
            play = itemView.findViewById(...);
            
            play.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                
                    // ..... Add the mediaPlayer code
                                    
                }
            }
        }
    
    }
    

    【讨论】:

    • 我将它转移到代码的开头,现在我在 setDataSource 行中遇到错误
    • 你能用你得到的错误更新问题吗。请完整的堆栈跟踪
    • @ghazalia 请在mediaPlayer.setDataSource()之前添加mediaPlayer.reset()
    • 现在我没有错误。但是当我单击两个播放按钮时,两个音频仍然一起播放
    • @ghazalia 请查看更新后的答案
    【解决方案2】:

    这是 MediaPlayer() 类的双重实例化的问题。你要做的就是创建一个像这样的对象类:

    import android.media.MediaPlayer
    import android.net.Uri
    import java.util.concurrent.ExecutorService
    import java.util.concurrent.Executors
    
    object MusicObject {
    
        private lateinit var mediaPlayer: MediaPlayer
        private val executor: ExecutorService = Executors.newCachedThreadPool()
        private var flag = 0
        private var musicName = ""
        private var musicID = 1
        private var musicUri: Uri? = null
    
        // Function to play music
        fun playMusic(mp: MediaPlayer,name: String,ID: Int,Uri: Uri) {
            if (flag > 0) {
                pauseMusic()
            }
            flag++
            musicName = name
            musicID = ID
            musicUri = Uri
            mediaPlayer = mp
            executor.execute {
                mediaPlayer.start()
            }
        }
    
        // Function to play currently playing music again
        fun playMusicAgain() {
            executor.execute {
                mediaPlayer.start()
            }
        }
    
        // Function to pause music
        fun pauseMusic() {
            mediaPlayer.pause()
        }
    
        // Function to stop music
        fun stopMusic() {
            if (mediaPlayer.isPlaying) {
                mediaPlayer.stop()
            }
        }
    
        fun getMediaPlayer(): MediaPlayer {
            return mediaPlayer
        }
    }
    

    并调用这个类来播放和暂停音乐。

    播放音乐:

    MusicObject.playMusic(MediaPlayer.create(this, songUri), idOfMusic, songID, songUri)
    

    暂停音乐:

    MusicObject.pauseMusic()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多