Чистая SurfaceTexture с черным прямоугольником

Я использую Exoplayer и GL SurfaceTexture (из TextureView) для отображения видео. Я повторно использую ту же самую поверхность среди воспроизведения видео.

Я отпускаю плеер и создаю новый экземпляр. Когда SurfaceTexture отображается во второй раз, она отображает старую текстуру из последнего видео до тех пор, пока игрок не начнет играть, и заполнит поверхность черным.

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

4 ответа

Решение

Используя ссылку @fadden на Grafika, я создал собственный скрипт для очистки поверхности. Это совместимо с API 16.

СУТЬ

/**
 * Clear the given surface Texture by attaching a GL context and clearing the surface.
 * @param texture a valid SurfaceTexture
 */
private void clearSurface(SurfaceTexture texture) {
    if(texture == null){
        return;
    }

    EGL10 egl = (EGL10) EGLContext.getEGL();
    EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    egl.eglInitialize(display, null);

    int[] attribList = {
            EGL10.EGL_RED_SIZE, 8,
            EGL10.EGL_GREEN_SIZE, 8,
            EGL10.EGL_BLUE_SIZE, 8,
            EGL10.EGL_ALPHA_SIZE, 8,
            EGL10.EGL_RENDERABLE_TYPE, EGL10.EGL_WINDOW_BIT,
            EGL10.EGL_NONE, 0,      // placeholder for recordable [@-3]
            EGL10.EGL_NONE
    };
    EGLConfig[] configs = new EGLConfig[1];
    int[] numConfigs = new int[1];
    egl.eglChooseConfig(display, attribList, configs, configs.length, numConfigs);
    EGLConfig config = configs[0];
    EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, new int[]{
            12440, 2,
            EGL10.EGL_NONE
    });
    EGLSurface eglSurface = egl.eglCreateWindowSurface(display, config, texture,
            new int[]{
                    EGL10.EGL_NONE
            });

    egl.eglMakeCurrent(display, eglSurface, eglSurface, context);
    GLES20.glClearColor(0, 0, 0, 1);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    egl.eglSwapBuffers(display, eglSurface);
    egl.eglDestroySurface(display, eglSurface);
    egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
            EGL10.EGL_NO_CONTEXT);
    egl.eglDestroyContext(display, context);
    egl.eglTerminate(display);
}

Я не знаком с Exoplayer, но я подозреваю, что ваши варианты такие же, как для воспроизведения с MediaPlayer, перечисленные в этом ответе.

Резюме:

  • Вы можете прикрепить GLES, очистить поверхность, отсоединить GLES ( это делает Графика).
  • Вы можете создать однокадровое черное видео и воспроизвести его.
  • Вы можете создать второй, пустой вид, который перекрывает первый. Скройте его во время воспроизведения видео и покажите, когда оно будет готово.

То, что вы не можете сделать, это прикрепить холст и очистить его, потому что, как только холст присоединен, он никогда не отпускает.

Супер пример кода

Определенно работает для очистки SurfaceView, используется следующим образом:

      if (player != null) {
                player.stop();
                player.release();
            }

    if (binding.surfaceView.getHolder().getSurface().isValid()) {
                try {
                    clearSurface(binding.surfaceView);
                }catch (RuntimeException re){
                    re.printStackTrace();
                }
            }

Пожалуйста позвони GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

прежде чем рисовать новый кадр

Другие вопросы по тегам