How to get Flowplayer to automatically play in Android WebView? - android

I can't get Flowplayer to automatically play video in a WebView on Android. The video plays fine if the in-HTML play button is pressed, but it won't start by itself. This seems to be Chrome-related since autoplay doesn't work in the Android Chrome browser either. It does work in the stock Android browser and in Chrome for the (Linux) desktop.
I've seen this page that suggests adding a WEBM file to get MP4 content to work, but it didn't help. I've also seen this page that mentions using the new setting setMediaPlaybackRequiresUserGesture(), but that didn't help either.
Has anyone gotten autoplay to work in an Android WebView?
Here is my test code that distills the app down to its essentials.
package com.example.testautovideo;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
#SuppressLint("SetJavaScriptEnabled")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webview = new WebView(this);
setContentView(webview);
webview.setWebChromeClient(new WebChromeClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setLoadsImagesAutomatically(true);
// webview.getSettings().setMediaPlaybackRequiresUserGesture(false); // didn't help
webview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
webview.loadUrl(THE_URL);
}
}
Here is the source of my web page. The Flowplayer and jQuery calls are to standard installs. The Flowplayer library is the latest free version; the jQuery library is the latest production version.
<!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">
<meta property="ws:skip" value="false" />
<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>
$(document).ready(function(){
function playVideo(){
var player = flowplayer($('#theVideo'));
player.play();
}
setTimeout(playVideo,10);
});
</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" id="theVideo">
<video preload="none" autoplay>
<source type="video/webm" src="video_1.webm">
<source type="video/mp4" src="video_1.mp4">
</video>
</div>
</div>
</body>
</html>
I know links can go stale, but here's a copy of that web page with working Flowplayer and jQuery installs.

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>

You will definitely need to call setMediaPlaybackRequiresUserGesture(false) to get this to work. I can't see a problem with your HTML right away, does it work if you use javascript to call play() on the video element from an onload handler, say?
It's intended behavior that Chrome for Android does not support autoplay. But it should work in WebView when setMediaPlaybackRequiresUserGesture is false.

I wasn't able to get it working even with setMediaPlaybackRequiresUserGesture.
So what I did was a simple javascript call to the webpage.
public void triggerPlayVideo()
{
activity.runOnUiThread(new Runnable() {
#Override
public void run()
{
webView.loadUrl("javascript:playVideo()");
}
}
); }
This method is triggered once i receive an event from webview that the page got loaded/Video got loaded.

Related

Android webview click button using jquery

I am loading some website in my android application using WebView and what I just want to do is after loading the page I want to automatically click the <button> with data-stage="premium"
here is my html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="switch-stage">
<div>
<button data-stage="normal">Normal</button>
</div>
<div>
<button data-stage="premium">Premium</button>
</div>
</div>
<script src="/js/jquery-3.3.1.min.js"></script>
<script>
$('#switch-stage button').on('click', function() {
var stage = $(this).data('stage');
});
</script>
</body>
</html>
This is what I've done in android.
webView.loadUrl("javascript:document.getElementById(\"switch-stage button\").click(\"premium\");");
but I think my loadUrl is not correct. (This is what I am seeing in different link that I've searched.)
Is it possible to do what I am asking, to automatically click the button so that the var stage will have a data.?
I hope someone will help, Thanks.
Try this:
public void onPageFinished(WebView view, String url)
{
// hide element by id LECLERC
view.loadUrl("javascript:(function() { " +
"document.getElementsById('Premium').click();"
//document.getElementById("switch-stage").children[1].click();
;})()");
}

Intel App Framework 2.2 in Android 5 webview cannot allow 'clicking' on any link

