Search code examples
androidmedia-player

Android MediaPlayer change live stream's URL


I have a problem with changing URL of live stream in the MediaPlayer instance. When I tap on a ListView item for a first time, live streaming is started and video is displayed, but if I click on another object in the ListView, stream is not changed, the same stream continues to play which was executed at first time.

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, VideoControllerView.MediaPlayerControl {

    SurfaceView videoSurface;
    MediaPlayer player;
    VideoControllerView controller;

    ArrayList<Channel> channels;
    Channel clickedChannel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        videoSurface = (SurfaceView) findViewById(R.id.videoSurface);
        SurfaceHolder videoHolder = videoSurface.getHolder();
        videoHolder.addCallback(this);
        controller = new VideoControllerView(this);
        player = new MediaPlayer();

        channels = new ArrayList<Channel>();
        CreateChannels();

        ListView lvMain = (ListView) findViewById(R.id.lvMain);
        CustomAdapter adapter = new CustomAdapter(this, channels);

        lvMain.setAdapter(adapter);
        lvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Log.d(LOG_TAG, "itemClick: position = " + position + ", id = "
                        + id);
                clickedChannel = channels.get(position);

                        }
                    }
                }

                PlayStream(clickedChannel.Streams[0].URL);

            }
        });

    }

    public void PlayStream(String URL) {

        try {
            player.setAudioStreamType(AudioManager.STREAM_MUSIC);
            player.setDataSource(this, Uri.parse(URL));
            player.setOnPreparedListener(this);
            player.prepareAsync();
            player.start();

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

// missed code

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        controller.show();
        return false;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        player.setDisplay(holder);
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        controller.setMediaPlayer(this);
        controller.setAnchorView((FrameLayout) findViewById(R.id.videoSurfaceContainer));
        player.start();
    }

}

Solution

  • Solved my problem by recreating player instance every time

    public void PlayStream(String URL) {
            releaseMP();
            try {
                player = new MediaPlayer();
                player.setDisplay(videoHolder);
                player.setAudioStreamType(AudioManager.STREAM_MUSIC);
                player.setDataSource(this, Uri.parse(URL));
                player.setOnPreparedListener(this);
                player.prepareAsync();
                player.start();
    
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private void releaseMP() {
            if (player != null) {
                try {
                    player.release();
                    player = null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            releaseMP();
        }
    @Override
        public void surfaceCreated(SurfaceHolder holder) {
    
        }