bilibili To Old Url 通过替换获取视频地址的方式, 实现跳转稍后再看旧版播放
< Feedback on 哔哩哔哩bilibili替换旧版播放(稍后再看)
遗憾,b站这个播放器交互照搬安卓端,页面照搬y2b,体验一坨屎,大概开发人员早就不是原来那一批了吧
对比了一下稍后再看前后变化,其实就一处算上css就两处,可以考虑怎么用脚本把script type="text/javascript" src="//s1.hdslb.com/bfs/static/player/main/video.js?v=20191209"></script,这样启动的还是旧版播放器。
昨天暴力尝试了一下,是可以成功的,只是新版还修改了css,在link href="//s1.hdslb.com/bfs/static/jinkela/watchlater/css/watchlater.0.ba8f2751267792c1f4a5e3a14514e47c34afba61.css" rel="stylesheet"里面,删除这个element整个网页布局会拉跨,保留的话启用的旧版播放器会缩小变形,进度条和弹幕列表全部消失,尝试在保留新版css的情况下重新引入旧版布局link href="https://s1.hdslb.com/bfs/static/phoenix/viewlater/static/css/main.d9641d2f4dc42228ea8c2650e1b98b0b.css" rel="stylesheet"文件,由于后者覆盖前者,旧版播放器基本恢复正常,但播放器下投币转发那一栏会部分挡住弹幕列表(但不会挡住播放器界面,所以三者层次应该是底层弹幕列表-中层投币转发栏-上层播放器),个人尝试就到这里
watchlater.0.ba8f2751267792c1f4a5e3a14514e47c34afba61.css这个文件里面5.8w字符!一打开就觉得头疼,而且我是个css苦手,实在不知道如何修复,目前只能说还能看吧
找到修复办法了,直接删掉新版布局启用旧版布局就完美了
@"Motoori Kokoro" 说道: 找到修复办法了,直接删掉新版布局启用旧版布局就完美了
看了你写的脚本,实现挺有趣的,可以使用
// @run-at document-start
脚本头描述使脚本在网页刚开始加载时就注入,这样window.stop();
就可以生效从而阻止整个网页包括脚本在内后续东西的加载。如果没有指定@run-at
的话脚本默认是网页加载完成才注入的自然没有办法阻止加载。另外你把document.write
写在XHR里完全没有意义,既然不依赖XHR返回内容,那么直接写入就可以了,用户脚本并不属于被覆盖网页的一部分不需要写在异步方法里,如果有脚本被覆盖的担忧,写在setTimeout
里就可以了不需要执行一个没有意义的请求,当然要是需要使用XHR返回内容进行替换那写在XHR里倒是有意义
@indefined 说道: 看了你写的脚本,实现挺有趣的,可以使用
// @run-at document-start
脚本头描述使脚本在网页刚开始加载时就注入,这样
window.stop();
就可以生效从而阻止整个网页包括脚本在内后续东西的加载。
多谢指教,看着行文风格就知道您是资深的前辈,针对您说的几个问题表达一下我的看法,希望您能再指点一二。其实我也尝试过@run-at document-start
方法,并配合window.stop();
检查chrome控制台,发现脚本注入的时机并不能保证,有时body的好几 个element都已经载入并运行了,尤其是video.js
这个脚本其实是在body的很靠前位置,所以常常会拦截失败,导致后续fetch的视频进入了network里。Google了一下好像在chrome+Tampermonkey里@run-at document-start
并不像Firefox+Greasemonkey那样迅速,且不说Firefox里还有强大的beforescriptexecute
事件,Tampermonkey文档里也说@run-at document-start
是“尽快地注入”,事实上在我尝试重写av播放页时,添加了@run-at document-start
也十有八九会落在自带的video.js之后,于是就有了明明页面完全空白了(重写空内容),还有一个idm
下载浮动条的现象——当然这在稍后再看页面不会发生,毕竟之前还有判断登录等一大堆事。XHR其实是残留问题,之前想的是用字符串接收XHR内容再进行替换,也的确是考虑到可能会需要返回内容的情况,后来发现稍后再看原生页面实在太干净了,根本就不需要返回内容,就直接把新页面写在字符串,真的不需要XHR,就像考试时没有检查就交卷了一样。不过不知道为什么如果不把write
写在XHR里,旧版播放器就启动不了,要么干脆播放器整个消失,上面的信息栏和下面工具栏直接贴合了,要么弹出flash
和HTML5
播放器选择,flash
可能有效,HTML5
点了完全没反应,这个问题解决不了,所以XHR也只能留着了。话说我在重写av页时也遇到这个问题,布局全乱时播放器正常载入,调整完播放器应该在的位置又弹出flash
和HTML5
二选一。
@"Motoori Kokoro" 说道: 多谢指教,看着行文风格就知道您是资深的前辈,针对您说的几个问题表达一下我的看法,希望您能再指点一二。 ...
不是什么前辈,我玩脚本也只是闲着没事做随便研究而已完全没有系统学习过。@run-at
确实是无法保证时效的,实际注入时机甚至还受限于系统性能,只能说聊胜于无了,只要window.stop
执行了就算有些网络请求已经发出了也会尽可能被cancle掉所以没什么所谓的。播放器异常虽然我也不太敢肯定但是大概就是因为之前的网页加载一半导致的,B站的HTML5播放器是有完整性校验逻辑的,因为之前的页面页面加载了一半被你覆盖了,但是之前的播放器脚本已经执行,所以完整性校验会失败导致在新页面上弹出FLASH选择,之前也有人写脚本时遇到过侵入播放器导致播放器自毁消失现象,所以要么就在播放器加载前完全阻止它,要么就延迟直到播放器完全载入完成再覆盖文档,写在XHR里没事大概就是因为你多做了一个网络请求延迟的时间使之前播放器能加载完全了,这种操作写在setTimeout
里大概也是等效的。不过我这边并没有办法复现你说的现象,所以基本也只是胡猜的。替换播放器我之前也想过不过懒得折腾,基本上替换上去肯定有各种奇怪问题需要修复的,我用你的方法替换普通视频页面播放器并没有办法加载,网页中的脚本会执行错误,大概并不是一套运行逻辑的,倒是你想的稍后再看页面挺妙的
@indefined 说道: 我用你的方法替换普通视频页面播放器并没有办法加载,网页中的脚本会执行错误,大概并不是一套运行逻辑的
首先感谢您的耐心指点,“HTML5播放器是有完整性校验逻辑”什么的我也不懂,看来靠我自己是没办法实现重写av页了,我尝试上传了我目前写的最简陋的重写av页实验,在我这里能做到最基本的启用旧播放器(是真的简陋!),不知道能不能做为您的参考;基于这个脚本,我说下您说的这个没有办法复现的现象的一个复现方法,就是在我重写的那个body中把id为bofqi的那个顶级div的id属性去掉,而在另一个div中标上id=bofqi(比如在id=app的下级新建一个id为bofqi的div,之所以在这里建,是因为app这个顶级div是旧版av页主体,所有网页能显示出来的内容本来都应该在这里),顺便再贴一下我从网页时光机上备份下来的av810872作为对比,我不确定这是不是原生的html,有没有被js等修改过,其中链接均以https开头是我加的,正常都是以//开头
@"Motoori Kashin" 说道: 没有办法复现的现象的一个复现方法,就是在我重写的那个body中把id为bofqi的那个顶级div的id属性去掉,而在另一个div中标上id=bofqi(比如在id=app的下级新建一个id为bofqi的div
我指的是你最前面说的替换video.min.js的那部分在AV页错误,实际是因为jquery没有载入导致的,不过就算有jq播放器载入后确实会自毁。我挺好奇你是怎么想到的把播放器拖出app外的,虽然挺笨的但是拖到外面它确实可行。下午我研究了一通虽然有些深井冰的表现大体能用,不过看上去你也差不多已经搞好了,这个 有用的话拿去参考改进一下你发布的脚本,我的话大概并不打算发布它
@indefined 说道: 我挺好奇你是怎么想到的把播放器拖出app外的,虽然挺笨的但是拖到外面它确实可行。下午我研究了一通虽然有些深井冰的表现大体能用,不过看上去你也差不多已经搞好了,这个 有用的话拿去参考改进一下你发布的脚本,我的话大概并不打算发布它
“托到app外”什么的其实是它就直接在app外生成播放器了,并非出自主动意愿,我还费尽心机想把它弄回去但都失败了。“差不多搞好”什么的其实差什么,布局是新旧混合得而且兼容不是很好,凭我的能力修复起来大概很困难吧,说实话从b站彻底放弃旧版播放器的那一天(12月7日)我就开始尝试了,昨天(12月27日)才误打误撞写成这个样子,接下来又不知道要多久才能改进。我看了您github上的脚本,写得太简洁明了了,其中有很多难解之处我还没看懂。而且您的很多脚本我都在用,尤其是那个cc字幕的,简直神器,但用我这个脚本重写后就失效了,如果是您自己发布发脚本,兼容性肯定很好,而且直接能从老板av页自动生成的话就不用像我这样新旧搭配再尝试改回去了……千言万语,还是请您收回不打算发布的想法吧。
@"Motoori Kashin" 说道: 其中有很多难解之处我还没看懂
没什么深奥的地方的,就是和你写的一样,主要原理就是分开独立由video.min.js
渲染#bofqi
然后由其它脚本渲染app
,你的脚本里是用原网页里的新脚本渲染的所以网页布局是新版的,我写的里面用的脚本都是从你昨天给的那个旧网页里直接扒的所以是旧版的,把你的脚本改成旧版的只需要把里面新版的版头和新脚本和样式删掉换成旧版的脚本和样式就可以了,至于播放器是怎么跑回里面的我也不知道反正在旧版里它加载完就自己跑进去了,只是加载的过程还是在外面的所以我把bofqi
和启动初始化脚本放在app
后面这样加载过程不会很难看,剩下的就只是修复一行样式,大概旧网页里也有对应样式表吧我懒得去找而已。至于扒原网页里的视频数据的那一行,那个全局变量是播放器依赖的,但那个操作其实可能并没有必要做,那段数据在原网页的最前端并且一开始就被执行了,在你执行XHR替换之前就已经有那个全局变量了所以没有必要扒出来再执行一次,我写在那里只是为了以后看代码的时候方便知道有这么一个依赖。
我不想发布其实主要是因为我没有用这个脚本的需要而且懒得维护它,这个东西依赖的那个全局变量显而易见B站很容易就改掉它使得这个方法失效,而且fetch的兼容性并不比XHR高,只是它很容易写所以我自己折腾时懒得顾别人就写fetch了。你发布的脚本完成度已经挺高了完善一下就可以了,我没有必要再发布一个重复功能的东西
另外你不需要这么客气,不过都是闲着互相学习折腾东西而已,我写的东西也不是什么高大上的专业东西
@indefined 说道: 你发布的脚本完成度已经挺高了完善一下就可以了,我没有必要再发布一个重复功能的东西 我不想发布其实主要是因为我没有用这个脚本的需要而且懒得维护它
嗯,看不懂源码还让您这样拆开来讲解实在是惭愧,有了这详细的讲解我再看一阵子大概会明白一些吧!您说没有需要和懒得维护什么的,其实我也大概理解,不过我不是没有需要,也不单是懒得维护,而是实在水平有限,怕无力维护下去。我说看不懂也不是谦虚,是真的不懂,就像您一眼就知道那个全局变量而我以为那是无意义的代码,从来就没想过去引入。而这个
完善一下
的过程对我而言也可能也不会比前面轻松,更何况后面还有更艰巨的维护工作。我公开脚本的初衷也只是听您说稍后再看写的有趣
而您又说替换播放器在av页会失败什么的,才把我的发现上传上来给您看看能否抛砖引玉,毕竟我可能只是有点新奇的想法,但也自知并没有能力去实现之,这也是我一开始就在这里评论的原因。版主在b吧从零开始写新版av页跳转到旧版稍后再看页面(那时稍后再看还是旧版)脚本的那天,我就一直关注着,而且也可能是第一个下载的这个脚本(如果下载显示没有延迟的话)。那时我还完全不会js,只会点c语言基础,我是真的希望能保住旧版播放器,所以尝试着帮着分析给大家提供一点思路。正如我这些对话里暴露出来的基本功不扎实,我可能真的无力完善这样一个心愿,所以再三恳求您和版主这些有能力的人可以去真正完成,那并不是不必要的功能重复的东西,也可能不单单只是我一个人的心愿。拜托了,至少您已经写出来了,而且写得那么好。
@"Motoori Kashin" 说道:
……其实我也没学过JS,替换播放器这个思路我连其实播放器初始化启动脚本在哪里都不知道,还是从你写的脚本里扒的,甚至花了点时间排除才确认那段启动的核心,因为启动那里有这个变量所以我才去原网页里找变量在哪里,一开始我也是无从下手。因为我不需要使用这个脚本,那么我也不可能会知道它后面会有什么使用问题更不可能去修它,而B站的播放器什么执行逻辑我更是不懂,这个脚本只是用你写的东西拼凑的,能帮助你理解就可以了,我发出来也只是想你复制去用罢了毕竟我也是从你那复制来的,当然看懂比较重要。至于后续维护我也不见得有能力,相比起来你比我更有动手能力愿意去折腾它,以后遇到问题你折腾不出来再问我或者问别人,能力范围内别人还是会解答的,或者找别的愿意接手的人开发维护,我也不见得会在这里活跃多久
看来已经结束了
稍后再看的播放器也变了