基于油猴脚本与Python的B站视频横竖屏智能适配方案

张开发
2026/4/10 12:03:05 15 分钟阅读

分享文章

基于油猴脚本与Python的B站视频横竖屏智能适配方案
1. 为什么需要横竖屏智能适配方案作为一个经常刷B站的用户我发现网页版B站有个很烦人的问题视频的横竖屏格式不统一。有些视频是横屏的比如电影、电视剧有些又是竖屏的比如短视频、手机录制的vlog。我平时用双屏办公一个横屏显示器用来工作一个竖屏显示器专门刷视频。每次遇到竖屏视频都得手动把浏览器窗口拖到竖屏显示器上特别麻烦。这个问题其实困扰了很多双屏用户。根据我的实测在1080P的横屏显示器上看竖屏视频实际显示面积只有屏幕的1/3左右两边都是黑边特别浪费屏幕空间。反过来在竖屏显示器上看横屏视频也一样上下都是黑边。手动拖拽窗口不仅效率低还经常打断观看体验。更糟的是B站网页版本身没有提供自动适配功能。虽然手机APP能自动旋转屏幕但电脑端完全需要手动操作。作为一个技术爱好者我决定用油猴脚本Python开发一套自动化解决方案实现以下功能自动检测当前播放视频的宽高比根据横屏/竖屏自动将窗口移动到对应显示器自动最大化窗口以获得最佳观看体验整个过程无需人工干预完全自动化2. 技术方案整体设计这个方案采用了前后端分离的架构前端用油猴脚本检测视频尺寸后端用Python处理窗口管理。具体工作流程是这样的2.1 前端检测部分油猴脚本会持续监控页面中的video元素当检测到视频尺寸变化时比如切换视频或调整窗口大小就会把当前视频的宽高信息通过HTTP POST发送到本地服务。关键代码逻辑如下const check () { const video document.querySelector(video); if (!video) return; const { videoWidth, videoHeight } video; if (videoWidth videoHeight) notify(videoWidth, videoHeight); }; // 首次加载和每次清晰度切换都会触发尺寸变化 setTimeout(check, 1500); new MutationObserver(check).observe(document.body, { childList: true, subtree: true });这段代码做了三件事获取页面中的video元素读取视频的实际宽高不是显示尺寸如果尺寸有效就发送到后端服务2.2 后端处理部分Python服务监听本地8848端口收到宽高数据后计算宽高比判断是横屏还是竖屏找到Chrome浏览器窗口句柄将窗口移动到对应的显示器最大化窗口消除边框核心的窗口管理代码def move_and_max(hwnd, mon): 将窗口移动到目标显示器并全屏 style win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE) # 移除窗口标题栏和边框 win32gui.SetWindowLong(hwnd, win32con.GWL_STYLE, style ~win32con.WS_CAPTION ~win32con.WS_THICKFRAME) # 移动并调整窗口尺寸 win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, mon[x], mon[y], mon[w], mon[h], win32con.SWP_SHOWWINDOW) win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE)3. 详细实现步骤3.1 油猴脚本安装与配置首先需要安装油猴脚本管理器推荐使用Tampermonkey在Chrome应用商店搜索Tampermonkey并安装点击插件图标选择创建新脚本粘贴以下元信息// UserScript // name B站横竖屏自动适配 // namespace http://your-namespace/ // version 1.0 // description 自动根据视频方向切换显示器 // author YourName // match *://www.bilibili.com/video/* // grant GM_xmlhttpRequest // /UserScript在脚本编辑器中添加前面提到的检测代码保存脚本它会自动在B站视频页面生效3.2 Python服务部署后端服务需要以下环境准备安装Python 3.6安装必要库pip install pywin32创建一个Python文件比如bilibili_auto_rotate.py服务端完整代码结构import json, time from http.server import BaseHTTPRequestHandler, HTTPServer import win32gui, win32con # 显示器配置根据实际调整 MONITORS { landscape: {x: 0, y: 0, w: 1920, h: 1080}, # 主屏 portrait: {x: 1920, y: 0, w: 1080, h: 1920} # 副屏 } class Handler(BaseHTTPRequestHandler): def do_POST(self): # 解析视频尺寸数据 data json.loads(self.rfile.read(int(self.headers[Content-Length]))) w, h data[width], data[height] # 判断横竖屏 target_mon MONITORS[landscape] if w h else MONITORS[portrait] # 找到Chrome窗口 hwnd find_chrome_window() if hwnd: move_and_max(hwnd, target_mon) self.send_response(204) self.end_headers() if __name__ __main__: HTTPServer((, 8848), Handler).serve_forever()3.3 显示器配置调整关键是要正确配置MONITORS字典这需要了解你的显示器布局使用WindowsP键可以查看当前显示器排列x,y表示显示器左上角在虚拟桌面中的坐标w,h是显示器的分辨率比如我有两个1080P显示器主屏横屏(1920x1080)副屏竖屏(1080x1920)副屏在主屏右侧所以x坐标是1920。4. 实际使用效果与优化经过一段时间的实际使用这个方案表现相当稳定。当我打开横屏视频时窗口会自动跳到横屏显示器并全屏显示打开竖屏视频时又会自动切换到竖屏显示器。整个过程几乎感觉不到延迟体验非常流畅。不过也遇到了一些小问题经过多次迭代优化4.1 防抖优化最初版本在视频加载过程中会频繁触发窗口移动因为视频尺寸会经历多次变化。后来增加了时间戳判断2秒内不重复处理同一个视频if hasattr(self.server, _last_hwnd) and self.server._last_hwnd hwnd and \ time.time() - self.server._last_time 2: return4.2 窗口样式优化发现全屏后窗口边框有时会残留于是强制移除了窗口标题栏和边框style win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE) win32gui.SetWindowLong(hwnd, win32con.GWL_STYLE, style ~win32con.WS_CAPTION ~win32con.WS_THICKFRAME)4.3 多标签页支持当有多个B站标签页时脚本需要确保只操作当前可见的标签页。修改了窗口查找逻辑def find_chrome_window(): def enum_cb(hwnd, wins): if win32gui.IsWindowVisible(hwnd) and bilibili in win32gui.GetWindowText(hwnd).lower(): wins.append(hwnd) wins [] win32gui.EnumWindows(enum_cb, wins) return wins[0] if wins else None这套方案我已经稳定使用半年多大大提升了刷B站的体验。特别是看竖屏短视频时不再需要手动调整窗口真正实现了无感切换。对于经常使用双屏的用户来说这种自动化改进虽然小但确实能显著提升使用体验。

更多文章