Дублируйте TextureView в другой

Я пытаюсь продублировать процесс рисования в TextureView в других TextureView. Основная цель состоит в том, чтобы иметь возможность создать «стену» из одного и того же видео, воспроизводимого из одного экземпляра MediaPlayer, прикрепленного к TextureView (я сделал эту часть). Это в первую очередь связано с проблемами производительности, поскольку использование нескольких экземпляров MediaPlayer может привести к катастрофическим последствиям, а также для обеспечения синхронизации всех видео друг с другом.

Спасибо за ваши ответы/предложения.

Редактировать: переопределение onDraw() не работает, потому что TextureView использует OpenGL для рисования на своей поверхности. Если у кого-нибудь есть представление о том, как я могу дублировать или переопределить это поведение. Другие предложения, конечно, приветствуются!


person Hey'Youssef    schedule 25.02.2017    source источник


Ответы (1)


Первоначально я думал, что вам может повезти, и это может быть простой случай переопределения метода onDraw(Canvas) TextureView, чтобы сделать что-то вроде этого:

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

Тогда вам понадобится только один CustomTextureView, занимающий весь экран, и он будет выглядеть много, потому что он будет рисовать себя много раз.

Однако TextureView работает иначе. Вместо этого TextureView имеет фиктивный метод onDraw(Canvas) и вместо этого использует свой собственный метод draw(Canvas), который является окончательным и поэтому не может быть переопределен. TextureView использует OpenGL для отрисовки кадров с камеры, и довольно сложно внедрить себя в этот процесс, хотя кажется возможным следующие примеры, которые можно найти в обсуждаемых здесь. Это действительно сложная тема, и, вероятно, это слишком для субботнего утра, чтобы я мог написать краткий ответ.

Но мне удалось быстро собрать кое-что, чем вы могли бы воспользоваться и работать, хотя у него есть некоторые очевидные проблемы с памятью и частотой кадров:

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

Если у вас есть сетка из одного TextureView, а остальные — это CopyCatTextureView, вы можете вызвать setTextureViewToCopy(TextureView) для каждого из копирующих котов, чтобы указать на одиночный TextureView, а затем просто вызвать invalidate() для каждого из копирующих котов всякий раз, когда вы хотите обновить кадр. Очевидно, что это не идеально, но это быстро и определенно сработает, если вам нужен только один кадр.

Надеюсь это поможет. Удачи.

(переменная отредактирована)

person DanielLaneDC    schedule 25.02.2017
comment
Я не верю, что это сработает. TextureView рисуется не так, как обычные View, и я думаю, что в любом случае получается onDraw() final, IIRC. - person Mike M.; 25.02.2017
comment
Вы правы, это окончательно. Дай мне посмотреть, что я могу сделать. - person DanielLaneDC; 25.02.2017
comment
Сначала я пытался это сделать именно так, а потом понял, что onDraw() — это просто муляж и что все рисование делается в OpenGL. Я также пробовал аналогичный подход, подобный предложенному вами взлому, но безуспешно, я получаю только черную рамку в своем пользовательском представлении. Мне было интересно, может ли кто-нибудь, кто работал с картонными приложениями или OpenGL на Android, дать мне некоторое представление об этой проблеме. Спасибо DanielLaneDC за попытку! - person Hey'Youssef; 25.02.2017
comment
Не беспокойтесь, Эй'Юссеф. Для справки, я смог скопировать TextureView в пользовательское представление, которое я разместил, я не стал черным, но мне пришлось бы самому управлять частотой кадров. Я буду с нетерпением ждать, что скажет кто-нибудь с опытом работы с OpenGL! - person DanielLaneDC; 26.02.2017
comment
не работает. даже несмотря на то, что textureViewToCopy.draw(canvas); называется текстура остается пустой. Я полагаю, что даже если бы он мог работать, производительность была бы крайне низкой (конечно, в зависимости от разрешения). В любом случае спасибо за ответ - person vir us; 09.06.2018