Flutter中使用webview_flutter: ^1.0.7插件如何禁用WebView内视频全屏播放
webview_flutter ^1.0.7 拦截视频自动全屏实现方案
适配约束:保留JavaScript运行权限、不影响用户交互触发的视频正常播放、仅阻止视频自动进入全屏状态,不依赖AutoMediaPlaybackPolicy配置
方案核心逻辑
webview_flutter 1.0.7 这个版本本身没有暴露原生层的全屏事件拦截回调入口,很多人一开始尝试调整AutoMediaPlaybackPolicy,但那个参数只管“没有用户交互时网页能不能自动播放媒体”,和视频播放后触发的全屏跳转逻辑完全不搭边,根本解决不了问题。
我们的实现思路很直接:在网页自身业务JS执行前,提前注入拦截代码重写所有视频元素的全屏请求API,不侵入网页原有逻辑,也完全不修改JavaScript的运行权限,就能实现拦截效果。
具体实现步骤
- 初始化WebView时确保开启无限制JavaScript运行权限,对应配置为
JavaScriptMode.unrestricted,符合不禁用JS的要求。 - 拦截脚本的注入时机要选对:必须在网页DOM结构开始构建、还没执行自身业务JS的阶段注入,选
NavigationDelegate的onPageStarted回调最合适,通过WebViewController.runJavascript方法执行拦截代码。千万不要等onPageFinished再注入,那时候网页已经绑定好点击事件引用了原生全屏方法,重写逻辑根本不生效。 - 注入的拦截脚本只重写视频元素的全屏请求方法,完全不触碰播放、暂停、进度控制等视频核心播放逻辑,保证视频功能正常可用,脚本内容如下:
// 重写标准全屏API,替换为空的已完成Promise实现 Object.defineProperty(HTMLVideoElement.prototype, 'requestFullscreen', { value: function() { return Promise.resolve() }, writable: true }); // 兼容安卓WebView内核的webkit前缀全屏API Object.defineProperty(HTMLVideoElement.prototype, 'webkitRequestFullscreen', { value: function() { return Promise.resolve() }, writable: true }); // 兼容其他内核的前缀实现 Object.defineProperty(HTMLVideoElement.prototype, 'mozRequestFullScreen', { value: function() { return Promise.resolve() }, writable: true }); Object.defineProperty(HTMLVideoElement.prototype, 'msRequestFullscreen', { value: function() { return Promise.resolve() }, writable: true });
- 低版本内核补漏:如果遇到老版本WebView内核中,JS层的全屏请求没有被完全拦截、仍然触发原生层全屏跳转的情况,只需要对当前版本插件的原生实现做极小幅修改,不需要升级插件版本:
- 安卓端:找到插件内置的
WebChromeClient实现,在onShowCustomView回调中直接返回,不将传入的自定义视图添加到根布局,阻断原生全屏的展示流程。 - iOS端:找到插件内置的
WKUIDelegate实现,在视频全屏触发的回调中直接拒绝请求,不唤起原生全屏控制器。
- 安卓端:找到插件内置的
方案效果说明
- 全程不限制JavaScript的运行能力,网页所有原有业务逻辑都可正常执行。
- 用户点击页面触发的视频播放动作不受任何影响,播放、暂停、进度拖动、音量调整等视频基础功能完全可用。
- 所有触发全屏的入口(网页JS主动调用、视频内置全屏按钮触发)都会被拦截,不会出现自动跳转全屏的情况。
内容的提问来源于stack exchange,提问作者luc
相关产品推荐
相关产品推荐

