12

I'm using a ListView with TextureView children. The TextureView uses a MediaPlayer to play videos. When the TextureView gets recycled, the last frame remains on the surface until the next MediaPlayer makes use of it.

What is the easiest way to "clear" the TextureView's surface (e.g black) so the old frames do not appear?

Gilbert
  • 543
  • 7
  • 20

2 Answers2

9

After struggling with this for a while, I've come up with a couple of possible solutions:

a) clear the surface using GLES. You can see an example in Grafika (check out the clearSurface() method). I'm personally not a fan of this because I don't think that a jarring transition to black looks particularly good, and it's a fair bit of technical overhead if you aren't already using GL code. Additionally, this only seems to work for API 17+.

b) My chosen solution was to simply create a new TextureView and add it to the appropriate view every time I wanted to play a video, instead of reusing an old one. I would hesitate to call this a good solution, but it's the least horrible one I could find.

c) One thing you might be able to do if you're playing the same video again is to try to seek to the first frame of the video when it's done playing. Then the next time the last frame flashes, it won't be visible since it will be the same frame as the beginning of the video. I had some success with this but couldn't get it to work reliably on all devices. It's also pretty clearly a hack.

Good luck, this was immensely frustrating to try to fix.

gcgrant
  • 351
  • 4
  • 12
  • 1
    There's also (d) add a blank View on top of the TextureView. Hide it while playing videos, show it when playback stops. – fadden Feb 05 '15 at 21:53
  • 1
    The problem with that, at least that I found, is that the video will flash the first frame when playback starts, even after the MediaPlayer onPrepared call. I couldn't find a way to determine when the texture was actually ready! If there is such a thing I'd love to know. – gcgrant Feb 05 '15 at 23:05
  • I know this is old but are you able to share your code for b)? Unfortunately I've been unable to get any solution to reliably work. – Cory Charlton Jan 27 '16 at 05:13
  • Unfortunately I can't share the code, but the gist of it is pretty straightforward. My solution was to use an empty ViewGroup (in my case, a FrameLayout worked fine), defined in XML. When it came time to play a video, I would instantiate a new TextureView, and add it as a child to that ViewGroup, removing it when video playback finished, or when a view recycle occurs. That or fadden's solution of a blank view on top of the texture should be able to get you what you need. – gcgrant Jan 28 '16 at 17:47
2

2020 simplest way is to simply set the alpha of the texture view to 0.

mTextureView.setAlpha(0);

Wharbio
  • 1,345
  • 9
  • 15