Embed Youtube video inside an Android app - android

I'm using a WebView for displaying embedded Youtube video and that works on Galaxcy S2 (OS 2.3.5) and doesn't on Nexus S (OS 2.3.4), all I get is white screen without any video display.
Here is the code snippet I'm using and the declarations in Manifest file:
private WebView wv;
private void setWebView()
{
wv = (WebView) findViewById(R.id.webView);
wv.setWebChromeClient(new WebChromeClient());
wv.getSettings().setPluginState(WebSettings.PluginState.ON);
wv.setWebViewClient(new WebViewClient());
wv.getSettings();
wv.setBackgroundColor(0x00000000);
wv.setKeepScreenOn(true);
wv.setHorizontalScrollBarEnabled(false);
wv.setVerticalScrollBarEnabled(false);
wv.getSettings().setBuiltInZoomControls(true);
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = getHTML();
wv.loadDataWithBaseURL("", html, mimeType, encoding, "");
}
public String getHTML()
{
String html = "<html>"
+ "<head>"
+ "</head>"
+ "<body style=\"border: 0; padding: 0\">"
+ "<iframe "
+ "type=\"text/html\" "
+ "class=\"youtube-player\" "
+ "width= 100%\""
+ "\" "
+ "height= 95%\""
+ "\" "
+ "src=\"http://www.youtube.com/v/"
+ selected_video
+ "?controls=0&showinfo=0&showsearch=0&modestbranding=0" +
"&autoplay=1&fs=1&vq=hd720\" " + "frameborder=\"0\"></iframe>"
+ "</body>"
+ "</html>";
return html;
}
Note: the parameter "selected_video" is the hash of the video (VideoID).
The declarations in Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=http://schemas.android.com/apk/res/android
.
.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
.
.
android:hardwareAccelerated="true" >
.
.
Please let me know in case you recognizing anything I should change in my code, or help with a complete code which can support all Android devices and OS for displaying embedded (In-App) Youtube video with high quality.
UPDATE:
Pay attention, the solution I'm looking for should display high resolution video. I got it work on the different devices and OS using VideoView class but the video quality isn't good enough. So any solution including VideoView or WebView or any other way will be accepted only if it makes high quality YouTube video to be displayed. Thanks to all the responders!

there is an official YouTube Android Player API wich you can use. This is a bit more complicated but it is working better than other solutions using webclients.
First you must register your app in Googles API Console. This is completely free until your app gets over 25k request a month (or something like that). There are complete anf great tutorials under the link. I hope you can understand them. If not, ask! :)

How it looks:
Best solution to my case. I need video fit web view size.
Use embed youtube link with your video id.
Example:
WebView youtubeWebView; //todo find or bind web view
String myVideoYoutubeId = "-bvXmLR3Ozc";
outubeWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
});
WebSettings webSettings = youtubeWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
youtubeWebView.loadUrl("https://www.youtube.com/embed/" + myVideoYoutubeId);
Web view xml code
<WebView
android:id="#+id/youtube_web_view"
android:layout_width="match_parent"
android:layout_height="200dp"/>

although I suggest to use youtube api or call new intent and make the system handle it (i.e. youtube app), here some code that can help you, it has a call to an hidden method because you can't pause and resume webview
import java.lang.reflect.Method;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.app.Activity;
#SuppressLint("SetJavaScriptEnabled")
public class MultimediaPlayer extends Activity
{
private WebView mWebView;
private boolean mIsPaused = false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
String media_url = VIDEO_URL;
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebChromeClient(new WebChromeClient());
WebSettings ws = mWebView.getSettings();
ws.setBuiltInZoomControls(true);
ws.setJavaScriptEnabled(true);
mIsPaused = true;
resumeBrowser();
mWebView.loadUrl(media_url);
}
#Override
protected void onPause()
{
pauseBrowser();
super.onPause();
}
#Override
protected void onResume()
{
resumeBrowser();
super.onResume();
}
private void pauseBrowser()
{
if (!mIsPaused)
{
// pause flash and javascript etc
callHiddenWebViewMethod(mWebView, "onPause");
mWebView.pauseTimers();
mIsPaused = true;
}
}
private void resumeBrowser()
{
if (mIsPaused)
{
// resume flash and javascript etc
callHiddenWebViewMethod(mWebView, "onResume");
mWebView.resumeTimers();
mIsPaused = false;
}
}
private void callHiddenWebViewMethod(final WebView wv, final String name)
{
try
{
final Method method = WebView.class.getMethod(name);
method.invoke(mWebView);
} catch (final Exception e)
{}
}
}

