Texture Preview video and bitmap

I have a TextureView that displays a bitmap (placeholder image) and when the user uploads the video, the texture should show the video.

I was able to get the video to play as a texture and show the bitmap in texture view, but when done sequentially I just get a black screen.

In my onSurfaceTextureAvailable method, I will draw a bitmap onto the surface view like this:

public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ic_add_clip);
    Canvas canvas = lockCanvas();
    canvas.drawBitmap(bm, (width/2)-(bm.getWidth()/2), (height/2)-(bm.getHeight()/2), null);


When the user selects a video from their gallery, I load the Uri into the Media Player and set the surface to the media player. But the bitmap is still displayed. I tried to remove the bitmap by clearing the canvas and it removes the bitmap, but then the textured view is just black and won't show the video.

public void setMediaPlayer(MediaPlayer mediaPlayer) {
    // Canvas canvas = lockCanvas();
    // canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    // unlockCanvasAndPost(canvas);

    Surface s = new Surface(getSurfaceTexture());
    mMediaPlayer = mediaPlayer;


Something tells me that the surface view I'm using to display the video is behind the bitmap I'm drawing in TextureAvailble. And when I try to clean the canvas, I also clean the surface that the media player wants to use. Any solutions?


source to share

2 answers

Your approach won't work.

The surface is a queue of buffers with producer-consumer relationships. There can only be one producer at a time, and you have two producers (Canvas and MediaPlayer). When you call mMediaPlayer.setSurface()

it attaches to the MediaPlayer; when you call lockCanvas()

it attaches the Canvas. You need to detach one before you can attach it to the other.

(Check your logcat output - there are probably some "already related" complaints there.)

The problem is you must be able to detach the MediaPlayer, you cannot detach the Canvas. There is simply no bell that does it. This is an unfortunate artifact in the API. (Confirmed prior to 4.4 "KitKat" and I doubt it has changed since then.)

You have several options:

  • Draw a bitmap with GLES. You can see an example in the Grafika PlayMovieSurface activity - see the method clearSurface()

    that just clears the screen. With GLES, you can attach and detach from a surface.
  • Convert the bitmap to a single-frame video and play it through MediaPlayer.
  • Place the ImageView on top of the video window using FrameLayout. Hide ImageView while video is playing.

I must add that I haven't actually tried to detach the MediaPlayer from the Surface. This lower level MediaCodec works in the way that the Grafika player shows, so I assume the MediaPlayer will be disabled as well. For your use case, however, # 3 is probably the easiest solution and doesn't require gymnastics plugging / unplugging.



You can use opengl es to paint a bitmap on the display surface and then paint the video frame in the same way. I did like this and it works great.



All Articles