MediaPlayer не может отображать TextureView после рендеринга изображения

У меня есть MediaPlayer рендеринг видео в TextureView. Это работает.

Теперь я хочу отобразить неподвижное изображение на этом TextureView в течение заданного времени, а затем получить MediaPlayer для рендеринга видео на тот же TextureView.

Вот мой код для рендеринга растрового изображения:

Canvas canvas = mTextureView.lockCanvas();
canvas.drawBitmap(sourceBitmap, matrix, new Paint());
mTextureView.unlockCanvasAndPost(canvas);

После этого любые попытки воспроизвести видео приводят к срабатыванию ERROR_INVALID_OPERATION (-38) из видеоплеера.

Я попытался закомментировать вызов drawBitmap, но ошибка все равно возникла. Кажется, что простой вызов lockCanvas с последующим unlockCanvasAndPost приводит к тому, что TextureView не подходит для использования MediaPlayer.

Есть ли способ сбросить TextureView в состояние, позволяющее MediaPlayer использовать его?

Я работаю на Android 4.2.2.


person Andrew Shepherd    schedule 23.07.2014    source источник


Ответы (2)


Вы не можете сделать это из-за ограничения платформы приложения Android (по крайней мере, для Android 4.4).

SurfaceTexture, лежащий в основе TextureView, является потребителем буфера. MediaPlayer — один из примеров производителя буфера, Canvas — другой. После того, как вы присоедините производителя, вы должны отсоединить его, прежде чем вы сможете подключить второго производителя.

Проблема в том, что нет возможности отключить программный (Canvas) производитель буферов. Может быть, но нет. Итак, как только вы рисуете с помощью Canvas, вы застряли. (На этот счет есть примечание здесь.)

Вы можете отсоединить производителя GLES. Например, в одном из классов видеоплеера Grafika вы можете найти ссылку clearSurface(), который очищает поверхность до черного цвета с помощью GLES. Обратите внимание, что контекст и окно EGL создаются и явно освобождаются в рамках метода. Вместо этого вы можете расширить метод, чтобы отобразить изображение.

person fadden    schedule 23.07.2014
comment
Если у меня есть MediaPlayer в качестве производителя буфера, какой самый простой способ очистить мою поверхность до черного? - person Gilbert; 13.10.2014
comment
@Gilbert: вам, вероятно, следует опубликовать это как новый вопрос. Решения этой проблемы обычно имеют три формы: (1) заставить MediaPlayer сделать это, возможно, воспроизведя однокадровое черное видео; (2) отключите MediaPlayer, очистите его с помощью GLES, снова подключите MediaPlayer; (3) поместите перед ним непрозрачный черный вид с такими же размерами. Третий довольно прост с TextureView, так как, в отличие от SurfaceView, он хорошо сочетается с другими представлениями. - person fadden; 13.10.2014
comment
@fadden Мы можем использовать 2 способа рисования растрового изображения в SurfaceView: просто используя Canvas.drawBitmap() API и рисуя вручную с помощью opengl. Оба имеют аппаратное ускорение, но что быстрее? Я думаю, что рисование вручную с помощью opengl требует копирования памяти, мы должны сначала использовать API-интерфейсы texImage2D для загрузки растрового изображения в текстуру в GPU. - person dragonfly; 06.12.2016
comment
Последнее, что я проверял, это то, что рендеринг Canvas на Surface не ускоряется аппаратно. Если растровое изображение меняется каждый раз, когда вы его рисуете, возможно, вам лучше выполнять работу на процессоре. Если вы рисуете одно и то же растровое изображение несколько раз, лучше использовать графический процессор. - person fadden; 06.12.2016

Недавно я столкнулся с подобными проблемами. Мое намерение состояло в том, чтобы показать миниатюру видео непосредственно в TextureView, а затем использовать тот же TextureView для воспроизведения видео, не используя другой ImageView для отображения миниатюры видео.

Я реализовал второй подход в комментариях @fadden, используя EGL, чтобы нарисовать миниатюру видео в том же TextureView.

Кроме того, мы также можем использовать две текстуры в GLSurfaceView для достижения той же цели. Одна внешняя текстура OES для непрерывного воспроизведения видео и другая 2D-текстура для отображения эскиза видео.

Полную демонстрацию можно найти в этом проекте github EGLPoster.

Надеюсь, это будет полезно для тех, кто достигает здесь.

person alijandro    schedule 29.10.2016