本来竖屏的素材传到B站,播放器里却横着显示,一半画面被裁掉;或者录屏时方向没锁住,画面躺平了;又或者只是想临时把某个直播画面转个方向看,而B站设置里根本没有"旋转视频"这个按钮。我最初碰到这个问题时也想找插件,后来发现用浏览器控制台写一行代码就能搞定。这篇文章就围绕"b站观看视频旋转90°"这个操作场景,讲清楚控制台里到底做了什么、每一步的原理是什么、旋转之后还会牵连哪些布局问题,以及各种容易踩的坑,最后给一套可以直接复制的完整方案。
1. 同一行文字的两个读者群:为什么有人觉得控制台很难,有人觉得它理所当然
1.1 控制台是什么,它和你日常用的浏览器有什么关系
控制台是浏览器开发者工具中的一个面板,Chrome、Edge、Firefox都有,按一下F12或者右键页面空白处选"检查",就能打开。它最初是给网站开发人员调试代码用的,能在网页加载完之后,直接查看和操作页面里的所有元素,也能临时执行JavaScript代码。因为不需要下载任何额外软件,普通用户也能用它做很多"官方没做但非常实用"的操作。
很多人一听"控制台"就觉得是黑客干的事,其实不是。它就是一把螺丝刀,你可以用它拧开电脑机箱,也可以用它撬开一个饼干盒。本文的场景就是用它撬开B站播放器,把视频方向改过来。
1.2 需求场景盘点:什么样的视频需要旋转90度
结合我自己的经历和周围朋友问过我的情况,需要旋转视频的常见场景大概有下面几类:
- 竖屏素材横放:手机拍摄的竖屏视频,直接上传到B站后,播放器按横屏处理,画面左右两侧被拉伸或中间被裁切,需要旋转90度才能正常观看。
- 录屏方向错误:录制电脑屏幕时,如果显示器是竖屏,或者录屏软件设置不当,录出来的画面躺倒,后期又不想重新录。
- 外部源画面方向不对:一些直播间、课程平台或特殊播放源的视频方向本身就是横的,但内容实际是竖的。
- 临时镜像需求:比如对照视频做动作练习,希望画面左右镜像,这和旋转是同一套操作逻辑。
这些场景用B站自带的设置都无解,因为B站播放器目前只提供倍速、清晰度、画面比例(拉伸/裁切)等选项,没有"旋转"这个功能。
2. 从打开控制台到锁定视频节点:先看到目标再动手改
2.1 打开开发者工具的三种入口,以及各自的优势
打开控制台的方式有三条路,按使用习惯任选一条:
- 快捷键:在B站播放页按下
F12,这是最快的方式。注意部分笔记本需要同时按Fn + F12。 - 右键菜单:在页面上任意位置右键,点击"检查",会直接打开Elements(元素)面板。
- 浏览器菜单:Chrome右上角三个点 -> 更多工具 -> 开发者工具。
打开之后界面上方有不少标签页:Elements(元素)、Console(控制台)、Sources(源码)、Network(网络)等。我们这次既要用Elements定位视频元素,也要用Console执行旋转代码。
2.2 在Elements面板里找到B站播放器的video标签
视频在网页里本质上是一个<video>标签,B站播放器虽然包了很多层UI,但最终渲染画面的是这个标签。在Elements面板左侧的DOM树里,可以用两种方式快速定位:
- 点击Elements面板左上角的箭头图标(鼠标指针形状),然后回到页面上点击视频画面,DOM树会自动跳到对应的节点位置。
- 直接在Elements面板按
Ctrl + F,输入video,回车查找。B站页面里video节点通常不会太多,找到那个class里带video字样的<video>即可。
找到后你会看到类似这样的结构:
<video src="blob:https://www.bilibili.com/xxxx" class="bpx-player-video"></video>这个节点就是我们接下来要操作的核心目标。
2.3 为什么要先验证节点,而不是直接写旋转代码
如果跳过定位直接写代码,很可能出现两种情况:一是旋转命令作用在错误的元素上,页面毫无反应;二是作用在容器上而非视频本身,导致画面被剪切或跑到页面外。所以最好是先做一次快速验证,确认识别正确。
在Console面板(如果还没切换到Console,点上方标签进入)输入下面这段代码并回车:
document.querySelector('video')如果控制台返回了一个<video>对象,说明找到唯一一个视频节点,可以继续。如果返回null,说明页面上暂时没有视频节点,可能是视频还没开始加载;如果返回一个数组或报错,说明页面有多个video节点,或者B站的播放器结构和标准情况不一样,需要回到Elements面板重新定位。
再深入一步,B站的招牌播放器组件类名比较稳定,像bpx-player-video这种class在页面里是唯一的,可以直接用:
document.querySelector('.bpx-player-video')这段代码返回的也是那个<video>节点。确认节点之后,再执行旋转操作就非常稳妥。
3. 旋转90度的核心代码:一个CSS属性背后的几何逻辑
3.1 transform: rotate(90deg) 究竟对视频做了什么
transform这个CSS属性可以对元素做平移、缩放、旋转、倾斜等变换,而rotate(90deg)就是其中的旋转变换。写rotate(90deg)时,CSS会以元素的中心点为轴,把整个元素顺时针旋转90度。
这里的关键是旋转的单位,CSS支持deg(度)、turn(圈)、rad(弧度)。日常用deg最直观,90就是直角,180就是倒过来,360就是转一圈回到原位。
执行旋转的代码可以写成这样:
const video = document.querySelector('.bpx-player-video'); video.style.transform = 'rotate(90deg)';把这两行粘贴到Console里,回车,视频画面就会立刻旋转90度。
3.2 旋转之后为什么画面会溢出,这其实是个几何问题
不过很多人在这一步会愣住:视频确实转了,但是页面布局完全乱了,画面一半跑到了屏幕外面,播放器原来的位置留着一块空白,控制条也跑到视频旁边而不是视频下方。这不是旋转代码写错了,而是CSS旋转元素的原理决定的——元素旋转后,它在文档流里占据的空间仍然保持原来的宽高和位置,只是视觉上被旋转了。打个比方,一张横放的A4纸旋转90度后,视觉上是竖着的,但原先放A4纸的桌面格子还是横着的尺寸,纸自然就伸出去了。
所以旋转之后必须手动调整它的布局参数,主要就是width和height。B站播放器容器的实际宽高会因浏览器窗口大小而变化,旋转后应该让视频宽度等于原来容器的高度,让视频高度等于原来容器的宽度。
3.3 为什么transition能让旋转过程更顺滑
直接设置transform的话,画面切换是瞬间完成的,虽然功能上没问题,但看着有些突兀,也很容易在一瞬间让人误以为页面崩了。给视频加上过渡属性会让视角转换更舒服:
const video = document.querySelector('.bpx-player-video'); video.style.transition = 'transform 0.5s'; video.style.transform = 'rotate(90deg)';transition的意思是CSS属性变化时不要瞬间完成,而是在指定的时间内平滑过渡。0.5s就是一个比较合适的时长,既不会太慢也不会让人觉得卡顿。这个过渡对后续调整布局也有好处,能看出每一步变化的效果,便于判断参数是否合适。
3.4 完整的一步到位旋转代码
下面这段是我个人用得最多、也推荐你先试的完整控制台代码,核心目的就是"旋转90度 + 自动修正占位尺寸"。粘贴到Console后直接回车:
const video = document.querySelector('.bpx-player-video'); const container = video.closest('.bpx-player-container') || video.parentElement; const rect = container.getBoundingClientRect(); video.style.transition = 'transform 0.5s, width 0.5s, height 0.5s'; video.style.transformOrigin = 'center center'; video.style.transform = 'rotate(90deg)'; video.style.width = rect.height + 'px'; video.style.height = rect.width + 'px';closest('.bpx-player-container')是向上找B站播放器最外层容器,找不到就用parentElement兜底。getBoundingClientRect()获取容器实际渲染的宽高等几何信息。- 把视频宽度改成容器高度、视频高度改成容器宽度,这样旋转后画面刚好对齐原来播放器的可视区域。
transformOrigin设置为center center,让旋转以元素中心为基准,否则默认的旋转中心点也是元素中心,但显式写出来更清楚,也方便后面调整。
执行完这段代码,视频画面应该正好填满播放器的可视区域,方向正确,控制条虽然位置有点怪但基本可用。
4. 旋转后的界面适配:控制条、弹幕、全屏这些连锁问题要一起处理
4.1 旋转后布局失衡的本质是容器和视频解耦了
视频元素被旋转后,B站播放器的UI层还是按原来的横屏布局排列控制条、弹幕层、遮罩层,而这些UI层是叠在视频上面的,所以会出现控制条错位、弹幕方向没跟着转、右键菜单跑到奇怪位置等现象。根本原因是旋转只作用于video标签,播放器外壳并没有感知到画面方向变了。
想彻底让UI也适配竖屏方向,只靠改video本身是不够的,需要把旋转效果加到播放器容器那一层,让整个播放器界面一起翻转。思路是找到bpx-player-container级别的元素,对它做旋转和宽高交换,而不是只对video做。但这样操作后,弹幕文字也会跟着旋转,控制条的交互朝向也一样会翻转,属于"一损俱损"的方案,不过至少画面和UI是协调的。
我个人更推荐另一种折中方案:只用视频层旋转,UI保持横屏不变。因为很多转90度场景(比如竖屏视频横放)只关心画面不歪,弹幕和控制条的位置虽然看着别扭,但功能不受影响,鼠标点击的区域也仍然有效,只是控制条在视觉上横在画面外面。
4.2 弹幕和字幕方向不跟着转,有什么临时对策
如果旋转的是视频层,B站的弹幕会正常水平滚动,视觉上弹幕出现在画面右侧或下方,观感不佳。想连弹幕一起转,需要把弹幕容器也加入旋转范围。弹幕渲染节点通常是一个class里带danmaku的容器,执行下面的脚本可以把弹幕也翻转:
const danmaku = document.querySelector('.bpx-player-danmaku'); if (danmaku) { danmaku.style.transform = 'rotate(90deg)'; danmaku.style.transformOrigin = 'center center'; danmaku.style.width = '100vh'; danmaku.style.height = '100vw'; }实际测试下来,B站不同播放器版本里弹幕层结构和类名会变,这条不是百分百生效。想要稳定连弹幕一起旋转,操作对象就必须升级到播放器容器层。
4.3 全屏模式和旋转的冲突
旋转后如果你点B站播放器的全屏按钮,浏览器会进入全屏状态,但视频依然是旋转后的状态,画面可能朝向不对、尺寸失衡。因为全屏状态下B站播放器会重新计算布局,给video设置新的宽高,覆盖掉你手动设置的width和height,但transform属性不一定被清除。结果通常是:视频在全屏后转动了但尺寸没有修正,画面被拉伸。
我在实测中遇到过一种更迷惑的情况:全屏后视频不仅方向不对,连鼠标控制的进度条都变得"乱跳",点击进度条某个位置会跳到另一段。原因在于全屏时B站播放器渲染的坐标矩阵经过旋转后出现了偏移,鼠标坐标映射到视频时间轴时发生了错位。简单说,画面转了,可点击的坐标系统没转,两者对不上。
解决思路有两个:
- 全屏后重新执行修正代码,让width和height适应当前全屏容器的实际值。
- 不用B站自带的全屏,而是在控制台用
video.requestFullscreen()。这样全屏的是video元素本身,其他UI不参与,旋转和尺寸会保持一致,体验反而更好。
实际使用中,如果只是临时旋转看一下,我建议不要全屏,把浏览器窗口调大一点,效果已经足够。
4.4 旋转完想还原,别刷新页面也能做到
还原最粗暴的方式是刷新页面,但那样所有状态都丢了。更优雅的做法是把transform和尺寸都清掉:
const video = document.querySelector('.bpx-player-video'); video.style.transform = 'none'; video.style.width = ''; video.style.height = ''; video.style.transition = 'none';这样视频会瞬间回到原始状态。如果你之前设置了transition,可能会看到一段动画式的回弹,也算是个不错的视觉效果。
5. 容易被忽略的边界情况:B站升级导致的报错、控制台被禁用、多P视频和动态页面
5.1 B站改版后类名失效怎么办
我最初写这套代码时,B站播放器容器的类名和现在不完全一致。比如早期版本里外层容器是bilibili-player,后来变成了bpx-player-container,视频节点的class也从video-player改成了bpx-player-video。如果你在控制台执行代码发现没反应,先回Elements面板查看播放器区域DOM树的真实类名,按实际类名替换代码里的选择器即可。
更稳妥的写法是不依赖类名,而是从DOM关系入手:
const video = document.querySelector('video'); // 向上找两层,通常就能找到播放器外层 const container = video.parentElement.parentElement;这种写法的缺点是找错层级风险高,优点是B站无论如何换皮肤、换类名,只要页面用的还是<video>标签,就能定位到。
5.2 有些环境控制台是被禁用的,怎么绕过
B站主站没有禁用控制台的逻辑,但如果你是在B站的一些嵌入页面、直播页的特殊模式或者通过第三方客户端访问,可能会遇到右键检查无效、F12没反应、Console输出被清空的情况。这里要区分两种"禁用":
- 网站故意拦截了F12快捷键:可以试
Ctrl + Shift + I,或者浏览器菜单里手动打开开发者工具。 - 网站循环输出刷屏信息,让你找不到自己的代码位置:这种情况打开Console后先点清空按钮,再执行代码即可。
还有一种情况是提示"请打开控制台查看"之类的文字,那是站点在Console里打印的调试信息,不是禁用的意思,直接继续操作就行。不需要去研究那些绕过禁用控制台的黑魔法,B站场景根本用不到。
5.3 多P视频、BV号跳转和SPA页面下的元素替换
B站是单页应用(SPA),你在视频页切换到分P、切换清晰度、从普通视频切到番剧时,页面不会整体刷新,而是异步替换播放器内容。这意味着第一次旋转成功后,如果你切换了分P,视频节点可能被重建,之前设置的transform和宽高会失效,画面又变回歪的。
解决办法是把操作封装成一个函数,随时可以在控制台手动调用。切换分P后如果发现画面歪了,再执行一次即可。
5.4 直播页和普通视频页的差异
B站直播页面的播放器同样是<video>标签,但外层结构和普通视频不一样,类名不是bpx-player-container,而是web-player-controller之类的结构。用closest('.bpx-player-container')会匹配不到,退回到parentElement又能勉强工作,但宽高获取可能不准确。
直播页面旋转后还有一个特殊现象:直播流是实时的,旋转对直播流本身不影响,只是观看角度变化,这没问题。但如果直播的原始流是横屏而你想竖屏看,旋转90度后画面通常会有一定缩放裁切,因为直播画面上下被裁掉以确保视觉比例正常。这属于正常的显示裁切,不是代码问题。
6. 旋转之外的控制台玩法:任意角度、镜像、清晰度切换和自动化
6.1 想要任意角度旋转,代码只是改一个数值
把90换成45、135、180都可以。比如180度适合处理倒置录屏,镜像功能在动作教学场景很常用。CSS里还有一个scaleX(-1)可以实现水平镜像翻转,逻辑上就是把x轴方向反转。和旋转组合使用时,能实现一些比较特殊的画面效果。
const video = document.querySelector('.bpx-player-video'); // 水平镜像 video.style.transform = 'scaleX(-1)'; // 旋转180度 video.style.transform = 'rotate(180deg)';注意transform是单一属性,写第二次会覆盖第一次。如果想组合多个变换,需要写在一行里:
video.style.transform = 'rotate(90deg) scaleX(-1)';6.2 把旋转逻辑封装成可复用的控制台函数
为了避免每次都要重新粘贴一大段代码,可以把逻辑封装成一个函数,存到浏览器控制台里,这个会话内随时调用。如果浏览器重启了,再粘贴一次即可。如果你经常需要这个功能,也可以把函数存成代码片段(Snippets),在Sources面板里新建一个文件保存,下次直接用Ctrl + Enter运行。
function rotateBilibiliVideo(deg = 90) { const video = document.querySelector('.bpx-player-video'); if (!video) { console.log('没有找到视频节点,请确认页面已经加载出播放器'); return; } const container = video.closest('.bpx-player-container') || video.parentElement; const rect = container.getBoundingClientRect(); video.style.transition = 'transform 0.5s, width 0.5s, height 0.5s'; video.style.transformOrigin = 'center center'; video.style.transform = 'rotate(' + deg + 'deg)'; if (deg % 180 === 0) { video.style.width = rect.width + 'px'; video.style.height = rect.height + 'px'; } else { video.style.width = rect.height + 'px'; video.style.height = rect.width + 'px'; } } // 调用示例 rotateBilibiliVideo(90);这里对180度做了一次分支处理,因为旋转180度时宽高不需要交换,否则尺寸会反过来。
6.3 控制台跳转和定位播放进度的另类用法
热搜词里有一条是"网页视频如何通过控制台跳转",这里顺带说一个控制台的实用技巧。如果想精确跳转到视频的某个时间点,可以直接操作video元素:
const video = document.querySelector('.bpx-player-video'); video.currentTime = 120; // 跳到第120秒这在处理长视频时比拖动进度条精准得多。同理,想临时改变播放速率也可以这么做:
video.playbackRate = 2; // 两倍速这些操作和旋转共用同一套控制台逻辑,定位到video节点后,几乎所有播放器底层属性和方法都能直接调用。
6.4 为什么不推荐用油猴脚本或浏览器插件代替控制台操作
很多人觉得控制台操作每次都要手动执行,不如直接装个浏览器插件或者油猴脚本来得省事。这个思路没问题,但要注意两点:
第一,B站的播放器结构和类名经常调整,第三方插件如果没跟上更新,容易失效,而控制台代码你可以随时根据当前页面结构调整。第二,插件涉及安装来源问题,从非官方渠道下载的插件有安全风险,而控制台代码你完全能看到在做什么,不涉及隐藏行为。
如果是长期使用、频繁需要旋转的场景,我建议用代码片段(Snippets)来保存函数,而不是装一个专门为"旋转B站视频"做的浏览器扩展。毕竟这个需求本质上是临时性的,成本越低越好。
7. 实操中的几个小细节:尺寸精确到px之后的视觉微调经验
真正跑到一线操作时,有几个细节影响最终观感,写代码时不一定能想到。
第一,旋转后的视频尺寸如果依然有一两像素的偏差,画面边缘可能出现细线或者模糊感。B站播放器容器可能有边框或圆角,视频旋转后四角露出底色。可以给video加一点缩放缓冲:
video.style.transform = 'rotate(90deg) scale(1.01)';scale(1.01)能轻微放大画面,盖住边缘细线,代价是画面顶部和底部会被裁掉一点,观感上通常看不出来。
第二,执行旋转代码的时机很重要。如果视频画面还在加载中就执行,getBoundingClientRect()拿到的容器尺寸可能不对。建议等画面稳定后再操作,或者把旋转命令放到视频的loadedmetadata事件后执行:
const video = document.querySelector('.bpx-player-video'); if (video.readyState >= 1) { rotateBilibiliVideo(90); } else { video.addEventListener('loadedmetadata', () => rotateBilibiliVideo(90)); }第三,如果浏览器窗口缩放后,旋转效果出现错位,重新执行一次旋转函数即可修复。因为容器宽高变了,视频尺寸需要重新计算。这也是为什么封装成函数比一行代码更实用——遇到变化时快速重跑。
这些细节看起来零碎,但真正决定一次控制台操作是"能用"还是"好用"。我最初做这个功能时也只觉得旋转一下就行,后来在几个不同分辨率窗口和不同清晰度之间切换,才一点点补齐了这些边界处理。
8. 写在最后:控制台操作解决的不只是B站视频这一个问题
回到开头那句话,把B站视频旋转90度这件事,表面上是一个很窄的需求,但它背后其实是一套通用的浏览器调试思维方式:定位目标元素、读取它的状态、修改它的属性、验证效果、处理副作用。这个过程不止适用于视频旋转,也适用于绝大多数"网页上看着不舒服想手动改一下"的场景。比如临时隐藏某个页面元素、修改页面的背景色、导出页面里的图片资源、调试一个页面交互逻辑,控制台都能派上用场。
对我个人而言,学会在控制台里改视频方向以后,最大的收获是理解了一条规则:网页上看到的一切,几乎都是可以被检查和修改的。B站播放器不提供旋转按钮,不等于它做不到旋转,只是产品没有把开关暴露给用户。控制台就是那个绕开产品设计的入口。
如果你只是想把视频转正,按文章里前几节的代码操作几分钟就能完成;如果你还想进一步折腾,把这套思路用在其他网站上也是一样的路径。下次再遇到"页面功能没有某个按钮"的尴尬局面,先打开控制台看看元素结构,说不定答案就写在DOM里面。