Search code examples
androidvideoandroid-mediaplayerrtsp

Android MediaPlayer Replay Issue


I am having an few issues when I use Android's MediaPlayer Class to replay a completed video.

  1. I have looked at MediaClass Android SDK and the state diagram. From what I can tell, once a video has completed playing you should be able to call start() and have it start at the beginning.
  2. However when I replay an RSTP file these are the errors I get:

01-10 11:36:49.138: E/MediaPlayer(4821): error (-2147483648, 0)
01-10 11:36:49.146: E/MediaPlayer(4821): error (1, -1)
01-10 11:36:49.154: E/MediaPlayer(4821): Error (-2147483648,0)
01-10 11:36:49.162: E/MediaPlayer(4821): Attempt to call getDuration without a valid mediaplayer
01-10 11:36:49.162: E/MediaPlayer(4821): error (-38, 0)
01-10 11:36:49.169: E/MediaPlayer(4821): Error (1,-1)
01-10 11:36:49.185: E/MediaPlayer(4821): Error (-38,0)

3.The last issue occurs when I replay a MPG4 that is on a website. After hitting play again the video does not show and the seekbar moves way out of sync.

Below is my code for the Activity.

public class CustomMediaPlayer extends Activity implements MediaPlayerControl,
        OnCompletionListener, OnErrorListener, OnInfoListener,
        OnPreparedListener, OnSeekCompleteListener, OnVideoSizeChangedListener,
        SurfaceHolder.Callback, OnBufferingUpdateListener {




    // TODO Remove
    String TAG = "VAC";
    public static final String FILE_PATH = "rtsp://v4.cache2.c.youtube.com/CjYLENy73wIaLQkQ7cBxuSy88hMYDSANFEIJbXYtZ29vZ2xlSARSBXdhdGNoYJitofTlp8vjUAw=/0/0/0/video.3gp";

    //

    PowerManager pm;
    PowerManager.WakeLock wl;

    SpeechRecognizer sr;
    ImageView talkImageview;

    Toast toast;

    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;

    MediaPlayer mediaPlayer;
    MediaController controller;

    ProgressBar progressBar;

    Display currentDisplay;

    int videoWidth = 0;
    int videoHeight = 0;
    boolean readyToPlay = false;

    Handler handler;

    int bufferedPercentage;

    boolean finishedPlaying = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_player);

        pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
                | PowerManager.ACQUIRE_CAUSES_WAKEUP
                | PowerManager.ON_AFTER_RELEASE, new String());
        wl.acquire();

        preInitWidgets();
    }

    private void preInitWidgets() {
        toast = Toast.makeText(this, "", Toast.LENGTH_LONG);
        progressBar = (ProgressBar) findViewById(R.id.VideoPlayerProgressBar);
        talkImageview = (ImageView) findViewById(R.id.VideoPlayerTalkImageView);

        sr = SpeechRecognizer.createSpeechRecognizer(this);
        sr.setRecognitionListener(new listener());

        handler = new Handler();

        surfaceView = (SurfaceView) findViewById(R.id.VideoPlayerSurfaceView);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mediaPlayer = new MediaPlayer();
        mediaPlayerInit();
        currentDisplay = getWindowManager().getDefaultDisplay();
        controller = new MediaController(this);

    }

    void mediaPlayerInit() {

        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnErrorListener(this);
        mediaPlayer.setOnInfoListener(this);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnSeekCompleteListener(this);
        mediaPlayer.setOnVideoSizeChangedListener(this);
        mediaPlayer.setOnBufferingUpdateListener(this);

        try {
            mediaPlayer.setDataSource(FILE_PATH);

            // mediaPlayer.setDataSource("http://www.blk-burn.com/sandbox/sj.mp4");
        } catch (Exception e) {
            toast.setText("Failed To Load Video");
            toast.show();
        }

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub

    }

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

        try {
            mediaPlayer.prepareAsync();
        } catch (Exception e) {
            toast.setText("Failed to Prepare");
            toast.show();
        }

        progressBar.setVisibility(View.VISIBLE);

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onVideoSizeChanged(android.media.MediaPlayer mp, int width,
            int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSeekComplete(android.media.MediaPlayer mp) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int bufferedPercent) {
        this.bufferedPercentage = bufferedPercent;

    }

    @Override
    public void onPrepared(android.media.MediaPlayer mp) {
        videoWidth = mp.getVideoWidth();
        videoHeight = mp.getVideoHeight();

        if (videoWidth > currentDisplay.getWidth()
                || videoHeight > currentDisplay.getHeight()) {
            float heightRatio = (float) videoHeight
                    / (float) currentDisplay.getHeight();
            float widthRatio = (float) videoWidth
                    / (float) currentDisplay.getWidth();

            if (heightRatio > 1 || widthRatio > 1) {
                if (heightRatio > widthRatio) {
                    videoHeight = (int) Math.ceil((float) videoHeight
                            / (float) heightRatio);
                    videoWidth = (int) Math.ceil((float) videoWidth
                            / (float) heightRatio);
                } else {
                    videoHeight = (int) Math.ceil((float) videoHeight
                            / (float) widthRatio);
                    videoWidth = (int) Math.ceil((float) videoWidth
                            / (float) widthRatio);
                }
            }
        }

        surfaceView.setLayoutParams(new LinearLayout.LayoutParams(videoWidth,
                videoHeight));

        surfaceView.setLayoutParams(new LinearLayout.LayoutParams(videoWidth,
                videoHeight));
        controller.setMediaPlayer(this);
        controller
                .setAnchorView(findViewById(R.id.VideoPlayerSurfaceViewLinearLayout));
        controller.setEnabled(true);
        controller.show();

        mp.start();

        // TODO - Get Catch Phrase

        talkImageview.setVisibility(View.VISIBLE);
        progressBar.setVisibility(View.GONE);

        // startListeningForVoice();

    }

    @Override
    public boolean onInfo(android.media.MediaPlayer mp, int what, int extra) {
        // TODO
        return false;
    }

    @Override
    public boolean onError(android.media.MediaPlayer mp, int what, int extra) {
        if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
            toast.setText("Media Server Died");
            toast.show();
        } else if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
            toast.setText("Unknown Error");
            toast.show();
        }
        return false;
    }

    @Override
    public void onCompletion(android.media.MediaPlayer mp) {



    }

    public boolean canPause() {
        return true;
    }

    public boolean canSeekBackward() {
        return true;
    }

    public boolean canSeekForward() {
        return true;
    }

    public int getBufferPercentage() {
        return bufferedPercentage;

    }

    public int getCurrentPosition() {
        return mediaPlayer.getCurrentPosition();
    }

    public int getDuration() {
        return mediaPlayer.getDuration();
    }

    public boolean isPlaying() {
        return mediaPlayer.isPlaying();
    }

    public void pause() {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }

    public void seekTo(int pos) {
        mediaPlayer.seekTo(pos);
    }

    public void start() {
        mediaPlayer.start();

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            if (controller.isShowing()) {
                controller.hide();
            } else {
                controller.show();
            }
        }
        return false;
    }

    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        mediaPlayer.stop();
        mediaPlayer.release();
        wl.release();

    }





}

Solution

  • Your setDataSource is the issue here. Android doesnt support rtsp streams. I tried rtsp several times without luck. If you try to stream from http, it should definately work if the video format is supported. Take a look at Vitamio library here http://vitamio.org/. It supports rtsp streams as well as many other audio and video formats that are not supported by android.