在 Android WebView 的 HTML5 页面上显示 .mp4 视频时,从远程 URL 检索文件时,视频和音频都可以正确播放。当尝试从设备的“/mnt/sdcard/....”路径中播放相同的媒体文件时,只会播放媒体文件的音频部分。对此有什么想法吗?有没有人经历过(并希望解决)类似的事情?尽管通过网络检索视频时可以看到视频,但这可能是编解码器问题吗?在 WebView 中结束之前,是否以某种方式操纵或转换了通过网络返回的视频。
最佳答案
下面的代码对我有用,希望对你有帮助, 我也认为很多人都面临着同样的问题,所以这就是我让 HTML5 视频 在我的应用程序 WebView 中运行的方法。
我将引导您完成过程。
我想在我的应用程序的 WebView 中一个接一个地加载多个 HTML 页面。这些 HTML 页面包含音频后跟视频,或视频后跟音频。
这是一个这样的 HTML 页面的示例。
<!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>
现在我创建了类作为 Android 和 HTML 页面中的 Javascript 之间的接口(interface)。
这是我的项目 src 文件夹中名为 JsHandler.java 的 JavaScriptInterface 类
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();
}
}
这是我的 MainActivity 中的代码,它在 WebView 中加载 HTML 页面
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");
}
这是考虑到要加载的 HTML 页面位于项目的 Assets 文件夹中。
我所做的是将媒体文件放在mnt/sdcard/
为此,我需要相应地更改 audio 和 video 标签的 src 属性。此外,正如我之前提到的我创建的 JavaScriptInterface 类,我将使用该类调用音频或视频以从 Java 播放,而不是 HTML 处理它。
所以,新的 HTML 页面是这样的
<!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>
为了解释这里发生的事情,当 HTML 页面完全加载时,我调用了 HTML 页面中定义的 init(); 方法。
该方法调用定义在JsHandler Class中的initVideo();方法
如您所见,此 initVideo(); 方法调用了 HTML 页面中定义的 playVideo(); 方法。
您可能想知道为什么不在页面加载时直接调用playVideo();方法, 好吧,我已经尝试过了,但没有用,(至少对我来说是这样)。
我希望它能帮助您或任何其他在 WebView 中加载 HTML 5 Video 时遇到类似问题的人
关于android - 与 Android WebView 中的 HTML5 视频不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16533170/