I have an Android app that is basically just a webview that loads a html page written using Intel's App Framework 2.2. It was running fine since last year. However, on my new Samsung Note 4 that is running Android 5, the app loads, shows the first panel but I was unable to navigate to any links on the page. Any one have similar problem and managed to solve it?
Below is the relevant code for my app and the html.
_wv = (WebView)findViewById(R.id.browser);
WebSettings ws = _wv.getSettings();
ws.setJavaScriptEnabled(true);
ws.setUseWideViewPort(true);
_wv.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//Log.d("SGC", "shouldOverrideUrlLoading " + url);
if (Uri.parse(url).getHost().equals(getString(R.string.app_url))) {
return false;
}
// Otherwise, give the default behavior (open in browser)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
});
_wv.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
myToast.setText("Loading... " + progress + "%");
myToast.show();
}
});
_wv.loadUrl("http://" + getString(R.string.app_url) + "/" + getString(R.string.app_url_name) + "/index.html");
Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${packageName}.${activityClass}" >
<WebView
android:id="#+id/browser"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
index.html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes" />
<script src="../js/appframework.min.js" type="text/javascript"></script>
<script src="../js/appframework.ui.min.js" type="text/javascript"></script>
<link href="../css/af.ui.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="afui">
<div id="content">
<div class="panel" id="page_main" selected="selected" data-header="header_main">
<a href=“#page_product”>Products</a>
</div>
<div class="panel" id="page_product" data-header="header_back" >
<p>Our products</p>
BACK
</div>
</div>
<header id="header_main">
<h1>Company</h1>
</header>
<header id="header_back">
<h1>Our Products</h1>
</header>
</div>
</body>
</html>
Apparently it's appframework.ui.js that is giving the problem on Android 5 webview. I've attempted many remedies on the java app as well as the html but nothing works. Eventually, I have to upgrade the Intel's App Framework to version 3 to make it work again; and it seems to work for the lower Android versions too.

Inappbrowser closing with javascript on client side

I am trying to display a webpages using in-app-browser in android platform of phone gap.
window.open() opening a url webpage which can call another html pages on to the server. I am trying to close the in-app-browser on any page (i.e., on very first loaded page or on intermediate page loaded or on the last page) by clicking a close hyperlink which calls a javascript function iabClose(event)
but the in-app-browser is not closing.
Please help me if anybody knows the solution or any other better way of closing in-app-browser.
Thanks in advance
Code:
<html>
<head>
<script type="text/javascript" charset="utf-8">
var iabRef = null;
function inApp() {
iabRef = window.open('http://202.65.155.246/Real_Time_Data /SSEClient.aspx', '_blank', 'location=no');
iabRef.addEventListener('loadstop', iabLoadStop);
iabRef.addEventListener('exit', iabClose);
}
function iabLoadStop(event) {
if(event.url == "http://202.65.155.246/Real_Time_Data/CloseIAB.aspx"){
iabRef.close();
}
}
function iabClose(event) {
iabRef.removeEventListener('loadstop', iabLoadStop);
iabRef.removeEventListener('exit', iabClose);
}
</script>
<title>Hello World</title>
</head>
<body>
Click Here </br></br>
Exit
</body>
</html>

The easiest way to play an audio RTMP stream in Android

