说在前面
最近在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,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『
前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。