头图

说在前面

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

JYeontu
15 声望0 粉丝