Playing multiple songs with MediaPlayer at the same time: only one is really playing

前端 未结 5 1869
甜味超标
甜味超标 2021-01-02 04:44

I need help with playing multiple audio tracks at the same time in Android.

I am supposed to play three audio tracks at the exact same

相关标签:
5条回答
  • 2021-01-02 04:45

    As Andrey Nikishaev already wrote in a comment, it seems like some devices have problems using multiple MediaPlayers at the same time. While only one was playing on my Nexus 5, it worked on my Moto G4 (but still having short breaks during playback). Both running with Android 6.0.1.

    I suggest to use the ExoPlayer for this use-case instead. It worked fine for me, at least on my two devices.

    0 讨论(0)
  • 2021-01-02 04:52

    I converted my mp3 in ogg file audio (using Audacity) and I am been able to use 2 Mediaplayer istances and listen the audio mixed.

    I didn't try is it is possible for more than 3.

    0 讨论(0)
  • 2021-01-02 04:54

    Well, I believe I found what I could name "a temporary solution".

    MediaPlayer track1 = MediaPlayer.create(this, R.raw.track1);
    track1.start();
    MediaPlayer track2 = MediaPlayer.create(this, R.raw.track2);
    track2.start();
    MediaPlayer track3 = MediaPlayer.create(this, R.raw.track3);
    track3.start();
    

    The problem with this is that the create() method creates a noticeable gap when the songs are being played.

    So this is not it.

    After a while, I tried the following :

    MediaPlayer track1 = MediaPlayer.create(this, R.raw.track1);
    track1.start();
    track1.pause();
    MediaPlayer track2 = MediaPlayer.create(this, R.raw.track2);
    track2.start();
    track2.pause();
    MediaPlayer track3 = MediaPlayer.create(this, R.raw.track3);
    track3.start();
    track3.pause();
    
    // resuming...
    track1.start(); 
    track2.start();
    track3.start();
    

    That whay, the songs are more synchronous. I can still hear a very small gap but it is way better. I found this solution quite strange as well as ugly.

    Unless someone has another idea, I will stick with that solution.

    0 讨论(0)
  • 2021-01-02 05:01

    hi try below code it will work it the song wont stop you just need to select the song from spinner and click on start button, then select next song from spinner and click start it will work.

    public class MainActivity extends AppCompatActivity {
    
        Spinner sp;
        Button bstart;
        MediaPlayer mp;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            sp=(Spinner)findViewById(R.id.sp);
            String [] mys={"demo","democheap","demorehana"};
            ArrayAdapter<String> data=new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,mys);
            sp.setAdapter(data);
    
        }
    
        public void code(View v)
        {
            if(sp.getSelectedItem().toString().equals("demo"))
            {
                mp=MediaPlayer.create(this,R.raw.demo);
            }
            else if(sp.getSelectedItem().toString().equals("democheap"))
            {
                mp=MediaPlayer.create(this,R.raw.democheap);
            }
            else if(sp.getSelectedItem().toString().equals("demorehana"))
            {
                mp=MediaPlayer.create(this,R.raw.demorehana);
            }
    
            if(v.getId()==R.id.bstart)
            {
                mp.start();
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-02 05:04

    I achieved what you're looking for using a CyclicBarrier instance and an inner class implementation.

    Example:

    public enum MP_COMMAND {
        START,
        STOP,
        PAUSE
    }
    
    /**
     * Uses threads to execute synced commands for the current video media player and 
     * background music player in tandem.
     */
    public void syncedCommand(MediaPlayer player1, MediaPlayer player2, MP_COMMAND command) {
        final CyclicBarrier commandBarrier = new CyclicBarrier(2);
        new Thread(new SyncedCommandService(commandBarrier, player1, command)).start();
        new Thread(new SyncedCommandService(commandBarrier, player2, command)).start();
    }
    
    /**
     * Inner class that starts a given media player synchronously
     * with other threads utilizing SyncedStartService
     */
    private class SyncedCommandService implements Runnable {
        private final CyclicBarrier              mCommandBarrier;
        private       MediaPlayerTest.MP_COMMAND mCommand;
        private       MediaPlayer                mMediaPlayer;
    
        public SyncedCommandService(CyclicBarrier barrier, MediaPlayer player, MediaPlayerTest.MP_COMMAND command) {
            mCommandBarrier = barrier;
            mMediaPlayer = player;
            mCommand = command;
        }
    
        @Override public void run() {
            try {
                mCommandBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
    
            switch (mCommand) {
                case START:
                    mMediaPlayer.start();
                    break;
    
                case STOP:
                    mMediaPlayer.stop();
                    break;
    
                case PAUSE:
                    mMediaPlayer.pause();
                    break;
    
                default:
                    break;
            }
        }
    }
    

    You'd utilize it like so:

    syncedCommand(mCurrentVideoPlayer, mBackgroundMusic, MP_COMMAND.START);
    

    If you had the requirement that it be usable for any number of media players, you could easily implement it - my requirements just call for two.

    I realize this question is old, but this page is where I found myself while searching for a solution, so I hope this helps anyone stuck on this issue in the future.

    0 讨论(0)
提交回复
热议问题