webview加载本地网页文件,网页中的视频大多是情况下一直显示加载转圈,极少数情况下偶尔能播放出来

问题遇到的现象和发生背景

写的前端页面,html+js+css,用来实现监控视频回放,用电脑浏览器打开能正常使用,将html、js、css文件嵌入android studio的assets下通过webview使用视频大多时候一直加载转圈,极少数偶尔能播放出来,按照网上提示已经硬件加速了,还是不行

问题相关代码,请勿粘贴截图

硬件加速部分

 name=".activity.HistoryVideo"
            android:configChanges="keyboardHidden|orientation"
            android:exported="true"
            android:hardwareAccelerated="true"
            android:screenOrientation="landscape" />

webview使用
webView = (WebView) findViewById(R.id.webView);

webSettings =webView.getSettings();
        webSettings.setPluginState(WebSettings.PluginState.ON);
        webSettings.setAllowFileAccess(true); // 允许访问文件
        //设置true,才能让Webivew支持标签的viewport属性
        webSettings.setUseWideViewPort(true);
//        webSettings.setSupportZoom(true); // 支持缩放
//        webSettings.setBuiltInZoomControls(true);//设置出现缩放工具
//        webSettings.setDisplayZoomControls(false);//设定缩放控件隐藏
        webSettings.setJavaScriptEnabled(true);// 启用javascript
//        webSettings.setAppCacheEnabled(true);
//        webSettings.setDatabaseEnabled(true);
//        webSettings.setDomStorageEnabled(true);//开启DOM缓存
        webSettings.setSupportMultipleWindows(true);// 新加
        webSettings.setLoadWithOverviewMode(true);// 缩放至屏幕的大小
//        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); // 不加载缓存内容
        ConnectivityManager connectivityManager =(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if(networkInfo.isAvailable()) {
            // 网络正常时使用默认缓存策略
            webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        } else {
            //网络不可用时只使用缓存
            webSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
        }
        webSettings.setAllowUniversalAccessFromFileURLs(true);
        webSettings.setMediaPlaybackRequiresUserGesture(false);
        webSettings.setUserAgentString("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
        //支持通过JS打开新窗口
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//        //支持自动加载图片
//        webSettings.setLoadsImagesAutomatically(true);
//        //优先使用缓存:
//        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        //提高渲染的优先级
        webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        // 开启H5(APPCache)缓存功能
        webSettings.setAppCacheEnabled(true);
        // 开启 DOM storage 功能
        webSettings.setDomStorageEnabled(true);
        // 应用可以有数据库
        webSettings.setDatabaseEnabled(true);
        // 可以读取文件缓存(manifest生效)
        webSettings.setAllowFileAccess(true);
        /*允许跨域访问*/
        if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            webSettings.setAllowUniversalAccessFromFileURLs(true);
        }
        //处理http和https混合的问题
        //在Android5.0以下,默认是采用的MIXED_CONTENT_ALWAYS_ALLOW模式,即总是允许WebView同时加载Https和Http;
        // 而从Android5.0开始,默认用MIXED_CONTENT_NEVER_ALLOW模式,即总是不允许WebView同时加载Https和Http。
        // 虽然官网给出的建议是,为了安全考虑,使用MIXED_CONTENT_NEVER_ALLOW模式,但是在实际引用中,当我们的服务器已经升级到Https,
        // 但是一些页面的资源是第三方的,我们不能要求第三方也都升级到Https,所以我们只能根据系统版本,用代码去设置加载模式为MIXED_CONTENT_ALWAYS_ALLOW。
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//如果sdk版本大于5.0
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        //设置进度条,处理提示框
        webView.setWebChromeClient(new WebChromeClient());
        webView.setWebViewClient(new WebViewClient());
        //添加监听
        webView.addJavascriptInterface(this,"android");
        //name:android在网页里面可以用window.name.方法名调用java方法
        /**
         * 实现JS调用Android方法,需要在Java代码中添加下面这句,webview绑定javascriptInterface,
         * js脚本通过这个接口来调用java代码, 第一个参数是自定义类对象,映射成JS对象,这里我直接传this,
         * 第二个参数是别名,JS脚本通过这个别名来调用java的方法,这个别名跟HTML代码中也是对应的。
         */
        webView.loadUrl("file:///android_asset/historyvideoback/VideoPlayback.html");// 从assets目录下面的加载html
    }


    private   class  MyWebViewClient extends WebViewClient {
        public MyWebViewClient() {
            super();
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
//            super.onReceivedError(view, request, error);
//            Log.e("TestTowActivity", "onReceivedError: "+"加载失败");
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
//          progressBar.setVisibility(View.GONE);
            //onPageFinished,走到这里的时候代表已加载结束
            //此时WebView加载完了,显示出来
            webView.setVisibility(View.VISIBLE);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {//注释掉不然左侧设备列表会重复出现
            view.loadUrl(url);
            return true;
        }
    }
    /**
     * 设置进度条和提示框
     */
    private class MyWebChromeClient extends WebChromeClient {
        //该方法中可以设置进度条
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
//            super.onProgressChanged(view, newProgress);
//            webView.loadUrl("javascript:getOrganizationId('"+affiliationId+"')");
        }
        //该方法中可以处理提示框
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            return super.onJsAlert(view, url, message, result);
        }
        /**
         * 解决WebView播放视频点击全屏按钮白屏的问题。
         * ps:如果去掉则部分机型视频全屏展示时有问题
         */
        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) {
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            webView.setVisibility(View.GONE);
            videoContainer.setVisibility(View.VISIBLE);
            videoContainer.addView(view);
            mCallBack=callback;
            super.onShowCustomView(view, callback);
        }

        @Override
        public void onHideCustomView() {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            if (mCallBack!=null){
                mCallBack.onCustomViewHidden();
            }
            webView.setVisibility(View.VISIBLE);
            videoContainer.removeAllViews();
            videoContainer.setVisibility(View.GONE);
            super.onHideCustomView();
        }
    }

运行结果及报错内容

webview中页面中的视频大多时候一直加载转圈,极少数偶尔能播放出来

webview设置的问题,请参考我的文章
https://blog.csdn.net/xiyangyang8110/article/details/123281065

在webview中播放视频,先定位一下是没收到流引起的转圈,还是收到流了,解码播放失败引起的转圈。
通过抓包判断是否收到流了。

img


你webview初始化的时候是隐藏的吗?

这个应该是你模式的问题,你用webview直接播放本地的视频文件,而不是网上的视频流。webview要加载完整个视频才可以播放,某些时候不卡只是手机当时内存够用反应快罢了。我曾经用个人笔记本搭建过视频流服务器,在同一局域网下,无论是手机播放,还是电脑播放都是十分流畅的【其核心在于断点续传】。python工具方法 29 基于Flask搭建自己的视频服务器网站_万里鹏程转瞬至的博客-CSDN博客_用python搭建视频网站

看你描述是一次拉了多个流塞住了,那个这个网页应该是默认某一个视频流播放,点击图片切另外一个。大多数视频网站都是这样的,客户端不像pc有插件支持和内存够