Discrepancies with HTML5 video in Android WebView

When displaying .mp4 video on an HTML5 page in Android WebView, video and audio play correctly when the file is extracted from a remote URL. When you try to play the same media file from the path "/ mnt / sdcard / ...." of the device, only part of the audio file of the media file is played. Any thoughts on this? Has anyone experienced (and hopefully decided) anything like this? Could this be a codec problem even though the video is visible when retrieving over the network? Is the video transmitted over the network, managed or transformed in some way, before ending in WebView.

+4
source share
1 answer

The following code worked for me, I hope this helps you, also I think that many people are facing the same problem, so I did this to get HTML5 video to run in my WebView applications.

I will guide you through the procedure .

I wanted to load several HTML pages one by one inside my WebView application . These HTML pages contained either Audio, then video , or video, followed by Audio .

Here is an example of one of these HTML pages.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <html> <head> <title>screen2</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="css/main-v1.css" rel="stylesheet" type="text/css"> <link href="css/screen2-v1.css" rel="stylesheet" type="text/css"> <script src="js/jQueryTest.js"></script> </head> <body> <audio id="audio1" src="audio/screen2_a.mp3"></audio> <video id="video1" src="video/mov_bbb.mp4"></video> </body> </html> 

Now I have created a Class to work as an interface between Android and Javascript on HTML pages .

Here is a JavaScriptInterface class named JsHandler.java in my src folder

 package com.example.dms; import java.io.IOException; import com.example.dms.R; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.util.Log; import android.webkit.JavascriptInterface; import android.webkit.WebView; public class JsHandler { Activity activity; String TAG = "JsHandler"; WebView webView; public JsHandler(Activity _contxt,WebView _webView) { activity = _contxt; webView = _webView; } /** * This function handles call from JS */ @JavascriptInterface public void initVideo() { webView.loadUrl("javascript:playVideo()"); } public void initAudio() { webView.loadUrl("javascript:playAudio()"); } /** * This function handles call from Android-Java */ public void javaFnCall(String jsString) { final String webUrl = "javascript:diplayJavaMsg('"+jsString+"')"; // Add this to avoid android.view.windowmanager$badtokenexception unable to add window if(!activity.isFinishing()) // loadurl on UI main thread activity.runOnUiThread(new Runnable() { @Override public void run() { webView.loadUrl(webUrl); } }); } /** * function shows Android-Native Alert Dialog */ public void showDialog(String msg){ AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); alertDialog.setTitle(activity.getString(R.string.app_dialog_title)); alertDialog.setMessage(msg); alertDialog.setButton(DialogInterface.BUTTON_POSITIVE,activity.getString(R.string.ok_text), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,activity.getString(R.string.cancel_text), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); alertDialog.show(); } } 

This is the code in my MainActivity that loads an HTML page inside a WebView

 public class MainActivity extends Activity{ //WebView Variables private JsHandler _jsHandler; private WebView myWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myWebView = (WebView) findViewById(R.id.webView); myWebView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { // TODO Auto-generated method stub if(event.getAction() == MotionEvent.ACTION_DOWN && !view.hasFocus()) { view.requestFocus(); } return false; } }); initWebView(); } private void initWebView(){ //Tell the WebView to enable javascript execution. myWebView.getSettings().setJavaScriptEnabled(true); myWebView.setBackgroundColor(Color.parseColor("#808080")); //Set whether the DOM storage API is enabled. myWebView.getSettings().setDomStorageEnabled(true); //setBuiltInZoomControls = false, removes +/- controls on screen myWebView.getSettings().setBuiltInZoomControls(false); myWebView.getSettings().setPluginState(PluginState.ON); myWebView.getSettings().setAllowFileAccess(true); myWebView.getSettings().setAppCacheMaxSize(1024 * 8); myWebView.getSettings().setAppCacheEnabled(true); _jsHandler = new JsHandler(this, myWebView); myWebView.addJavascriptInterface(_jsHandler, "JsHandler"); myWebView.getSettings().setUseWideViewPort(false); myWebView.setWebChromeClient(new WebChromeClient()); myWebView.setWebViewClient(new WebViewClient()); // these settings speed up page load into the webview myWebView.getSettings().setRenderPriority(RenderPriority.HIGH); myWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); myWebView.requestFocus(View.FOCUS_DOWN); myWebView.loadUrl("file:///android_asset/screen2.html"); } 

}

This assumes that your HTML page , which is to be downloaded, is located in the project resources folder .

What I did was put the media in mnt / sdcard /

To do this, I need to change the src attribute of the audio and video tags. In addition, as I mentioned earlier, the JavaScriptInterface class that I created, I will use this class to call audio or video for playback from Java, and not for processing HTML.

So this is what the new HTML page looks like

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <html> <head> <title>screen2</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="css/main-v1.css" rel="stylesheet" type="text/css"> <link href="css/screen2-v1.css" rel="stylesheet" type="text/css"> <script src="js/jQueryTest.js"></script> <script> function playVideo() { var cV = document.getElementById("video1"); cV.addEventListener('ended', function () { cV.removeEventListener('ended'); playAudio(); }, false); cV.play(); } function playAudio() { var cA = document.getElementById("audio1"); cA.addEventListener('ended', function () { cA.removeEventListener('ended'); playVideo(); }, false); cA.play(); } function init(){ JsHandler.initVideo(); } </script> <script> $(document).ready(function(){ init(); }); </script> </head> <body> <audio id="audio1" src="/mnt/sdcard/Android/data/com.exapmle.dms/files/resources/audio/screen2_a.mp3"></audio> <video id="video1" src="/mnt/sdcard/Android/data/com.exapmle.dms/files/resources/video/mov_bbb.mp4"></video> </body> </html> 

To explain what is happening, it is that when the HTML page is fully loaded, I called the init () method ; defined on the HTML page.

This method calls the initVideo () method ; defined in the JsHandler class

As you can see, this method is initVideo (); gives a call to the playVideo () method ; defined on the HTML page.

You may be wondering why not calling the playVideo () method ; directly when loading the page , well I tried and it didnโ€™t work (at least for me).

I hope this helps you or anyone else encountering a similar problem when loading HTML 5 Video in WebView

+1
source

Source: https://habr.com/ru/post/1480608/


All Articles