自动暂停和恢复网页中的视频播放

序言

在日常开发中,有时候一级栏目可能是个H5页面,当切换到其他栏目的时候需要自动暂停H5中的视频,切换回来以后需要自动恢复播放。实现的思路是通过JS来操作,难点是感知fragment的可见状态。还有js代码的编写。

比如下面这个页面就是H5页面。切换到首页的时候需要暂停视频,切换回来需要自动播放。

在这里插入图片描述

解决方案

对fragment可见状态的监视

通过一下工具类实现。相关的使用方式在注释中,只需要在fragment中调用相关方法就行了。该类采用了观察者模式,如果后面还有其他基于可见性的业务代码,通过添加观察者就可以扩展。

package com.trs.library.fragment;import java.util.Observable;/*** <pre>* Created by zhuguohui* Date: 2024/2/6* Time: 9:46* Desc:该类是用于监视fragment的可见状态的工具类* 采用观察者模式,注册观察者以后,可见状态会以参数的形式传递。* 这里的可见的定义是对用户可见。屏蔽了viewpager中的预加载不算* 或者通过fragmentManger的hide方法隐藏了fragment。也不算可见。** 使用方法。需要在fragment的生命周期方法中调用同名的以下方法。* {@link #setUserVisibleHint(boolean)}* {@link #onResume()}* {@link #onPause()}* {@link #onHiddenChanged(boolean)}** 提示:* 由于setUserVisibleHint 比fragment的onCreate方法还要提前。所以这个工具的初始化不能放在生命周期方法中。* 最好以类的成员变量的形式初始化。* </pre>*/
public  class FragmentShowStateMonitor extends Observable {boolean isVisibleToUser = true;boolean isHide = false;/*** 这个方法由ViewPager调用。** @param isVisibleToUser*/public final void setUserVisibleHint(boolean isVisibleToUser) {this.isVisibleToUser = isVisibleToUser;onFragmentShowStateChange(isVisibleToUser);}public final void onPause() {if (isShow()) {onFragmentShowStateChange(false);}}private boolean isShow() {if (isHide||!isVisibleToUser) {return false;//viewPager中也可能hide}return true;}/*** 使用FragmentTransaction的show或者hide方法的时候。会回调改方法。* hide的本质就是将fragment中的view设置为GONE。* 注意:如果fragment嵌套了子Fragment。当外层的fragment的onHiddenChanged被调用以后* 子Fragment默认是不会被调用了。如果要记录子Fragment的显示时长。需要自己去重新父Fragment的* onHiddenChanged方法。** @param hidden*/public final void onHiddenChanged(boolean hidden) {isHide = hidden;onFragmentShowStateChange(!hidden);}/*** 在viewPager中由于有预加载功能,当调用onResume的时候,其实并没有显示给用户* 需要通过isVisibleToUser 来判断是否显示**/public final void onResume() {if (isShow()) {onFragmentShowStateChange(true);}}/*** 子类重写该方法用于记录fragment给用户展示的时间** @param showToUser*/protected  void onFragmentShowStateChange(boolean showToUser){setChanged();notifyObservers(showToUser);}}

使用参考

package com.trs.library.fragment;import android.os.Bundle;
import android.util.Log;
import android.view.View;import com.gyf.immersionbar.components.ImmersionFragment;
import com.trs.library.rx.bus.RxBus;import java.util.LinkedList;
import java.util.Queue;import io.reactivex.disposables.CompositeDisposable;
import rx.subscriptions.CompositeSubscription;/*** Created by Vincent Woo* Date: 2016/6/8* Time: 10:41*/
public class TRSFragment extends Fragment{protected FragmentShowStateMonitor showStateMonitor=new FragmentShowStateMonitor();@Overridepublic void onResume() {super.onResume();showStateMonitor.onResume();}@Overridepublic void onPause() {super.onPause();showStateMonitor.onPause();}@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);showStateMonitor.setUserVisibleHint(isVisibleToUser);}@Overridepublic void onHiddenChanged(boolean hidden) {super.onHiddenChanged(hidden);showStateMonitor.onHiddenChanged(hidden);}
}

由于目前项目中H5的页面没有出现在ViewPager中。所以监视代码比较简单。

如果出现在ViewPager中。当一个fragment A 包含ViewPager,viewPager又包含很多子fragment。当A通过fragmentManger的hide方法隐藏的时候,只有A的onHiddenChanged方法会被调用,子Fragment的相关方法不会被调用。

如果我们要观察的fragment属于ViewPager中那么我们需要手动的找出正在显示的fragment,手动调用它的onHiddenChanged。因为默认的情况下,onHiddenChanged方法没有传递性。具体的解决方案参考我的另外一篇博客。

记录Fragment的显示时长

视频的暂停

主要通过js实现,相关的情况说明都写在注释了。

package com.trs.myrb.fragment.common;import com.tencent.smtt.sdk.WebView;/*** <pre>* Created by zhuguohui* Date: 2023/12/27* Time: 15:48* Desc:该工具类的作用是通过js来暂停或者恢复网页中的视频或音频播放。* </pre>*/
public class PauseWebVideoUtil {public static void pauseAudio(WebView webView){//以下两行代码的目的是清除网页中的定时器//在业务中发现,不清除定时器的话,在其他页面,用原生播放器播放视频的话可能会自动暂停//可能是网页中有定时器在播放视频,抢走了音频焦点。需要暂停视频//为什么不用WebView的pauseTimers()方法。因为这个方法它会暂停所有webView的渲染和js的执行。//结果就是其他的网页都加载不出来。使用js来清楚定时器,它的影响范围在单个WebView中// 清除所有 setTimeoutwebView.evaluateJavascript("for (var i = 1; i < 10000; i++) { clearTimeout(i); }", null);// 清除所有 setIntervalwebView.evaluateJavascript("for (var i = 1; i < 10000; i++) { clearInterval(i); }", null);//为什么要把暂停的视频保存在window.LastPauseVideoFromApp变量中。//主要是为了避免一个页面中有多个可以播放的模块。如果不记录之前暂停的控件的话//到了恢复播放的时候,可能就会错误的播放多个控件。造成一片混乱webView.loadUrl("javascript:( function (){\n" +"  var videos = document.getElementsByTagName('video');\n" +"  var audios = document.getElementsByTagName('audio');\n" +"\tvar len = videos.length;\n" +" window.LastPauseVideoFromApp;\n" +"\tfor (var i = 0; i < len; i++) {\n" +"      \tif(!videos[i].paused){\n" +"        \twindow.LastPauseVideoFromApp=videos[i];\n" +"        }\n" +"\t}\n" +"  \tvar len = audios.length;\n" +"\tfor (var i = 0; i < len; i++) {\n" +"\t \tif(!audios[i].paused){\n" +"        \twindow.LastPauseVideoFromApp=videos[i];\n" +"        }\n" +"\t}\n" +"  if(window.LastPauseVideoFromApp!=null){\n" +"    window.LastPauseVideoFromApp.pause();\n" +"  }\n" +"})();\n");}public static void resumeAudio (WebView webView){webView.loadUrl("javascript:(function(){\n" +" if(window.LastPauseVideoFromApp!=null){\n" +" \twindow.LastPauseVideoFromApp.play();\n" +"   window.LastPauseVideo=null;\n" +" }\n" +"})();");}
}

观察者对接


package com.trs.myrb.fragment.common;import com.tencent.smtt.sdk.WebView;
import com.trs.myrb.douyin.action.TRSFunction;import java.util.Observable;
import java.util.Observer;/*** <pre>* Created by zhuguohui* Date: 2024/2/6* Time: 9:57* Desc: 这类的作用是在fragment用户不可见的情况下自动暂停网页中的视频,在可见的状态下自动播放* </pre>*/
public class AutoPauseVideoInWebObserver implements Observer {TRSFunction<Void,WebView> webViewGetter;public AutoPauseVideoInWebObserver(TRSFunction<Void, WebView> webViewGetter) {//使用回调来获取webView是为了防止webView没有创建,比如在fragment的onCrate的情况下this.webViewGetter = webViewGetter;}@Overridepublic void update(Observable o, Object arg) {boolean showToUser= (boolean) arg;pauseOrResumeWebView(!showToUser);}boolean webViewIsPause = false;private void pauseOrResumeWebView(boolean pause) {WebView x5WebView = webViewGetter.call(null);//如果网页中有视频,可以暂停视频,或者恢复视频//比如从当前fragment切换到其他fragment避免再出现声音if (webViewGetter.call(null) == null) {return;}if (pause == webViewIsPause) {//状态相同return;}if (pause) {//通过js 暂停音频PauseWebVideoUtil.pauseAudio(x5WebView);x5WebView.onPause();} else {PauseWebVideoUtil.resumeAudio(x5WebView);x5WebView.onResume();}webViewIsPause = pause;}
}

使用

