VideoView getDrawingCache возвращается черным

Итак, я пытаюсь сделать снимок экрана VideoView. Я понял, что самый простой способ:

videoView.setDrawingCacheEnabled(true);

Затем, когда мне нужно сделать снимок экрана:

Bitmap screenshot = videoView.getDrawingCache();

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

Bitmap bitmap = Bitmap.createBitmap(videoView.getWidth(), videoView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
videoView.draw(canvas);

Но снова это возвращает мне черное изображение. Я вижу, что VideoView практически не задокументирован в javadocs Android. Любая помощь?

Ответ 1

Из документов для Просмотр # setDrawingCacheEnabled:

Включение кэша чертежа аналогично для установки уровня, когда аппаратное обеспечение ускорение отключается. когда аппаратное ускорение включается, включение кэша чертежа не имеет влияние на рендеринг, поскольку система использует другой механизм для ускорение, которое игнорирует флаг. Если вы хотите использовать Bitmap для просмотра, даже если аппаратное ускорение, см. setLayerType (int, android.graphics.Paint) для информация о том, как включить программное обеспечение и аппаратные уровни.

Возможно, что VideoView работает с аппаратным ускорением и обходит механизм кэширования. Хорошее погружение источника может пролить некоторый свет.

Изменить - этот пост, кажется, очищает некоторые вещи:

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

(VideoView является дочерним элементом SurfaceView)

Ответ 2

Начиная с API 10 вы можете использовать MediaMetadataRetriever для извлечения кадра в заданное время (в микросекундах). Вот пример кода:

public Bitmap videoFrame(String uri, long msec) {       
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {                       
        retriever.setDataSource(uri);            
        return retriever.getFrameAtTime(msec);
    } catch (IllegalArgumentException ex) {
        ex.printStackTrace();
    } catch (RuntimeException ex) {
        ex.printStackTrace();
    } finally {
        try {
            retriever.release();
        } catch (RuntimeException ex) {
        }
    }
    return null;
}