It works like this:
String item = "http://www.youtube.com/embed/";
String ss = "your url";
ss = ss.substring(ss.indexOf("v=") + 2);
item += ss;
DisplayMetrics metrics = getResources().getDisplayMetrics();
int w1 = (int) (metrics.widthPixels / metrics.density), h1 = w1 * 3 / 5;
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebChromeClient(chromeClient);
wv.getSettings().setPluginsEnabled(true);
try {
wv.loadData(
"<html><body><iframe class=\"youtube-player\" type=\"text/html5\" width=\""
+ (w1 - 20)
+ "\" height=\""
+ h1
+ "\" src=\""
+ item
+ "\" frameborder=\"0\"\"allowfullscreen\"></iframe></body></html>",
"text/html5", "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
private WebChromeClient chromeClient = new WebChromeClient() {
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
if (view instanceof FrameLayout) {
FrameLayout frame = (FrameLayout) view;
if (frame.getFocusedChild() instanceof VideoView) {
VideoView video = (VideoView) frame.getFocusedChild();
frame.removeView(video);
video.start();
}
}
}
};

Embedding the YouTube player in Android is very simple & it hardly takes you 10 minutes,
1) Enable YouTube API from Google API console
2) Download YouTube player Jar file
3) Start using it in Your app
Here are the detailed steps http://www.feelzdroid.com/2017/01/embed-youtube-video-player-android-app-example.html.
Just refer it & if you face any problem, let me know, ill help you

The video quality depends upon the Connection speed using API
alternatively for other than API means without YouTube app you can follow this link

Refer to this answer: How can we play YouTube embeded code in an Android application using webview?
It uses WebViews and loads an iframe in it... and yes it works.

Pretty simple: Just put it inside a static method.
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(linkYouTube)));

Use this Youtube Embed API from google.

Related

How to load only html(not load css,png,ico etc) in android webview?

I'm trying to develop android app using webview and JavaScriptInterface like this.
private static final String ENTRY_URL = "https://www.google.com";
mWebView.setWebViewClient(new WebViewClient() {
...
#Override
public void onPageFinished(WebView view, String url) {
if (url.equals(ENTRY_URL)) {
String keyword = "tistory";
String script = "javascript:function afterLoad() {"
+ "document.getElementById('keyword').value = '" + keyword + "';"
+ "document.forms[0].setAttribute('onsubmit', 'window.Zeany.justDoIt(elements[0].value); return true;');"
+ "};"
+ "afterLoad();";
view.loadUrl(script);
}
}
}
when I call method (mwebview.load("https://www.google.com")), I want to load only html file. Beacuse of Download Speed
I need only html, not css,png. when download all resources, webview load speed is too slow.
I really want to get only html. How to I achieve this goal?
Using this code you should be able to do that.
WebSettings settings = webview.getSettings();
settings.setBlockNetworkLoads(true);
settings.setBlockNetworkImage(true);
settings.setJavaScriptEnabled(false);

Get HTML Code from WebSite and remove unnecessary Code - Only display the Table in WebView

I am trying to get my app to sync itself with a website, and display only the table of a website. Example: Normal HTML framework, and the table is inside a div#table, so I did it pretty simple and built the HTML Framework:
String html = "<html> " +
"<head>" +
"</head>" +
"<body style=\"background-color: transparent\">" +
"?body" +
"</body>" +
"</html>";
And then I tried to replace the ?body with the table, but here's my problem: I have no clue how to do that and then load it into a transparent WebView. I found a little bit code online, and tried to get it working for my case, so here's that:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
List<String> links = new ArrayList();
setContentView(SliderCreator.createSlider(R.layout.activity_news, this));
wv = (WebView) findViewById(R.id.newsWebView);
wv.setBackgroundColor(Color.TRANSPARENT);
try {
String finalHTML = getIntent().getStringExtra("html");
if (!finalHTML.contains("<html>")) {
String css = "";
for(String link : links) {
css+=Utils.getHTML(link);
}
finalHTML = html.replace("?body", getIntent().getStringExtra("html")).replace("?css", css);
}
wv.getSettings().setJavaScriptEnabled(true);
//open URLs in external Browser
wv.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
}
});
wv.loadDataWithBaseURL("", finalHTML, "text/html", "UTF-8", "");
} catch(Exception e) {
Toast.makeText(this, "An error occured...", Toast.LENGTH_LONG).show();
}
But that doesn't work.. Can somebody help me out get that working for me?
(Btw.: I tried it with RegEx, didn't work, I tried it with JSoup, didn't work either...)
try using HTML Agility Pack if not working with RegEx
Please note, your RegEx might not work the desired way if the text contains nested table tags

