VideoView getDrawingCache 返回黑色

Posted

技术标签:

【中文标题】VideoView getDrawingCache 返回黑色【英文标题】:VideoView getDrawingCache is returning black 【发布时间】:2011-03-11 21:44:07 【问题描述】:

所以我正在尝试制作 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);

但是,这又一次返回给我一个黑色图像。我可以看到 android javadocs 中几乎没有记录 VideoView。有什么帮助吗?

【问题讨论】:

这让我想起了过去我曾经尝试用打印屏幕和绘画在 WMP 中截取视频的时候。我认为这是一个问题,表面视图只是窗口中的一个透明层,因此无法像您尝试的那样进行快照。 【参考方案1】:

来自View#setDrawingCacheEnabled 的文档:

启用绘图缓存类似 硬件时设置层 加速被关闭。什么时候 打开硬件加速, 启用绘图缓存没有 对渲染的影响,因为系统 使用不同的机制 忽略标志的加速度。 如果您想使用位图 查看,即使在硬件加速时 已启用,请参阅 setLayerType(int, android.graphics.Paint) 为 有关如何启用软件的信息 和硬件层。

VideoView 可能使用硬件加速运行并绕过缓存机制。良好的源潜水可能会有所启发。

编辑 - this post 似乎解决了一些问题:

抱歉,SurfaceView 的本质是 不在正常视图层次结构中绘制 更新系统,所以不会被拉进来 那个。

(VideoView 是 SurfaceView 的子级)

【讨论】:

嗯。我可以看到一个视图在 javadocs 中有 setLayerType,但我的 VideoView 没有 setLayerType,View 也没有显示它使用的常量(将其设置为 View.LAYER_TYPE_SOFTWARE)。这是一堂很奇怪的课。它还在 javadocs 中说 VideoView 有一个 resume() 方法,但我的没有显示其中之一?我会继续环顾四周,可能会深入研究源头。 您可能应该将 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;

【讨论】:

我已经很久没有重温这个了,但是很高兴知道,谢谢。但是,这对我的情况没有帮助,因为我想要截屏的是流式视频。 @Arbi 谢谢,我可以用手机本地存储的视频来做到这一点。但是,当视频在 VideoView 中流式传输时,我似乎无法捕获视频帧。你知道怎么做吗? 你需要获取流媒体视频的uri 嗨@Arbi。我在 uri 参数中放置了一个示例“test.com/myVideo.mp4”,但没有成功。似乎只有在设备上下载了视频时,上面的函数 videoFrame() 才有效 您没有提供协议(我想知道您是否能够播放视频)。尝试使用new URL("you_full_url").toExternalForm() 之类的内容,以确保您提供了正确的网址,否则您会看到异常。

以上是关于VideoView getDrawingCache 返回黑色的主要内容,如果未能解决你的问题,请参考以下文章

ScrollView嵌套子View的getDrawingCache为空的解决方法

启用滚动时调用 `getDrawingCache` 返回 null

使用getDrawingCache保存视图位图会显示黑色图像

使用VideoView播放视频

Fragment 中带有 VideoView 的黑屏

如何在 Android Studio 中将一个 VideoView 放在另一个 VideoView 下方?