写点什么

写了一个 B 站直播实时字幕插件

作者:JYeontu
  • 2025-04-21
    广东
  • 本文字数:2865 字

    阅读完需:约 9 分钟

写了一个B站直播实时字幕插件

说在前面

之前看剧习惯了看字幕,最近在 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";       // 中文普通话识别
复制代码


页面状态判断

只在页面显示的时候开启语音监听,页面被切到后台的时候关闭语音监听。


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/bilibiliVoiceAssistant





  • 🌟觉得有帮助的可以点个 star~

  • 🖊有什么问题或错误可以指出,欢迎 pr~

  • 📬有什么想要实现的功能或想法可以联系我~



插件安装

本插件是基于之前开发的一个插件进行迭代开发新增的功能,有兴趣的可以看看这篇文章:《因为懒得点鼠标,我给B站做了个语音助手

源码下载

直接下载一份源码到本地。


插件引入

打开 edge 扩展管理页面:edge://extensions/



选择 bilibiliVoiceAssistant 这个目录:




再打开 B 站刷新页面,就可以看到插件图标了,将插件图标选择固定显示



记得打开语音助手开关



然后你就有了一个 b 站语音助手了~



最后选择一个 B 站直播打开,将音量调整到适度大小,然后你就可以看到实时字幕了

公众号

关注公众号『 前端也能这么有趣 』,获取更多有趣内容。


发送 加群 还可以加入群聊,一起来学习(摸鱼)吧~

说在后面

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

发布于: 刚刚阅读数: 2
用户头像

JYeontu

关注

技术~运动~分享 公众号:前端也能这么有趣 2023-02-07 加入

喜欢算法,GDCPC打过卡;热爱羽毛球,大运会打过酱油。毕业两年,三年前端开发经验,做过unity游戏开发,目前担任H5前端开发,算法业余爱好者。公众号:『前端也能这么有趣』

评论

发布
暂无评论
写了一个B站直播实时字幕插件_前端_JYeontu_InfoQ写作社区