The following is an approach that works on all versions of Android down to Honeycomb (API 11), and perhaps earlier. The important part is to dynamically run load() and play() on the video via JavaScript. Even then, it doesn't always work on older versions of Android (with the setMediaPlaybackRequiresUserGesture()
call, which was added in API 17, removed.
The WebView refuses to let the load/play start automatically, but it will let the Android app initiate it. It's desirable for the page itself to be able to determine when the video is started, rather than the app.
Here's what was done to get it all to work. First, a guard condition was put around around the setMediaPlaybackRequiresUserGesture()
call to keep it from being run on pre-Jellybean MR1 devices. Then a small, single-method JavascriptInterface class was added and enabled. That method calls an on-page JavaScript method that loads and plays the page's video. Finally, the web pages were altered to call the exposed method when the video should be started. In the code below, the method is called when page has finished loading and the video is set to loop continuously.
Yes, there's a known security concern with enabling a JavascriptInterface class, but our's only has a single method and that method doesn't do anything other than call back into the calling JavaScipt.
The relevant parts of the app:
{
...
webView = (WebView) findViewById(id.web);
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setJavaScriptEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
webView.addJavascriptInterface(new JsInterface(), "AndroidApp");
}
class JsInterface {
@JavascriptInterface
public void startVideo() {
Log.v(TAG, "in JsInterface.startVideo()");
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v(TAG, "in JsInterface.startVideo.run");
webView.loadUrl("javascript:playVideo()");
}
});
}
}
The web page:
<!DOCTYPE HTML>
<html>
<head>
<meta name='viewport' content='width=device-width,initial-scale=1,maximum-scale=1,target-densitydpi=device-dpi'>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Autoplay Test</title>
<link rel="stylesheet" type="text/css" href="src/js/flowplayer/skin/minimalist.css">
<script type="text/javascript" src="src/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="src/js/flowplayer/flowplayer.min.js"></script>
<script type="text/javascript">
function playVideo(){
var player = flowplayer($('#theVideo'));
player.load('video_1.mp4');
player.bind("finish", function() {
player.play();
});
}
$(document).ready(function(){
AndroidApp.startVideo()
});
</script>
<style>
body {
margin:0;
padding:0;
background:#000;
}
#wrapper .flowplayer {
width:640px;
height:360px;
}
#wrapper {
width:640px;
height:360px;
background:#000;
margin:30px auto;
}
</style>
</head>
<body>
<div id="wrapper">
<div class="flowplayer is-splash" id="theVideo">
<video preload="none">
<source type="video/mp4" src="">
</video>
</div>
</div>
</body>
</html>