我想从webview中<video>
标记的流中截取屏幕截图。
我在framelayout中创建了带webview控件的简单项目。在清单中我添加了一行: 机器人:硬件加速= “真”
配置webview
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WebView.enableSlowWholeDocumentDraw();
}
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webView1);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setAppCacheMaxSize(1024 * 1024 * 5);
mWebView.getSettings().setAppCachePath(getCacheDir().getAbsolutePath());
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setDatabaseEnabled(true);
String sDataPath = getApplicationContext().getDir("databases", Context.MODE_PRIVATE).getPath();
mWebView.getSettings().setDatabasePath(sDataPath);
mWebView.getSettings().setDatabaseEnabled(true);
mWebView.setScrollBarStyle(mWebView.SCROLLBARS_OUTSIDE_OVERLAY);
mWebView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onExceededDatabaseQuota(String url,
String databaseIdentifier, long quota,
long estimatedDatabaseSize, long totalQuota,
WebStorage.QuotaUpdater quotaUpdater) {
quotaUpdater.updateQuota(5 * 1024 * 1024);
}
});
WebViewClient client = new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
...
}
};
mWebView.setWebViewClient(client);
}
@Override
protected void onResume() {
mWebView.loadUrl("file:///android_asset/video.html");
super.onResume();
}
Android测试解决方案:
1
public static Bitmap screenshot(WebView webView) {
try {
float scale = webView.getScale();
int height = (int) (webView.getContentHeight() * scale + 0.5);
Bitmap bitmap = Bitmap.createBitmap(webView.getWidth(), height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
webView.draw(canvas);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
2
public static Bitmap screenshot2(WebView webView) {
webView.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
webView.layout(0, 0, webView.getMeasuredWidth(), webView.getMeasuredHeight());
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(webView.getMeasuredWidth(),
webView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
int iHeight = bitmap.getHeight();
canvas.drawBitmap(bitmap, 0, iHeight, paint);
webView.draw(canvas);
return bitmap;
}
3
Picture picture = mWebView.capturePicture();
Bitmap b1 = Bitmap.createBitmap(picture.getWidth() / 2, picture.getHeight() / 2, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b1);
mWebView.draw(c);
4
View view = mWebView.getRootView();
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
5
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Picture picture = mWebView.capturePicture();
Bitmap b = Bitmap.createBitmap(picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
picture.draw(c);
...
我通过这种方法保存到文件的所有上述解决方案:
public static Bitmap saveBitmap(Bitmap bitmap, String filename) {
FileOutputStream fos1 = null;
try {
fos1 = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + filename);
if (fos1 != null) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos1);
fos1.close();
}
} catch (Exception e) {
}
}
使用Javascript解决方案的HTML文件:
<!DOCTYPE html>
<html>
<body>
<div id="input" width="250" height="250">
<video width="250" height="250" id="video" controls>
<source src=http://clips.vorwaerts-gmbh.de/VfE_html5.mp4 type="video/mp4">
</video>
</div>
<canvas id="canvas" width="250" height="250">
Your browser does not support the canvas element.
</canvas>
<div id="output" width="250" height="250">
<button id="snap" onclick="snap()">Snap Photo</button>
</div>
<script type='text/javascript'>
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
var w, h, ratio;
video.addEventListener('loadedmetadata', function() {
ratio = video.videoWidth / video.videoHeight;
w = video.videoWidth - 100;
h = parseInt(w / ratio, 10);
canvas.width = w;
canvas.height = h;
}, false);
function snap() {
context.fillRect(0, 0, 200, 200);
context.drawImage(video, 0, 0, w, h);
}
</script>
</body>
</html>
上述解决方案已经在8款手机上进行了测试(范围从Android 4.4到6.0),但在所有这些手机中,Android解决方案都无效。这取决于解决方案,但基本上我有一个文件,其中包含“快照”按钮,视频播放器元素和流视图中的白色屏幕。 Javascript解决方案在半数设备中工作,但没有任何与Android版本的连接。我也改变了视频类型但没有成功。
我做错了什么?