说在前面
最近在B站刷视频,发现B站的倍速选择最高只能 2 倍速,最低只能 0.5 倍速,默认提供的倍速选择不满足需求怎么办呢?既然不能让B站直接帮我们修改,那就只能我们自己写个插件来修改下了。
效果展示
插件使用
1、插件下载
直接点击下载,下载 dist.zip 压缩包。
下载的时候方便的话可以顺便给我点个小星星🥰🥰🥰
2、解压压缩包
将下载好的 dist.zip 压缩包解压
3、加载插件到chrome
打开chrome扩展程序面板 chrome://extensions/,点击 加载已解压的扩展程序
选择刚刚解压的好的 dist 目录即可
4、插件固定显示
将插件固定显示在插件栏上。
5、倍速设置
打开设置面板,输入需要的倍速,多个用 、 隔开,点击确定即可。
修改成功后再看一下倍速列表,倍速就已经是自己设置的倍速了,可以选择自己喜欢的倍速来观看视频。
插件源码
Gitee
该插件已开源到gitee,有兴趣的也可以到这里看看:gitee.com/zheng_yongt…
🌟觉得有帮助的可以点个star~
🖊有什么问题或错误可以指出,欢迎pr~
📬有什么想要实现的组件或想法可以联系我~
公众号
关注公众号『前端也能这么有趣
』,发送 chrome插件 ,即可获取插件源码地址。
目前也新建了一个wx群,公众号发送 加群 即可加入群聊,一起讨论学习。
看到这里,插件的使用效果和使用方法大家都知道了吧,如果对插件的实现原理感兴趣的话,可以继续往下看,不感兴趣的同学可以直接下载插件体验试试,欢迎反馈交流,后续会继续扩展更多有趣插件功能。
插件实现
1、快速生成插件模版
可以通过jyeontu
脚手架快速生成一个插件模版,没安装的需要先安装下。
npm install -g jyeontu
通过命令生成浏览器插件模版。
jyeontu create
2、项目初始化
等待安装所需依赖
cd bilibiliVideoSpeedRate
npm run init
3、弹窗页面编写
在插件栏点击图标后会弹出一个弹窗
(1)弹窗目录
我们生成的插件模板目录中有一个 popup 目录,这个目录为一个vue
项目,弹窗页面在这个项目里编写即可。
(2)弹窗页面调试
调试弹窗页面,我们只需要直接运行该项目,当成一个独立的 vue 项目进行调休开发即可
cd popup
npm run serve
(3)倍率列表修改
修改完倍率列表,我们需要点击确定按钮将最新的倍率列表发送给 bilibili 标签页进行修改。
<textarea v-model="speedRateList" class="textarea-content"></textarea>
<button @click="sendData" class="button">确定</button>
import { sendMessage } from "../../utils/chrome.js";
sendData() {
localStorage.setItem("bilibiliVideoSpeedRateList", this.speedRateList);
sendMessage({
action: "setSpeedList",
data: this.speedRateList,
});
},
生成的插件模板中已经写好了 sendMessage 方法,直接调用该方法发送消息即可。
4、脚本编写
编写好了一个简单的弹窗配置页面之后,我们就可以开始写脚本了。
(1)脚本目录
我们直接在 bg.js 中编写脚本即可
(2)接收配置消息
前面我们在配置面板修改配置的时候,点击确认后会发送消息到标签页,标签页也需要接收消息。
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
const { action, data } = request;
sendResponse({ state: "视频倍速列表已更新" });
if (action === "setSpeedList") {
changSpeedRateList(data.split("、"));
}
});
- chrome.runtime.onMessage.addListener 是 Chrome 扩展开发中一个非常重要的 API 方法,用于注册一个消息监听器。它接受一个回调函数作为参数,每当有其他部分(比如扩展的不同脚本之间或者内容脚本与后台脚本之间等)通过 chrome.runtime.sendMessage 或者 chrome.tabs.sendMessage 等方式发送消息时,这个注册的回调函数就会被触发执行。
- 回调函数接收三个参数:
- request:代表接收到的消息内容,通常是一个对象,包含了发送方传递过来的各种数据和指令等信息。
- sender:表示消息的发送方相关信息,比如发送消息的脚本所在的标签页、扩展 ID 等,通过这个对象可以了解消息的来源情况。
- sendResponse:这是一个用于回复消息的函数,调用它并传入一个对象作为参数,就可以将响应消息发送回给发送方,让发送方能够获取到相应的反馈信息。
(3)视频倍速列表修改
- b站视频页面分析
直接打开 F12,可以找到视频元素和倍速列表元素
可以获取到两个元素的 selector
const videoDomSelector =
"#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div > video";
const speedListSelector =
"#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-control-wrap > div.bpx-player-control-entity > div.bpx-player-control-bottom > div.bpx-player-control-bottom-right > div.bpx-player-ctrl-btn.bpx-player-ctrl-playbackrate > ul";
const videoDom = document.querySelector(videoDomSelector);
const speedListDom = document.querySelector(speedListSelector);
- 倍速列表内容替换
我们需要用我们设置的倍速列表将原有的倍速列表替换掉,点击倍速的时候直接修改 video 元素的 playbackRate 即可修改视频的倍速。
if (!mySpeedList) {
const defaultList = [0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 5, 16];
const storageList = localStorage.getItem("bilibiliVideoSpeedRateList");
if (storageList) {
mySpeedList = JSON.parse(storageList);
} else {
mySpeedList = defaultList;
}
}
localStorage.setItem(
"bilibiliVideoSpeedRateList",
JSON.stringify(mySpeedList)
);
const videoDom = document.querySelector(videoDomSelector);
const speedListDom = document.querySelector(speedListSelector);
const speedItemDom = speedListDom.firstElementChild;
speedListDom.innerHTML = "";
mySpeedList
.sort((a, b) => b - a)
.forEach((item) => {
const node = speedItemDom.cloneNode();
node.setAttribute("data-value", item);
node.innerText = `${item}x`;
node.addEventListener("click", () => {
videoDom.playbackRate = item;
});
speedListDom.appendChild(node);
});
5、打包插件
npm run build
- 打包完成后会生成一个dist文件
- 将生成的dist文件夹加载进浏览器即可。
公众号
关注公众号『前端也能这么有趣
』,获取更多有趣内容。
公众号发送 加群 即可加入群聊,一起讨论学习。
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。