Reputation: 295
I am trying to duplicate the drawing process on a TextureView into other TextureViews. The main goal being to be able to create a "wall" of one same video being played from one instance of a MediaPlayer attached to a TextureView (I've got that part done). This is first for performance issues since using multiple MediaPlayer instances could have catastrophic performances, and also to be sure that all the videos are on sync with each other.
Thank you for your answers/suggestions.
Edit: Overriding onDraw() doesn't work because TextureView uses OpenGL to draw on its surface. If anyone has some insight on how I can duplicate or override that behavior. Other suggestions are of course welcome!
Upvotes: 2
Views: 1838
Reputation: 1781
Originally, I thought you might be lucky and this might be a simple case of overriding the onDraw(Canvas)
method of the TextureView to do something like this:
final int xTiles = 5;
final int yTiles = 5;
@Override
public void onDraw(Canvas canvas){
int widthPerTile = canvas.getWidth() / xTiles;
int heightPerTile = canvas.getHeight() / yTiles;
float widthScale = widthPerTile / (float) canvas.getWidth();
float heightScale = heightPerTile / (float) canvas.getHeight();
for(int x = 0; x < xTiles; x++){
for(int y = 0; y < yTiles; y++){
canvas.save();
canvas.translate(x * widthPerTile, y * heightPerTile);
canvas.scale(widthScale, heightScale);
super.onDraw(canvas);
canvas.restore();
}
}
}
Then you will only need one CustomTextureView taking up the whole screen and it'll look like a lot, because it will be drawing itself lots of times.
However, this is not how the TextureView works. The TextureView instead has a dummy onDraw(Canvas)
method and instead uses its own draw(Canvas)
method which is final and therefore cannot be overriden. The TextureView is using OpenGL to draw the frames from the camera, and it's quite complicated to inject yourself in that process, although it seems posssible following examples like can be found being discussed here. This is an advanced topic indeed and probably a bit much for a Saturday morning for me to write a succinct answer for.
But, I did manage to hack something together quickly that you might be able to take advantage of and run with, although it has some obvious issues with regards to memory and framerate:
public class CopyCatTextureView extends View {
TextureView textureViewToCopy;
public CopyCatTextureView(Context context) {
super(context);
}
public void setTextureViewToCopy(TextureView view){
this.textureViewToCopy = view;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(textureViewToCopy != null){
textureViewToCopy.draw(canvas);
}
}
}
If you have a grid of a single TextureView and the rest being these CopyCatTextureViews, you can call setTextureViewToCopy(TextureView)
on each of the copy cats to point to the single TextureView and then simply call invalidate()
on each of the copy cats whenever you want a frame update. Obviously this is not ideal, but it's quick and certainly will work if you just want a single frame.
Hope this helps. Best of luck.
(Variable edited)
Upvotes: 1