
1. 网课自动暂停到底卡在哪先搞懂检测机制再动手很多人遇到网课自动暂停第一反应是“平台故意整我”其实绝大多数情况下是浏览器把“你切走了”这个信号老老实实告诉了网页。在线学习平台判断你有没有在认真看课靠的不是摄像头也不是什么黑科技而是浏览器提供的一组标准事件接口。搞明白这套机制后面所有操作你都能自己推导出来而不是死记某个偏方。1.1 页面可见性检测切标签页就暂停的元凶现代浏览器有一个 Page Visibility API核心就是document.hidden和visibilitychange事件。当你切换到别的标签页、最小化窗口、甚至把浏览器拖到屏幕边缘被其他窗口盖住时浏览器会把当前页面的可见性状态改成 hidden同时触发visibilitychange。学习平台的脚本监听到这个事件立刻调用播放器的 pause 方法视频就停了。这个机制本身是合理的它的设计初衷是省电、省资源让后台标签页不要疯狂跑动画和视频解码。但用在网课场景里就变成了“你一走开它就停”。所以解决思路很直接要么让页面永远认为自己可见要么让平台的监听逻辑失效。1.2 焦点丢失检测blur 和 focus 事件才是隐藏关卡比可见性更隐蔽的是焦点检测。有些平台不满足于只看标签页是否可见还会监听window的blur和focus事件。你只要点击了浏览器地址栏、点了另一个窗口、甚至点了开发者工具的面板当前页面就会触发 blur平台脚本收到信号后同样会暂停。这就是为什么有些人明明没切标签页只是点了一下别的地方课就停了。热搜词里反复出现的blur就是这个东西。它比 visibilitychange 更“敏感”也更难缠因为你在操作浏览器的过程中几乎不可避免地会产生焦点变化。1.3 鼠标与键盘空闲检测你以为没人看其实它在数秒还有一类平台会监听mousemove、keydown、scroll等交互事件设定一个空闲阈值比如 60 秒内没有任何鼠标移动或按键就判定你“不在电脑前”自动暂停。这种检测在继续教育类平台上特别常见因为它们的核心诉求就是确认“本人在场”。这类检测的破解思路和前两种不同它需要你持续制造“假活动”。后面我会给出具体的实现方式包括用开发者工具注入定时器模拟事件以及更省事的后台播放方案。把这三层机制理清楚你就明白了自动暂停不是单一原因而是可见性、焦点、空闲三重检测叠加的结果。不同的平台用的组合不一样所以不存在一个万能按钮但有一套通用的排查和应对流程。2. 用 Edge 开发者工具定位暂停逻辑F12 实战排查Edge 的 F12 开发者工具是解决这类问题最趁手的武器没有之一。它内置的事件监听器面板、断点调试、控制台注入能力足够你把平台的暂停逻辑扒得清清楚楚。下面这套流程是我自己反复用过的按顺序走基本不会迷路。2.1 打开事件监听器面板锁定 blur 与 visibilitychange第一步在网课页面按 F12 打开开发者工具切到 Elements 面板选中body或html节点右侧会有一个 Event Listeners 标签页。点开它你会看到这个节点上挂载的所有事件监听。重点看三类blur、focus、visibilitychange。如果 body 或 window 上挂了这些基本可以确定平台在用它们做暂停判断。展开对应的监听器能看到它绑定的函数名和所在文件点进去就能看到源码逻辑。提示有些平台会把监听挂在 document 或 window 上Elements 面板默认只显示当前选中节点的监听。记得把 Ancestors 勾上才能看到父级和全局的监听。2.2 用断点确认暂停触发点别瞎猜找到可疑的监听函数后直接在里面下断点。切走标签页再切回来如果断点被命中说明这条路就是暂停的触发路径。命中后看调用栈往上翻一层就能找到真正执行 pause 的地方。这一步的价值在于你不用去猜平台用了哪种检测断点会告诉你真相。我遇到过一些平台表面上监听的是 visibilitychange实际上真正暂停是在 blur 回调里做的光看代码不打断点很容易判断错。2.3 控制台注入事件拦截快速验证思路如果你不想一行行读源码可以用控制台快速验证。在 Console 里执行一段拦截代码把document.hidden的 getter 改成永远返回 false同时阻止 visibilitychange 事件的传播Object.defineProperty(document, hidden, { get: () false }); Object.defineProperty(document, visibilityState, { get: () visible }); document.addEventListener(visibilitychange, e e.stopImmediatePropagation(), true); window.addEventListener(blur, e e.stopImmediatePropagation(), true);这段代码的作用是让页面永远认为自己可见并且把可见性变化和焦点丢失事件在捕获阶段就掐断平台的监听器根本收不到通知。执行完再切走标签页试试如果视频不暂停了说明思路正确。注意stopImmediatePropagation必须加true参数走捕获阶段否则平台的监听如果在冒泡阶段注册你拦不住。这个细节很多人会忽略。2.4 把注入代码做成书签一键生效每次开课都手动粘贴太麻烦可以做成书签小工具。新建一个书签地址栏填javascript:开头的那段代码以后点一下书签就自动注入。不过 Edge 对javascript:书签有安全限制部分版本会拦截这时候可以用扩展或者油猴脚本来替代效果一样。实测下来这套 F12 排查流程对绝大多数基于浏览器事件的暂停逻辑都有效。真正难缠的是那些用 WebSocket 上报心跳、服务端判断在线的平台那种就得换思路走后台播放或者模拟活动。3. 后台播放与防暂停的几种落地方法排查清楚机制之后落地方法其实就那么几类。我按“侵入性从低到高”排个序你可以根据自己的情况选。3.1 方法一事件拦截注入适合临时救急就是上面控制台那段代码优点是即开即用、不改动任何文件、不留痕迹。缺点是每次刷新页面就失效得重新注入。适合偶尔挂一节课、不想折腾的场景。如果平台还检测鼠标空闲可以再加一段模拟活动的代码setInterval(() { window.dispatchEvent(new MouseEvent(mousemove, { clientX: Math.random() * 100, clientY: Math.random() * 100 })); window.dispatchEvent(new KeyboardEvent(keydown, { key: Shift })); }, 30000);每 30 秒模拟一次鼠标移动和按键骗过空闲检测。间隔别设太短太频繁反而可能触发平台的反作弊风控。3.2 方法二油猴脚本常驻一劳永逸Tampermonkey 这类用户脚本管理器可以把注入代码固化下来匹配到指定网课域名就自动执行。写一个match规则把拦截逻辑和模拟活动都塞进去以后打开页面就自动生效不用管。这种方式的优势是稳定、可维护平台改检测逻辑你改脚本就行。缺点是需要装扩展部分公司的电脑可能不允许装。另外脚本要写好异常处理别把页面其他正常功能搞崩了。3.3 方法三多窗口并排 画中画物理规避如果不想动代码还有个纯物理的办法把网课窗口和你要做的事情并排放在屏幕上各占一半。这样网课窗口始终可见、始终有焦点只要你不在另一边点击blur 和 visibilitychange 都不会触发。更进一步可以用浏览器的画中画功能。很多播放器支持把视频弹出成画中画小窗画中画窗口是独立的切走主标签页视频照样播。不过画中画能不能绕过平台的暂停逻辑取决于平台是否监听画中画事件实测大部分继续教育平台是绕不过的因为它们的暂停逻辑绑在页面可见性上跟播放器形态无关。3.4 方法四虚拟机或第二台设备彻底隔离最省心的办法其实是物理隔离用另一台电脑、或者本机开个虚拟机专门挂课你该干嘛干嘛。这种方式不涉及任何代码注入平台检测到的就是一台“老老实实开着页面”的设备没有任何异常信号。代价是需要额外的硬件或虚拟机软件但对需要长期挂继续教育学时的人来说这个投入是值得的。我自己就是一台旧笔记本专门跑这类任务屏幕常亮、页面常开从来没出过问题。把这四种方法对比一下方法侵入性持久性适用场景主要风险控制台注入低单次临时救急刷新失效油猴脚本中长期固定平台扩展被禁并排/画中画无单次轻度使用效果有限虚拟机/第二设备无长期长期挂课硬件成本4. 常见问题与排查技巧实录实际操作中遇到的问题远比想象中杂这里整理几个高频坑和对应的排查思路都是我自己踩过的。4.1 注入后视频不暂停了但进度条不走这种情况通常是平台用了服务端心跳。页面虽然不暂停但平台每隔一段时间向服务器上报一次“在线状态”如果你的事件拦截把某些必要的网络请求也拦了或者模拟活动被识别为异常服务端就不给记进度。排查方法打开 Network 面板看有没有周期性的 XHR 或 WebSocket 请求。如果有检查你的拦截代码是不是误伤了它们。解决思路是只拦事件、不拦网络让心跳正常发。4.2 切走标签页后视频继续播但声音没了这是浏览器的省电策略在起作用后台标签页的音频输出可能被限制。解决办法是在页面里加一段静音的音频循环保持音频通道活跃或者干脆用画中画。不过这个现象因浏览器版本而异Edge 较新版本对后台音频的限制比较宽松一般不会遇到。4.3 平台检测到开发者工具打开就暂停有些平台会检测开发者工具是否打开一旦发现就暂停视频甚至弹警告。检测方式通常是看窗口内外尺寸差或者监听debugger语句的执行时间。应对方式用独立的浏览器窗口打开开发者工具F12 后点右上角三个点选“在独立窗口中打开”这样内外尺寸差检测就失效了。或者用远程调试的方式从另一个浏览器实例连过去平台完全感知不到。4.4 模拟活动被判定为机器人模拟鼠标移动的代码如果太规律比如每次都是固定坐标、固定间隔平台的风控可能识别出来。改进方法是加入随机性坐标随机、间隔随机、偶尔模拟滚动而不是移动。让行为看起来更像真人。4.5 常见问题速查表现象可能原因排查方向解决思路切标签就暂停visibilitychange 监听事件监听器面板拦截 visibilitychange点别处就暂停blur 监听事件监听器面板拦截 blur不动鼠标就暂停空闲检测搜索 mousemove 监听定时模拟活动注入后进度不走服务端心跳Network 面板放行心跳请求开 F12 就暂停开发者工具检测窗口尺寸差独立窗口打开 F12模拟活动被风控行为太规律观察警告提示加入随机性4.6 几个容易被忽略的细节第一Edge 的“睡眠标签页”功能会把后台标签页冻结冻结后你的注入代码可能也停了。记得在edge://settings/system里把睡眠标签页关掉或者把网课域名加入例外。第二有些平台的暂停逻辑写在 Web Worker 里主线程的事件拦截拦不住。这种情况得用更底层的方式比如在 Worker 创建时注入代理难度较高一般不建议折腾直接上虚拟机方案更省事。第三浏览器扩展之间可能冲突。如果你装了广告拦截、隐私保护类扩展它们可能修改了页面的事件系统导致你的注入失效。排查时先禁用其他扩展确认是哪个在捣乱。第四平台更新很频繁今天有效的注入明天可能就失效。所以别把宝押在单一方法上最好准备两套方案一套失效立刻切另一套。5. 我的实操心得与方案选择建议折腾这类问题这么多年我最大的体会是不要追求“完美破解”而要追求“稳定可用”。平台和用户之间的检测与反检测是持续博弈你今天找到的漏洞平台下个版本可能就补上了。所以选方案的时候优先考虑那些不依赖平台具体实现的通用方法。从稳定性排序虚拟机或第二设备 油猴脚本 控制台注入 纯物理并排。虚拟机方案之所以最稳是因为它不跟平台的检测逻辑正面冲突平台看到的就是一个正常用户正常开着页面没有任何异常信号。代价是硬件成本但对长期需求来说这个成本摊薄到每天几乎可以忽略。如果只是偶尔应付一下控制台注入足够了记住那几个关键 APIObject.defineProperty改 hidden、stopImmediatePropagation拦事件、setInterval模拟活动。这三板斧能解决八成以上的场景。最后再分享一个小技巧排查的时候养成开 Network 面板的习惯。很多暂停逻辑的真相不在前端事件里而在网络请求里。看到周期性的心跳请求你就知道这个平台是服务端判断在线的前端怎么注入都没用直接换方案。这个判断能帮你省下大量无效折腾的时间。