I found some Android RTMP libraries (like this : http://rtmpdump.mplayerhq.hu/).
The problem is that there is no accurate documentation on how we can use it.
In my case, I have a simple RTMP live audio stream (ex: rtmp://myserver/myapp/myliveaudio).
What is the easiest way to read it in my Android app?
Please, I don't want links: I need some pieces of code or some accurate step-by-step explanation.
Thank you very much.
It is unfortunately non-trivially difficult to do. Right now your best bet is to look at the code in http://code.google.com/p/android-rtmp-client/: specifically look at http://code.google.com/p/android-rtmp-client/source/browse/trunk/example/com/ryong21/example/recorder/RecorderClient.java and http://code.google.com/p/android-rtmp-client/source/browse/trunk/example/com/ryong21/example/recorder/Recorder.java. These walk through taking in a streamed MP3 file and recording its contents to an FLV file on disk.
You would need to modify the RecorderClient.java file (specifically around line 193) to play the audio data out the speakers.
Not sure if this helps, but... I was able to do something similar (rtmp - streaming video) using Flash, so you need Android 2.2+ for this.
Anyway, I just wrote an HTML page displaying the flash video then opened the page in a WebView.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<style type="text/css" media="screen">
html, body{
margin:0;
padding:0;
height:100%;
}
#altContent{
width:100%;
height:100%;
}
</style>
<title>YOUR TITLE HERE!</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
var flashvars = {};
flashvars.HaloColor = "0x0086db";
flashvars.ToolTips = "true";
flashvars.AutoPlay = "true";
flashvars.VolumeLevel = "50";
flashvars.CaptionURL = "YOUR CAPTION HERE";
flashvars.Title = "YOUR TITLE HERE";
flashvars.Logo = "";
flashvars.SRC = "rtmp://YOUR STREAM URL HERE";
flashvars.BufferTime = "5";
flashvars.AutoHideControls = "false";
flashvars.IsLive = "true";
var params = {};
params.wmode = "transparent";
params.allowfullscreen = "true";
var attributes = {};
attributes.id = "L3MP";
swfobject.embedSWF("http://media-player.cdn.level3.net/flash/v1_1_1/Level3MediaPlayer.swf", "altContent", "100%", "100%", "10.1.0","http://media-player.cdn.level3.net/flash/v1_1_1/expressInstall.swf", flashvars, params, attributes);
</script>
</head>
<body>
<div id="altContent">
<center> <BR><BR><span style="color:red"><b>Please Install Adobe Flash Player</b>
</span><BR><BR>
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
</center>
</div>
</body>
</html>
</script>
</html>
OK... now just save that in your assets folder in your project
and open it with something like this in your activity :
String LocalFile = "file:///android_asset/YOUR_HTML_FILE.htm";
WebView webView = (WebView) findViewById(R.id.YOUR_WEB_VIEW);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setPluginsEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webSettings.setAllowFileAccess(true);
webView.setBackgroundColor(Color.BLACK);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
webView.loadUrl(LocalFile);
Its a bit of a work around... Hope it works for you. CDub.

Displaying Android asset files in a WebView?

I have seen various discussions on the problem of serving WebView pages from assets, none of which seemed definitive.
I want to be able to use a webview to display html (and included css) files stored in the project assets.
I have found that wv.loadUrl("file:///android_asset/html_no_copy/demo_welcome.html") displays that file okay, but links in demo_welcome.html, either local (no url prefixing the file name) or absolute - the same form as fed to loadUrl - don't work. They get a "Web page not available" error displayed on the view.
WebView wv = (WebView)this.findViewById(R.id.splashWebView);
wv.loadUrl("file:///android_asset/html_no_copy/test.html"); // Works
or
wv.loadUrl("file:///android_asset/html_no_copy/demo_welcome.html"); // Works
But neither of the following links in demo_welcome.html work:
CLICK HERE<p>
OR HERE
I know I can get around this by writing a content provider, but that seems extreme.
I want this to work from SDK 1.6 (4) on up.
Does anyone know if this can be done with just HTML, or does one need to kluge up some code to load the data?
Well, I found something that seems to work (on 1.6 and 2.2), in spite of a warning that it would recurse.
I also discovered that a css style-sheet link inside the first and second page both work without the following intercept. Odd and it makes me a bit nervous. Thoughts?
Here's the code:
WebView wv = (WebView)this.findViewById(R.id.splashWebView);
wv.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
wv.loadUrl("file:///android_asset/html_no_copy/demo_welcome.html");
Here's the file contents:
demo_welcome.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Demo Html</title>
<link rel="stylesheet" type="text/css" href="demo.css" />
</head>
<body>
<H1>Testing One Two Three</H1>
CLICK HERE<p>
OR HERE
</body>
</html>
test.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="test.css" />
<title>Insert title here</title>
</head>
<body>
<H1>TEST.HTML</H1>
</body>
</html>
instead of loadUrl, try using the loadDataWithBaseURL method:
wv.loadDataWithBaseURL("fake://not/needed", html, mimeType, encoding, "");

Categories

Resources