    @Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//以下代码的作用是在fragment用户不可见的情况下自动暂停网页中的视频,在可见的状态下自动播放showStateMonitor.addObserver(new AutoPauseVideoInWebObserver(unused -> x5WebView));}

总结

实现起来不是很难,主要是把各个功能疏解到单独的类中。保证每个类的职责单一,提高逻辑的清晰性。增加维护的便利性。通过观察者模式还可以为后面的业务拓展提供支撑,增加了系统的弹性。这也是提高自己代码的设计性的尝试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/671649.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch的10个基本张量操作

PyTorch是一个基于python的科学计算包。它的灵活性允许轻松集成新的数据类型和算法&#xff0c;并且框架也是高效和可扩展的&#xff0c;下面我们将介绍一些Pytorch的基本张量操作。 Tensors 张量Tensors是一个向量&#xff0c;矩阵或任何n维数组。这是深度学习的基本数据结构…

DevExpress WinForms中文教程 - 如何创建可访问的WinForms应用?(二)

为用户创建易访问的Windows Forms应用程序不仅是最佳实践的体现&#xff0c;还是对包容性和以用户为中心的设计承诺。在应用程序开发生命周期的早期考虑与可访问性相关的需求可以节省长期运行的时间(因为它将决定设计决策和代码实现)。 一个可访问的WinForms应用程序提供了各种…

20240202在Ubuntu20.04.6下使用whisper.cpp的显卡模式

20240202在Ubuntu20.04.6下使用whisper.cpp的显卡模式 2024/2/2 19:43 【结论&#xff1a;在Ubuntu20.04.6下&#xff0c;确认large模式识别7分钟中文视频&#xff0c;需要356447.78 ms&#xff0c;也就是356.5秒&#xff0c;需要大概5分钟&#xff01;效率太差&#xff01;】 …

CleanMyMac2024如何识别并清理垃圾文件?

CleanMyMac识别并清理垃圾文件的过程主要依赖于其强大的扫描功能和智能算法。以下是具体的步骤&#xff1a; 扫描垃圾文件&#xff1a;首先&#xff0c;用户需要打开CleanMyMac软件&#xff0c;并点击“智能扫描”功能。然后&#xff0c;软件将开始自动扫描Mac系统上的各种垃圾…

微信小程序(基本操作)

概念&#xff1a; 小程序&#xff1a;就是小程序&#xff0c;mini program。现在市面上有微信小程序&#xff0c;百度智能小程序等等。 微信小程序&#xff0c;简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了…

5-4、S加减单片机程序【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍实现步进电机S曲线运动的代码 一、目标功能 实现步进电机转动总角度720&#xff0c;其中加减速各90 加速段&#xff1a;加速类型&#xff1a;S曲线  加速角度&#xff1a;角度为90  起步速度…

CSS太极动态图

CSS太极动态图 1. 案例效果 我们今天学习用HTML和CSS实现动态的太极&#xff0c;看一下效果。 2. 分析思路 太极图是由两个旋转的圆组成&#xff0c;一个是黑圆&#xff0c;一个是白圆。实现现原理是使用CSS的动画和渐变背景属性。 首先&#xff0c;为所有元素设置默认值为0…

Topaz Photo AI for Mac v2.3.1 补丁版人工智能降噪软件无损放大

想要将模糊的图片变得更加清晰&#xff1f;不妨试试Topaz Photo AI for Mac 这款人工智能、无损放大软件。Topaz Photo AI for Mac 一款强大的人工智能降噪软件&#xff0c;允许用户使用复杂的锐化算法来提高图像清晰度&#xff0c;还包括肖像编辑选项&#xff0c;如面部重塑、…

Visual Studio 2010+C#实现信源和信息熵

1. 设计要求 以图形界面的方式设计一套程序&#xff0c;该程序可以实现以下功能&#xff1a; 从输入框输入单个或多个概率&#xff0c;然后使用者可以通过相关按钮的点击求解相应的对数&#xff0c;自信息以及信息熵程序要能够实现马尔可夫信源转移概率矩阵的输入并且可以计算…

Netty源码系列 之 EventLoop run()方法 源码

EventLoop[实现类为NioEventLoop&#xff0c;我们研究NioEventLoop即可] EventLoop是一个单线程的线程池 核心作用&#xff1a;处理执行IO操作&#xff08;accept&#xff0c;read&#xff0c;write事件&#xff09;&#xff0c;普通任务&#xff0c;定时任务 EventLoop封装…

精酿啤酒:发酵过程中的温度控制与效果

在啤酒酿造过程中&#xff0c;发酵温度的控制重要&#xff0c;它不仅影响酵母菌的活性&#xff0c;还决定了啤酒的口感、香气和风味。对于Fendi Club啤酒来说&#xff0c;切确控制发酵温度是确保啤酒品质和口感的关键环节。 在Fendi Club啤酒的发酵过程中&#xff0c;温度控制尤…

c#cad 创建-正方形(四)

运行环境 vs2022 c# cad2016 调试成功 一、程序说明 创建一个正方形&#xff0c;并将其添加到当前活动文档的模型空间中。 程序首先获取当前活动文档和数据库&#xff0c;并创建一个编辑器对象。 然后&#xff0c;使用事务开始创建正方形的操作。获取模型空间的块表记录&a…

Vue3大事件项目(ing)

文章目录 核心内容1.大事件项目介绍2.大事件项目创建3.Eslint配置代码风格4.配置代码检查工作流问题: pnpm lint是全量检查,耗时问题,历史问题 5.目录调整6.vue-router4 路由代码解析7.引入 Element Plus 组件库8.Pinia 构建仓库 和 持久化9.Pinia 仓库统一管理 核心内容 Vue3…

C# 夺冠,微软.NET前途光明!

本文以C# 摘得 “2023 年度编程语言“称号为背景&#xff0c;介绍.NET的历史、生态及发展势头&#xff0c;该文章是本人C#专栏的第一篇文章。 这里写目录标题 1.C#摘得"2023年度编程语言"奖项2.什么是.NET&#xff1f;2.1.NET简史2.2.NET是用于应用程序开发的生态系…

2024:AI 大冒险

2024&#xff1a;AI 大冒险 2023 年就像一场疯狂的过山车&#xff0c;现在让我们一起系好安全带&#xff0c;来预测一下 2024 年的五大惊心动魄事件吧&#xff01; 一、AI 惹祸升级 嘿&#xff0c;2024 年可要小心了&#xff01;AI 这家伙可能会变得更调皮捣蛋。人们可能会用…

Ubuntu下anaconda的常用操作

Ubuntu下anaconda的安装及常用操作 安装Anaconda 下载Anaconda&#xff1a;在Anaconda官网下载适合你系统的Anaconda安装包&#xff08;通常是64位的Linux版本&#xff09;。 安装Anaconda 在终端中导航到你下载Anaconda安装包的目录&#xff0c;然后运行以下命令安装Anacon…

git 使用 (备查)

git忽略清单 添加忽略清单 SSH免登录 ssh协议可以实现免登录操作&#xff0c;身份验证通过密钥实现。 跨团队写作 解决冲突 拉取 克隆 拉取最新版本 推送 远程仓库别名 直接使用git push推送 多人协作开发 分支命令 合并分支命令在主分支使用&#xff0c;将develop分支合并到…

大型装备制造企业案例分享——通过CRM系统管理全球业务

本期&#xff0c;小Z为大家带来的CRM管理系统客户案例是某大型装备制造企业运用Zoho CRM管理全球业务的过程分享。该企业是创业板上市公司&#xff0c;业务遍及100多个国家和地区&#xff0c;合作伙伴超百位&#xff0c;拥有覆盖全球的销售和服务网络。截止目前&#xff0c;相继…

7.electron之渲染线程发送事件,主进程监听事件

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中&#xff0c;因此它允许你仅需一个代码仓库&#xff0c;就可以撰写支持 Windows、…

【漏洞复现】电信网关配置管理系统SQL注入漏洞

Nx01 产品简介 电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远程监控、配置、升级和故障排除等功能&#xff0c;从而确保网络的正常运行和高效性能。 Nx02 漏洞描述 电信网关配置管理系统存在SQL注入漏洞,攻…