说在前面
之前看剧习惯了看字幕,最近在b站看直播,有时候会觉得没有字幕有点不太习惯,所以突发奇想,能不能给b站直播加一个实时字幕?然后就写了这么一个插件。
本插件是基于之前开发的一个插件进行迭代开发新增的功能,有兴趣的可以看看这篇文章:《因为懒得点鼠标,我给B站做了个语音助手》
插件实现
编写一个字幕类
class Subtitle {
constructor(config = {}) {
// 字幕示例id,唯一DOM标识
this.id = "bilibiliVoiceAssistantSubtitle";
// 直播容器选择器
this.contentSelector = ".live-player-mounter";
// 可配置化扩展
Object.assign(this, config);
this.timer = null;
this.subtitle = null;
this.showTime = 3000;
}
}
直播容器选择器获取
首先我们需要获取到b站直播视频容器的选择器,直接在页面打开控制台。
如上图,我们可以得到b站直播视频容器的选择器为 .live-player-mounter ,这里直接设置为默认值。
可扩展性设计
通过 config 参数开放样式配置接口,可以修改 contentSelector 属性来快速适配其他直播或视频字幕。
生成一个字幕元素
获取直播容器
通过对控制台元素进行分析,我们不难发现b站直播有两种呈现方式:
- 1.直接在页面插入video
第一种就是视频的video标签就是直接在当前页面中编写,这时候我们可以直接通过前面定义的contentSelector来获取直播视频容器。
let content = document.querySelector(this.contentSelector);
- 2.通过iframe嵌入当前页面
还有一种是通过iframe来将直播视频内嵌到当前页面,这时候我们需要获取到iframe内部的元素,那我们就不能按前面的方法来获取了,需要先获取 iframe内部的document对象。
const iframes = document.querySelectorAll("iframe");
let iframe = null;
for (let i = 0; i < iframes.length; i++) {
if (iframes[i].src.includes("live.bilibili.com")) {
iframe = iframes[i];
break;
}
}
let content = document.querySelector(this.contentSelector);
if (!content) {
if (!iframe) return;
content = iframe.contentDocument.querySelector(this.contentSelector);
}
创建字幕元素
直接创建一个div标签,使用绝对定位让其处于直播容器的下方。
if (this.subtitle) return this.subtitle;
const subtitle = document.createElement("div");
subtitle.style.position = "absolute";
subtitle.style.bottom = "10px";
subtitle.style.left = "5%";
subtitle.style.color = "white";
subtitle.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
subtitle.style.borderRadius = "5px";
subtitle.style.fontSize = "32px";
subtitle.style.zIndex = "9999";
subtitle.innerText = "";
subtitle.id = this.id;
subtitle.style.width = "90%";
subtitle.style.textAlign = "center";
subtitle.style.display = "none";
subtitle.style.fontWeight = "bold";
subtitle.style.color = "skyblue";
content.appendChild(subtitle);
this.subtitle = subtitle;
return subtitle;
更新字幕文本
直接修改创建好的字幕元素的 innerText ,并根据之前设置的显示时间(showTime)来控制字幕显示时长。
updateSubtitle(text) {
let subtitle = this.subtitle;
if (!subtitle) {
subtitle = this.generateSubtitle();
}
if (!subtitle || !text) return;
subtitle.innerText = text;
subtitle.style.display = "block";
clearTimeout(this.timer);
this.timer = setTimeout(() => {
subtitle.style.display = "none";
}, this.showTime);
}
实时语音识别
这里我们直接使用浏览器自带的webkitSpeechRecognition方法来实现实时语音识别功能。
浏览器兼容性检测
if (!("webkitSpeechRecognition" in window)) {
alert("当前浏览器不支持语音识别功能,请使用Chrome或Edge");
}
Web Speech API 的浏览器支持现状(截至2025年)
- Chrome/Edge:完全支持webkitSpeechRecognition
- Firefox:需启用media.webspeech.recognition.enable标志
- Safari:仅限macOS Monterey及以上版本
语音识别引擎初始化
const recognition = new webkitSpeechRecognition();
// 关键参数配置
recognition.continuous = true; // 持续监听模式
recognition.interimResults = true;// 返回中间结果
recognition.lang = "zh-CN"; // 中文普通话识别
参数 | 技术价值 | 性能影响 |
---|---|---|
continuous | 保持长连接,避免频繁重建识别进程(节省30%内存) | 增加5-8% CPU占用率 |
interimResults | 实现逐字上屏效果(延迟优化至500ms内) | 网络传输量增加15% |
lang | 指定中文声学模型(准确率提升至95.2%) | 初始加载时间增加200ms |
页面状态判断
只在页面显示的时候开启语音监听,页面被切到后台的时候关闭语音监听。
document.addEventListener("visibilitychange", () => {
if (isBrowserTabActive()) { // 自定义页面可见性判断
recognition.start();
} else {
recognition.stop();
}
});
实时更新字幕
recognition.onresult = (event) => {
const results = event.results;
let fullText = "";
for (let i = event.resultIndex; i < results.length; i++) {
fullText += results[i][0].transcript;
}
if (location.hostname === "live.bilibili.com") {
if (!subtitle) {
subtitle = new Subtitle();
}
subtitle.updateSubtitle(fullText);
}
};
将获取到的语音文本片段进行拼接,然后调用 subtitle 实例的 updateSubtitle 更新实时字幕文本。
插件使用
局限性
API限制
由于语音识别API限制,暂时只能在edge浏览器使用,chrome 中使用的话需要🪜
识别准确性
因为用的是浏览器内置的API,免费的API终究不会那么完美,一些同音字或专有名称可能会识别不准确。
杂音干扰
因为是基于外部声源进行识别,所以需要将视频声音外放到浏览器可以识别的音量,而且外部环境杂音过大时,会影响识别结果。
插件源码
插件源码也已经上传到gitee,有兴趣的也可以到这里看看:https://gitee.com/zheng_yongtao/chrome-plug-in/tree/master/bi...
- 🌟觉得有帮助的可以点个star\~
- 🖊有什么问题或错误可以指出,欢迎pr\~
- 📬有什么想要实现的功能或想法可以联系我\~
插件安装
本插件是基于之前开发的一个插件进行迭代开发新增的功能,有兴趣的可以看看这篇文章:《因为懒得点鼠标,我给B站做了个语音助手》
源码下载
直接下载一份源码到本地。
插件引入
打开edge扩展管理页面:<edge://extensions/>
选择 bilibiliVoiceAssistant 这个目录:
再打开B站刷新页面,就可以看到插件图标了,将插件图标选择固定显示
记得打开语音助手开关
然后你就有了一个b站语音助手了\~
最后选择一个B站直播打开,将音量调整到适度大小,然后你就可以看到实时字幕了
公众号
关注公众号『 前端也能这么有趣 』,获取更多有趣内容。
发送 加群 还可以加入群聊,一起来学习(摸鱼)吧~
说在后面
🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。