我在Android Webview中自动播放视频。 这会给慢速互联网连接带来问题。我得到ANR弹出窗口(应用程序没有响应)
我认为这是因为视频在加载数据之前收到了video.play()。 5秒后,ANR弹出窗口出现。
我想要解决的问题是,在调用video.play()之前等待视频完全加载。
问题是Webview中的视频没有收到视频.readystate == 4.它永远不会像准备状态那样进一步扩展2.即使在正常的互联网连接上也是如此。 在我的Chrome浏览器中,它确实收到了状态清单4.那么为什么呢?为什么Webview中的视频没有收到readystate 4?
在我的代码下面:
<!DOCTYPE html>
<html>
<head>
<title>Video</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div id="item" class="item">
<video preload="auto" autobuffer width="1024" height="576" id="video">
<source id="videomp4" src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type='video/mp4' />
</video>
<script>
var interval;
$(document).ready(function () {
interval = setInterval('playVideoWhenReady()', 1000);
/*
// this doesn't work either
video.addEventListener('loadeddata', function() {
// Video is loaded and can be played
console.log("video play is triggered");
video.play();
}, false);
*/
});
function playVideoWhenReady() {
var video = document.getElementById('video');
console.log("!!!!! curstate: " + video.readyState);
if ( video.readyState == 4 ) { // this is never true in Android Webview
video.play();
clearInterval(interval);
}
}
</script>
</div>
</body>
</html>
MainActivity:
package net.eyefinder.www.testvideo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = (WebView) findViewById(R.id.activity_main_webview);
final WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setMediaPlaybackRequiresUserGesture(false);
settings.setUseWideViewPort(true);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("file:///android_asset/video.html");
}
}
这就是清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.eyefinder.www.testvideo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:hardwareAccelerated="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
然后日志输出为:
10-31 10:55:37.369 2181-2195/net.myapp.www.testvideo D/MediaPlayerPrivateAndroid: load url=http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4
10-31 10:55:37.389 2181-2181/net.myapp.www.testvideo D/TilesManager: Starting TG #0, 0x67360d10
10-31 10:55:37.399 2181-2181/net.myapp.www.testvideo D/TilesManager: new EGLContext from framework: 63c6cd40
10-31 10:55:37.399 2181-2181/net.myapp.www.testvideo D/GLWebViewState: Reinit shader
10-31 10:55:37.429 2181-2181/net.myapp.www.testvideo D/GLWebViewState: Reinit transferQueue
10-31 10:55:37.449 2181-2181/net.myapp.www.testvideo D/VideoLayerManager: Reinit GLResource for VideoLayer
10-31 10:55:38.439 2181-2181/net.myapp.www.testvideo I/Web Console: !!!!! curstate: 2 at ../video.html:23
10-31 10:55:39.379 2181-2181/net.myapp.www.testvideo I/Web Console: !!!!! curstate: 2 at ../video.html:23
10-31 10:55:40.379 2181-2181/net.myapp.www.testvideo I/Web Console: !!!!! curstate: 2 at ../video.html:23
并且它一直悬挂在第二阶段
答案 0 :(得分:1)
它通过以下配置为我工作:
WebView webView = (WebView) findViewById(R.id.webview);
final WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setMediaPlaybackRequiresUserGesture(false);
webView.setWebChromeClient(new WebChromeClient());
webView.loadUrl("file:///android_asset/video.html");
在src/main/assets/video.html
:
<!DOCTYPE html>
<html>
<head>
<title>Video</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<video preload="auto" autoplay="autoplay" autobuffer width="1024" height="576" id="video" />
<script>
var video = document.getElementById('video');
video.src = 'http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4';
video.load();
video.addEventListener('loadeddata', function() {
video.play();
}, false);
</script>
</body>
</html>
在清单中获得Internet权限:
<uses-permission android:name="android.permission.INTERNET" />
答案 1 :(得分:0)
经过一些研究后,我得出的结论是,在Android视频完全加载到Android Webview之前,没有正确的方法等待视频。
当然,有一些解决方案,如:
<video preload="auto" autobuffer width="1024" height="576" id="video"></video>
<script>
var interval;
$(function () {
var video = document.getElementById('video');
var req = new XMLHttpRequest();
req.open('GET', 'http://your-video-url.mp4', true);
req.responseType = 'blob';
req.onload = function() {
// Onload is triggered even on 404
// so we need to check the status code
if (this.status === 200) {
var videoBlob = req.response;
var vid = (window.URL || window.webkitURL || window || {}).createObjectURL(videoBlob); // IE10+
// Video is now downloaded
// and we can set it as source on the video element
video.src = vid;
video.load();
}
}
req.onerror = function() {
// Error
}
req.send();
video.addEventListener('progress', function() {
var range = 0;
var bf = this.buffered;
var time = this.currentTime;
while(!(bf.start(range) <= time && time <= bf.end(range))) {
range += 1;
}
var loadStartPercentage = bf.start(range) / this.duration;
var loadEndPercentage = bf.end(range) / this.duration;
var loadPercentage = loadEndPercentage - loadStartPercentage;
console.log("time: " + time);
console.log("loadStartPercentage: " + loadStartPercentage);
console.log("loadEndPercentage: " + loadEndPercentage);
console.log("loadPercentage: " + loadPercentage);
if ( loadPercentage == 1 ) {
video.play();
}
});
});
但此解决方案不适用于Android 4.2(关于Why can't my Android device play HTML5 video loaded as Blob via XHR?)。
所以我在Android中实现了一个视频下载器,并将本地文件URL解析为JavaScript。现在无需等待视频加载。
我的慢连接问题现在已经解决了!