Android WebView 中的 HTML5 视频不一致

Posted

技术标签:

【中文标题】Android WebView 中的 HTML5 视频不一致【英文标题】:Inconsistencies with HTML5 video in an Android WebView 【发布时间】:2013-05-08 03:26:15 【问题描述】:

android WebView 中的 html5 页面上显示 .mp4 视频时,从远程 URL 检索文件时,视频和音频都会正确播放。当尝试从设备的“/mnt/sdcard/....”路径中播放相同的媒体文件时,只会播放媒体文件的音频部分。对此有什么想法吗?有没有人经历过(并希望解决)类似的事情?尽管通过网络检索视频时可以看到视频,但这可能是编解码器问题吗?通过网络返回的视频在进入 WebView 之前是否经过了某种操作或转换?

【问题讨论】:

您是否在清单中启用了硬件加速(参见此示例gist.github.com/Offbeatmammal/3718414) 【参考方案1】:

以下代码对我有用,希望对您有所帮助, 我也认为很多人都面临同样的问题,所以这就是我所做的让 HTML5 视频 在我的应用程序 WebView 中运行。

我将引导您完成程序

我想在我的 App 的 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>

现在我创建了 Class 来充当 Android 之间的 接口 和 HTML 页面中的 Javascript

这是我的项目 src 文件夹中名为 JsHandler.javajavascriptInterface 类

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页面位于项目的资产文件夹中。

我所做的是将 媒体文件 放在 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类

中定义的initVideo();方法

如您所见,这个 initVideo(); 方法调用了 HTML 页面中定义的 playVideo(); 方法。

你可能想知道为什么不直接在页面加载上调用playVideo();方法, 好吧,我已经尝试过了,但它没有用,(至少对我来说)。

我希望它可以帮助您或其他在 WebView 中加载 HTML 5 视频 时遇到类似问题的人

【讨论】:

以上是关于Android WebView 中的 HTML5 视频不一致的主要内容,如果未能解决你的问题,请参考以下文章

android webview怎么加载ionic的html5

Android WebView html5 视频强制全屏

HTML5 Canvas 支持和 Android Webview

在 Android WebView 中拦截 HTML5 视频源请求

Android - 应用更新后 WebView html5 本地存储不持久

Android webview html5地理定位