hamer
hamer

Reputation: 123

get "[SurfaceView] connect: already connected" error if I draw a bitmap as the background of SurfaceView and then play video

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();
}

Upvotes: 9

Views: 2895

Answers (2)

AllThatICode
AllThatICode

Reputation: 1300

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.

Upvotes: 0

Jayesh Khasatiya
Jayesh Khasatiya

Reputation: 2140

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.

Upvotes: 0

Related Questions