Loading Youtube video through iframe in Android webview

I want to load youtube video to Android webview using iframe
here is my layout Xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/white"
android:id="#+id/mainLayout">
<WebView
android:background="#android:color/white"
android:id="#+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
My code is:
public class WebTube extends Activity {
private WebView wv;
String html = "<iframe class=\"youtube-player\" style=\"border: 0; width: 100%; height: 95%; padding:0px; margin:0px\" id=\"ytplayer\" type=\"text/html\" src=\"http://www.youtube.com/embed/WBYnk3zR0os"
+ "?fs=0\" frameborder=\"0\">\n"
+ "</iframe>";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv = (WebView)findViewById(R.id.webView);
wv.getSettings().setJavaScriptEnabled(true);
wv.loadDataWithBaseURL("", html , "text/html", "UTF-8", "");
}
}
Also I provide <uses-permission android:name="android.permission.INTERNET"/>
& android:hardwareAccelerated="true"
when I run this I didn't get any result its just showing a black screen
I tried this .but this provide me video on .3gp Quality . but I need the videos from youtube on original quality. That's why I am using iframe.
I try code using <object></object> and <video></video> instead of iframe. but it didn't solve my issue.
when I run this code on emulator it shows
Before Pressing Play Button
After Pressing Play button on video
I think we cannot stream videos on emulator since it is a virtual device
But when I run this on phone it's not even showing this result.
I try iframe with a document attach to it works fine on phone as well as emulator
String customHtml = "<iframe src='http://docs.google.com/viewer?url=http://www.iasted.org/conferences/formatting/presentations-tips.ppt&embedded=true' width='100%' height='100%' style='border: none;'></iframe>";
So please help me to load videos to this frame.
(I run it on phone). What's the problem?
also will iframe work on Android 2.1?
did any one tried Youtube Api ?
I have full customized ifram for youtube view
public class Act_VideoPlayer extends Activity {
WebView webView;
ProgressBar progressBar;
ImageView back_btn;
String video_url = "KK9bwTlAvgo", html = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_screen_youtube_video_screen);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
back_btn = (ImageView) findViewById(R.id.full_videoview_btn);
back_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
webView.loadData("", "text/html", "UTF-8");
finish();
}
});
webView = (WebView) findViewById(R.id.webView);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
if (video_url.equalsIgnoreCase("")) {
finish();
return;
}
WebSettings ws = webView.getSettings();
ws.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
ws.setPluginState(WebSettings.PluginState.ON);
ws.setJavaScriptEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.reload();
if (networkUtil.isConnectingToInternet(Act_VideoPlayer.this)) {
html = getHTML(video_url);
} else {
html = "" + getResources().getString(R.string.The_internet_connection_appears_to_be_offline);
CustomToast.animRedTextMethod(Act_VideoPlayer.this, getResources().getString(R.string.The_internet_connection_appears_to_be_offline));
}
webView.loadData(html, "text/html", "UTF-8");
WebClientClass webViewClient = new WebClientClass(progressBar);
webView.setWebViewClient(webViewClient);
WebChromeClient webChromeClient = new WebChromeClient();
webView.setWebChromeClient(webChromeClient);
}
#Override
protected void onDestroy() {
super.onDestroy();
try {
webView.loadData("", "text/html", "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
try {
webView.loadData("", "text/html", "UTF-8");
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
public class WebClientClass extends WebViewClient {
ProgressBar ProgressBar = null;
WebClientClass(ProgressBar progressBar) {
ProgressBar = progressBar;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
ProgressBar.setVisibility(View.VISIBLE);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
ProgressBar.setVisibility(View.GONE);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
LogShowHide.LogShowHideMethod("webview-click :", "" + url.toString());
view.loadUrl(getHTML(video_url));
return true;
}
}
public String getHTML(String videoId) {
String html = "<iframe class=\"youtube-player\" " + "style=\"border: 0; width: 100%; height: 96%;"
+ "padding:0px; margin:0px\" " + "id=\"ytplayer\" type=\"text/html\" "
+ "src=\"http://www.youtube.com/embed/" + videoId
+ "?&theme=dark&autohide=2&modestbranding=1&showinfo=0&autoplay=1\fs=0\" frameborder=\"0\" "
+ "allowfullscreen autobuffer " + "controls onclick=\"this.play()\">\n" + "</iframe>\n";
LogShowHide.LogShowHideMethod("video-id from html url= ", "" + html);
return html;
}
}
As stated in the android Webview documentation,
HTML5 Video support
In order to support inline HTML5 video in your application, you need to have hardware acceleration turned on, and set a WebChromeClient.
For full screen support, implementations of onShowCustomView(View, WebChromeClient.CustomViewCallback) and onHideCustomView() are required, getVideoLoadingProgressView() is optional.
This worked for me:
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
String frameVideo = "<html><body>Youtube video .. <br> <iframe width=\"320\" height=\"315\" src=\"https://www.youtube.com/\" frameborder=\"0\" allowfullscreen></iframe></body></html>";
mWebView.loadData(frameVideo, "text/html", "utf-8");
mWebView.loadUrl("http://www.youtube.com/");
mWebView.setWebViewClient(new WebViewClient());
Try this its working fine..
mWebView = (WebView) findViewById(R.id.web);
String videoURL = "https://www.youtube.com/embed/R52bof3tvZs";
String vid = "<html><body style=\"margin: 0; padding: 0\"><iframe width=\"100%\" height=\"100%\" src=\""+videoURL+"\" type=\"text/html\" frameborder=\"0\"></iframe><body><html>";
WebChromeClient mWebChromeClient = new WebChromeClient(){
public void onProgressChanged(WebView view, int newProgress) {
}
};
mWebView.getSettings().setPluginState(WebSettings.PluginState.ON);
mWebView.setWebChromeClient(mWebChromeClient);
mWebView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
mWebView.loadUrl("javascript:(function() { document.getElementsByTagName('video')[0].play(); })()");
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.setInitialScale(1);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
if (Build.VERSION.SDK_INT < 17) {
Log.i("GPSNETWORK", "<17");
} else {
Log.i("GPSNETWORK", Build.VERSION.SDK_INT+">=17");
mWebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
}
String myUrl = "<html><body style='margin:0px;padding:0px;'>\n" +
" <script type='text/javascript' src='http://www.youtube.com/iframe_api'></script><script type='text/javascript'>\n" +
" var player;\n" +
" function onYouTubeIframeAPIReady()\n" +
" {player=new YT.Player('playerId',{events:{onReady:onPlayerReady}})}\n" +
" function onPlayerReady(event){player.mute();player.setVolume(0);player.playVideo();}\n" +
" </script>\n" +
" <iframe id='playerId' type='text/html' width='1280' height='720'\n" +
" src=\""+videoURL+"\"?enablejsapi=1&rel=0&playsinline=1&autoplay=1&showinfo=0&autohide=1&controls=0&modestbranding=1' frameborder='0'>\n" +
" </body></html>";
mWebView.loadData(""+Html.fromHtml(myUrl), "text/html", "UTF-8");
I'm no expert in Android webview, but I encountered similar problems with web page.
What I had to do was to use tag and made sure it had onclick="this.play(); in the tag. The onclick event was specifically for Android. Chrome, Safari, Firefox didn't need it.
For example:
<video id="video" width="320" height="240" autobuffer controls onclick="this.play();">
Without the onclick, Android browser would not work. Since webview is calling the browser, I suspect it's the same.
And make sure in the source tag you do NOT use codec attribute.
Hope this helps you.
It's not exactly a direct answer to your question, but I believe you might want to use the newly released Android Youtube API. It should allow adding youtube video playback into your apps, so you don't have to inject them into a webview in an iFrame.. That's just silly, and not all Android devices will have Flash installed :)
https://developers.google.com/youtube/android/player/
You can visit my question again. Iv'e created a function that gives you all of the youtube video's direct links (including hq links). Now you can use mp4 and so instead of the poor 3gp.
Using WebChromeClient allows you to handle Javascript dialogs, favicons, titles, and the progress:
wv = setWebChromeClient(new WebChromeClient());
It's working properly
My Java file
String path="<iframe src='https://www.youtube.com/embed/94zICkZLQpY' width='100%' height='100%' style='border: none;'></iframe>";
webView.loadData(path,"text/html","utf-8");
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
Here 94zICkZLQpY is the embedded code you will get in any youtube video
My normal youtube video link which is watchable is
https://www.youtube.com/watch?v=94zICkZLQpY&feature=youtu.be

Youtube live streams in Android Webview are jittery

I am having a lot of trouble trying to play some youtube videos inside an Android Webview. I search everywhere but cannot find a solution that works.
I am using the following code:
WebView mWebView = (WebView) findViewById(R.id.webView1);
//Setup Webview
WebChromeClient client= new WebChromeClient();
mWebView.setWebChromeClient(client);
mWebView.getSettings().setPluginsEnabled(true);
mWebView.getSettings().setSupportZoom(false);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setRenderPriority(RenderPriority.HIGH);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.loadDataWithBaseURL("www.youtube.com", "<iframe class=\"youtube-player\" type=\"text/html\" width=\"640\" height=\"385\" src=\"http://www.youtube.com/embed/JEkbk-xDmZE?html5=1\" frameborder=\"0\">\n</iframe>", "text/html", "UTF-8", "");
The problem seems to be only with certain streams like this one: http://www.youtube.com/watch?v=JEkbk-xDmZE
The sound is great but the video is very slow, like 1 frame per second. unwatchable.
But if I use this stream: http://www.youtube.com/watch?v=GDFIYKmNw9Q
It works perfectly fine.
What is the difference between these live streams and how do I get the first one to play properly?
Also I should mention that sometimes the first one DOES play just fine. I am not able to figure out why it sometimes plays and other times doesn't. I've tried creating a new project with pretty much just a Webview and a Factory Reset device to eliminate any settings that may be effecting this but I still get the problem.
I've struggled with YouTube in general, trying to get it to work on android. Why certain videos lag is beyond me, but it might be different quality settings and limited bandwidth thus its buffering.
Hopefully one of the options below might help if it's not a buffering issue.
Currently, with WebView you use either use an IFrame or the YouTube API. Otherwise you can use the GData API to get the RSTP link to the video for use in a VideoView. Finally you can use an Intent to launch the YouTube app.
In the future there is a new API for Android for YouTube. But it has not been released. Theme again neither has Fragment support for Google Maps that was announced in Dec 2011. - http://www.youtube.com/watch?v=3WFsx-u-q3Y
Pros/Cons below (Examples are all making the WebView fill 100% of screen height and width)
WebView - IFrame - Limited configuration available. Runs in the WebView and works on nearly all platforms. Don't get me wrong, sometimes different options do not work, and you get a grey background when you try to play the video. Use the following site to create the IFrame code and try different options until it works for you - https://developers.google.com/youtube/youtube_player_demo (Do note several of the allowed configuration options do not work, such as hide controls has no effect). As mentioned there are lots of different options so trial and error is involved. Whilst several don't work, some look quite different. Looking at your question, i've never used the html5=1 option before, or set youtube.com as the base url.
webView = new WebView(this);
webView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
webView.getSettings().setPluginState(PluginState.ON);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webView.getSettings().setJavaScriptEnabled(true);
// Prevent scrolling of the webview
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.setHorizontalScrollBarEnabled(false);
webView.setVerticalScrollBarEnabled(false);
webView.setWebChromeClient(new WebChromeClient()); //Blank webview to prevent null pointer plugin issues
webView.setWebViewClient(new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
String data = "<html>"+
"<head>"+
"</head>"+
"<body style=\"margin: 0; padding: 0\">"+
"<iframe " +
"type=\"text/html\" "+
"class=\"youtube-player\" "+
"width=\"100%25\" "+
"height=\"100%25\" "+
"src=\"http://www.youtube.com/v/" + uri +
"?controls=0&showinfo=0&showsearch=0&modestbranding=1&fs=0\" "+
"frameborder=\"0\"></iframe>" +
"</body>"+
"</html>";
webView.loadData(data, "text/html", "utf-8");
WebView - YouTube API - Much better, but requires flash. Therefore "Nexus 7" and any future devices released with JellyBean (4.1 and above) will not work. As the WebView on those devices uses a cut down version of Chrome rather than a cut down version of WebBrowser. Therefore as I found out yesterday, going forward this can't be used on our apps.
webView = new WebView(this);
webView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
webView.getSettings().setPluginState(PluginState.ON);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webView.getSettings().setJavaScriptEnabled(true);
// Prevent scrolling of the webview
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.setHorizontalScrollBarEnabled(false);
webView.setVerticalScrollBarEnabled(false);
webView.setWebChromeClient(new WebChromeClient()); //Blank webview to prevent null pointer plugin issues
webView.setWebViewClient(new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
String data = "<!DOCTYPE HTML>" + "<html>" + "<body style=\"margin: 0; padding: 0\">"
+ "<div id=\"player\"></div>"
+ "<script>"
+
// Load player api asynchronously.
"var tag = document.createElement('script');" + "tag.src = \"http://www.youtube.com/player_api\";"
+ "var firstScriptTag = document.getElementsByTagName('script')[0];" + "firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);"
+ "var done = false;" + "var player;" + "function onYouTubePlayerAPIReady() {" + "player = new YT.Player('player', {" + "height: '100%25',"
+ "width: '100%25'," + "videoId: '"
+ uri
+ "',"
+ "playerVars: { 'controls': "
+ controls
+ ", 'showinfo': 0, 'fs':0, 'modestbranding':1 },"
+ "events: {"
+ "'onReady': onPlayerReady," + "'onStateChange': onPlayerStateChange" + "}" + "});" + "}" + "function onPlayerReady(evt) {" +
// Autoplay
"evt.target.playVideo();" + "}" + "function onPlayerStateChange(evt) {" +
"}" + "function stopVideo() {" + "player.stopVideo();" + "}" + "</script>" + "</body>" + "</html>";
webView.loadData(data, "text/html", "utf-8");
VideoView - YouTube Data API - Can get access to information and importantly links to the video streams for use in a VideoView. The draw back is the free API is limited to low quaility 3GP videos not the MP4 (high quality/HD) streams. - https://developers.google.com/youtube/getting_started#data_api
Intent - Launch YouTube - Open the YouTube app with the video you want to play. Drawback is that another app is opened, thus not embedded into your app, and that some devices don't have YouTube installed.
if (AppChecker.isAppInstalled("com.google.android.youtube", this) == true)
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + uri));
startActivity(intent);
}
else
{
//Show youtube not installed
}
//Code to check if YouTube is installed.
public class AppChecker
{
public static boolean isAppInstalled(String uri, Activity activity)
{
PackageManager pm = activity.getApplicationContext().getPackageManager();
boolean app_installed = false;
try
{
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
}
catch (PackageManager.NameNotFoundException e)
{
app_installed = false;
}
return app_installed;
}
}

Auto playing vimeo videos in Android webview

I've managed to get a vimeo video to load and play, using the following. However the autoplay=1 as indicated in the vimeo oembed docs doesn't auto play on load. Anyone found a way to auto play (also need to catch event when video finishes)
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
// how plugin is enabled change in API 8
if (Build.VERSION.SDK_INT < 8) {
mWebView.getSettings().setPluginsEnabled(true);
} else {
mWebView.getSettings().setPluginState(PluginState.ON);
}
mWebView.loadUrl("http://player.vimeo.com/video/24577973?player_id=player&autoplay=1&title=0&byline=0&portrait=0&api=1&maxheight=480&maxwidth=800");
This answer is specific to Vimeo only. After about a dozen failed attempts, here's what I have working. Perhaps it will help somebody else. A thousand apologies to the original authors of other SO answers. I have 'borrowed' a number of patterns below -- just thought it would be handy to have all this in one place, and do not claim them for my own code.
First, I have not found a way around embedding the Vimeo player (i.e. you can't get at the mp4 stream directly -- at least not easily or reliably -- I'm pretty sure that's deliberate). Second, Vimeo offers a javascript library to instrument their player, and using it is fairly unavoidable. Beware, it requires message passing, which is a newer browser feature. This is documented on their API page. Third, as is documented elsewhere on SO, you need to be very careful to wait for parts of the stack to become ready, and to not gun-jump. Fourth, the Vimeo player includes a particularly unhelpful background image meant to convey that the plugin is missing or broken (a little frame of film, common icon for this). What is really means is that your javascript has bombed out someplace, and nothing at all is running. If you see the little bit of film on a blank screen, check your javascript.
Step 1. Set up a WebView. You have this correct above. For reference, here is what I used.
mWebView = new WebView((Context) this);
mWebView.setLayoutParams(new LayoutParams(windowWidth, windowHeight));
mWebView.getSettings().setJavaScriptEnabled(true);
// Watch the sdk level here, < 12 requires 'false
// Wanted to force HTML5/264/mp4, you may want flash
// where still available
mWebView.getSettings().setPluginState(PluginState.OFF);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setUserAgentString("Android Mozilla/5.0 AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
wcc = new MyWebChromeClient();
mWebView.setWebChromeClient(wcc);
wvc = new MyWebViewClient();
mWebView.setWebViewClient(wvc);
Step 2. You need the WebChromeClient if you want video to work on the WebView. That's documented here: http://developer.android.com/reference/android/webkit/WebView.html (See HTML Video Support).
Again, for reference here is what I used.
private class MyWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView view, int progress) {
if(progress == 100) {
// Your page is loaded, but not visible,
// add whatever navigation elements you plan to use here.
// N.B. these are JAVA, not JS nav elements
}
}
#Override
public boolean onConsoleMessage(ConsoleMessage cm) {
// I like to watch in the console. And, since it was
// a very convenient way to monitor the javascript, I
// use it for that too. Purists will object, no doubt
if(cm.message().equalsIgnoreCase("EVENT -- Finish")) {
Log.i(TAG, "---> Finishing . . .");
// Depart the activity
finish();
} else {
Log.d(TAG, " **Console ["+cm.sourceId()+"] ("+cm.lineNumber()+") ["+cm.message()+"]");
}
return(true);
}
#Override
public View getVideoLoadingProgressView() {
// Something entertaining while the bytes arrive
Log.i(TAG, " -------------> Loading Progress . . . ");
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return(inflater.inflate(R.layout.loading_video, null));
}
#Override
public void onShowCustomView(View v, WebChromeClient.CustomViewCallback callback) {
// With great sadness, I report that this never fires.
// Neither does the 'hide'.
}
#Override
public void onHideCustomView() {
}
}
The WebViewClient looks like this:
private class MyWebViewClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String injection = injectPageMonitor();
if(injection != null) {
Log.d(TAG, " ---------------> Page Loaded . . .");
Log.d(TAG, " Injecting . . . ["+injection+"]");
view.loadUrl(injection);
}
}
}
Step 3. You need to build a tiny bit of Javascript to fire the player. I used this:
public String injectPageMonitor() {
return( "javascript:" +
"jQuery(document).ready( function() { " +
"console.log(' === Page Ready ===> Setting up');" +
"console.log(' ==== Sending PLAY Command ===');" +
"var froogaloop = $f('froog');" +
"setTimeout(function() { froogaloop.api('play'); }, 3000);" +
"});");
}
Quick explanation . . . I use jQuery in my JS, that's coming below. That's only for convenience, you can do straight JS if you want to lighten the load. Note that after everything else is ready, the script waits another 3 seconds to actually fire. In my weaker moments, I imagine that the kind folks at Vimeo have a broken "ready" callback. 3 Seconds seems to do it.
Step 4. You need some HTML and JavaScript on the page. I put it in a text file inside the resources (raw/vimeo_frame.html). The file looks like this:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript">jQuery.noConflict();</script>
<script src="http://a.vimeocdn.com/js/froogaloop2.min.js"></script>
<script type="text/javascript">
jQuery(document).ready( function() {
var showing_player = false;
var froogaloop = $f('froog');
console.log(' === Page Ready ===> Setting up');
jQuery('.froog_container_class').hide();
jQuery('.console').css('height', '100%');
froogaloop.addEvent('ready', function() {
console.log('==== PLAYER READY ====> Setting Play Callback');
froogaloop.addEvent('play', function(data) {
console.log('EVENT -- Play');
/* No idea why, but if the player isn't displayed, it goes
straight to 'pause'. Probably a feature. So I give it 4x4px
to do it's thing during setup */
jQuery('.froog_container_class').show();
jQuery('.froog_container_class').css('height', '4px');
jQuery('.froog_container_class').css('width', '4px');
jQuery('.froog_container_class').css('overflow', 'hidden');
});
/* I don't want to reveal the video until it is actually
playing. So I do that here */
var showingPlayer = false;
froogaloop.addEvent('playProgress', function(data) {
if(!showingPlayer && data.percent > 0) {
showingPlayer = true;
jQuery('.froog_container_class').show();
jQuery('.froog_container_class').css('height', '_windowHeight');
jQuery('.froog_container_class').css('width', '_windowWidth');
/* Most tablets I tested aren't quick enough to make this work
but one can still hope */
jQuery('#loading').fadeOut('slow');
}
});
});
});
</script>
</head>
<body>
<style>
body {
background-image: url('http://<SomethingEntertainingToWatch>.png');
background-size: contain;
}
.mask {
float: left;
height: _windowHeight;
width: _windowWidth;
z-index: 100;
background: transparent;
display: inline;
position: absolute;
top: 0;
left: 0;
}
.froog_container_class {
position: absolute;
height: _windowHeight;
width: _windowWidth;
left: 0;
top: 0;
display: inline;
z-index: 1;
}
#froog {
display: inline;
height: _windowHeight;
width: _windowWidth;
postion: absolute;
top: 0;
left: 0;
}
</style>
<div id="loading" class="loading"><h1>Loading</h1><img class="loading_anim" src="http://foo.bar.com/assets/global/loading.gif"/>
</div>
<!-- Completely optional, I put a div in front of the player to block controls -->
<div id="mask" class="mask">
</div>
<div id="froog_container" class="froog_container_class">
<iframe id="froog" src="_targetUrl?api=1&title=0&byline=0&portrait=0&player_id=froog" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
</iframe>
</div>
</body>
</html>
And I load this html file like so:
public String genMainHTML() {
String code = null;
try {
Resources res = getResources();
InputStream in_s = res.openRawResource(R.raw.vimeo_frame);
byte[] b = new byte[in_s.available()];
in_s.read(b);
code = new String(b);
} catch (Exception e) {
e.printStackTrace();
}
if(code != null) {
code = code.replaceAll("_windowHeight", "" + windowHeight + "px");
code = code.replaceAll("_windowWidth", "" + windowWidth + "px");
code = code.replaceAll("_targetUrl", targetUrl);
return(code);
} else {
return(null);
}
}
And inject it like so:
mDomain = "http://player.vimeo.com";
mWebView.requestFocus(View.FOCUS_DOWN);
targetUrl = extras.getString("URL");
String meat = genMainHTML();
mWebView.loadDataWithBaseURL(mDomain, meat, "text/html", "utf-8", null);
setContentView(mWebView);
Whew! When the WebView is ready, then the html and js go in, including the iframe with the Vimeo player. When the document is loaded, then we wait for the player to become ready. When the player is ready, we add some listeners. And 3 seconds later, we fire the api 'play' method.
Those apple-polishers in the audience may be wondering, for completeness, how does one stop the video? Two bits. First, when it ends, I stop it by watching the console output for a message I display. Thus:
public String injectPageFinisher() {
return( "javascript:" +
"jQuery(document).ready( function() { " +
"console.log(' === Page Ready ===> Tearing down');" +
"console.log(' ==== Sending PAUSE Command ===');" +
"var froogaloop = $f('froog');" +
"froogaloop.api('pause');" +
"jQuery('#froog_container').html('');" +
"});");
}
Which can be inserted like so:
#Override
public void onPause() {
super.onPause();
if(isFinishing()){
// Unload the page
if(mWebView != null) {
Log.i(TAG, " ------> Destroying WebView");
mWebView.destroy();
}
}
finish();
}
The second bit is where the video completes its little self. Thus, in the vimeo_frame.html above, just after the 'play' callback, I put:
froogaloop.addEvent('finish', function(data) {
console.log('EVENT -- Finish');
});
And in the Activity, I put a bit to watch for this -- see above in the onConsoleMessage override.
HOWEVER -- as of this writing, I still have not sorted one nagging problem. The MediaPlayer lives on after the WebView and all its progeny are gone. I'm sure this creates some problems, but I haven't identified them yet.
We've come across the same issue and it seems that Android WebView's (as well as those on iOS) are not programmed to allow auto-start of videos since it's possible that it would eat into someones data plan. You have to actually tap on it unless you want to take Google's WebView as a starting point and roll your own. It's not as easy as it sounds, we tried!
Here is the Simple Solution
Step1- Ensure you have minSdkVersion 17
Step2- mWebView.getSettings().setMediaPlaybackRequiresUserGesture(false); Paste this line on the Vimeo Class.
I had the same issue, I think that you could use this one to make it happen:
public abstract void setMediaPlaybackRequiresUserGesture (boolean
require)
Added in API level 17 Sets whether the WebView requires a user gesture
to play media. The default is true.
Parameters require whether the WebView requires a user gesture to play
media
Hope to help you at least a little!
Hope it might help someone new to this.
Please try the below settings to your webview.
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAppCacheEnabled(true);
webSettings.setMediaPlaybackRequiresUserGesture(false);
And append autoplay=1 with your Vimeo video url
webView.loadUrl(resLink + "?autoplay=1");
Here the resLink will look like "https://player.vimeo.com/video/your_video_id"

Categories

Resources