9

What I want to do is Show a background image on the SurfaceView before starting to play video.

  1. I tried to just draw a jpeg image as its background of SurfaceView. It worked.
  2. I also tried to play a video on the SurfaceView. It also worked.

But, when I tried to draw the jpeg image as the background of Surface in surfaceCreated function and then play a video. I got the error "[SurfaceView] connect: already connected".

Any ideas? Thanks.

Here is the partial code

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
    Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.pic1);
    float scale = (float) background.getHeight()/(float)mPreview.getHeight();
    int newWidth = Math.round(background.getWidth()/scale);
    int newHeight = Math.round(background.getHeight()/scale);
    mScaledBitmap = Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
    Canvas canvas = mHolder.lockCanvas();
    canvas.drawBitmap(mScaledBitmap, 0, 0, null);
    mHolder.unlockCanvasAndPost(canvas);
    } catch (Exception e)
    {}
            // initialize mediaplayer
    try {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setDataSource("/sdcard/Movies/2.mp4");
        mMediaPlayer.setDisplay(mHolder);
        mMediaPlayer.setLooping(true);
        mMediaPlayer.prepare();
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnCompletionListener(this);
    } catch (IOException e) {
        e.printStackTrace();
        Log.e(TAG, "error: " + e.getMessage(), e);
    } catch (Exception e) {
        e.printStackTrace();
        Log.e(TAG, "error: " + e.getMessage(), e);  
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    // TODO Auto-generated method stub
    Log.i(TAG, "surfaceChanged(w="+ width + ", h=" + height);
    mSurfaceWidth = width;
    mSurfaceHeight = height;
    mVideoWidth = mMediaPlayer.getVideoWidth();
    mVideoHeight = mMediaPlayer.getVideoHeight();
    Log.i(TAG, "video size w=" + mVideoWidth + ", h=" + mVideoHeight +")");     
}


@Override
public void onPrepared(MediaPlayer mp) {
    // TODO Auto-generated method stub
    Log.i(TAG, "onPrepared");
    mMediaPlayer.start();
}
hamer
  • 123
  • 1
  • 6

2 Answers2

0

I think problem is you can use out side SurfaceHolder just change mHolder object with local holder object it will be work. i can not try it on my side.

Jayesh Khasatiya
  • 2,140
  • 1
  • 14
  • 15
0

Here are couple of things that I see wrong based on my experience with MediaPlayer.

  • First, use prepareAysnc() instead of prepare().
  • Second, set the listeners first before calling prepare(). In your case, mMediaPlayer.setOnPreparedListener(this)

is followed by prepare(). Consider scenario where prepare() upon completion looks for OnPreparedListener and does not finds it, because you haven't set it yet. And setting it afterwards is not going to help since, media player is already in PREPARED state and thus you'd never get onPrepared() callback.

Thus in your case, mMediaPlayer.start() may never get executed.

In general, set all the necessary listeners first, before invoking their triggers.

AllThatICode
  • 1,250
  • 13
  • 19