使用 Node.js 为 OBS 构建 TikTok 直播叠加层

发布: (2026年3月16日 GMT+8 08:03)
4 分钟阅读
原文: Dev.to

Source: Dev.to

(请提供需要翻译的正文内容,我将为您翻译成简体中文并保持原有的格式、Markdown 语法以及代码块不变。)

概述

创建一个自定义的 OBS 覆盖层,实时响应 TikTok LIVE 事件,如聊天消息、礼物、关注和观众人数。架构如下:

TikTok LIVE → tiktok-live-api (WebSocket) → Node.js server → Local WebSocket → OBS Browser Source

设置

mkdir tiktok-overlay && cd tiktok-overlay
npm init -y
npm install tiktok-live-api ws express
mkdir public

服务器 (server.mjs)

// server.mjs
import { TikTokLive } from 'tiktok-live-api';
import { WebSocketServer } from 'ws';
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';

const __dirname = dirname(fileURLToPath(import.meta.url));
const app = express();
app.use(express.static(join(__dirname, 'public')));
app.listen(3000, () => console.log('Overlay at http://localhost:3000'));

const wss = new WebSocketServer({ port: 8080 });
const client = new TikTokLive('USERNAME_HERE', {
  apiKey: 'YOUR_API_KEY'
});

// Forward all TikTok events to the overlay via the local WebSocket
client.on('event', (event) => {
  const data = JSON.stringify(event);
  for (const ws of wss.clients) {
    ws.send(data);
  }
});

client.on('connected', () => console.log('✅ Connected to TikTok'));

client.on('chat', (e) => {
  console.log(`💬 ${e.user.uniqueId}: ${e.comment}`);
});

client.on('gift', (e) => {
  console.log(`🎁 ${e.user.uniqueId} sent ${e.giftName} (${e.diamondCount} 💎)`);
});

client.connect();

运行服务器:

node server.mjs

前端覆盖层 (public/index.html)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>TikTok Live Overlay</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      background: transparent;
      font-family: 'Segoe UI', sans-serif;
      color: white;
      overflow: hidden;
    }
    #alerts {
      position: fixed;
      top: 20px;
      right: 20px;
      width: 350px;
    }
    .alert {
      background: rgba(0,0,0,0.8);
      border-left: 4px solid #ff0050;
      padding: 12px 16px;
      margin-bottom: 8px;
      border-radius: 8px;
      animation: slideIn 0.3s ease-out, fadeOut 0.5s ease-in 4.5s;
      animation-fill-mode: forwards;
    }
    .alert.gift { border-color: #ffd700; }
    .alert .user { color: #ff0050; font-weight: bold; }
    .alert .diamonds { color: #ffd700; }
    #viewers {
      position: fixed;
      bottom: 20px;
      right: 20px;
      background: rgba(0,0,0,0.8);
      padding: 8px 16px;
      border-radius: 20px;
      font-size: 18px;
    }
    @keyframes slideIn {
      from { transform: translateX(100%); opacity: 0; }
      to { transform: translateX(0); opacity: 1; }
    }
    @keyframes fadeOut {
      to { opacity: 0; transform: translateY(-20px); }
    }
  </style>
</head>
<body>
  <div id="alerts"></div>
  <div id="viewers">👀 0</div>

  <script>
    const ws = new WebSocket('ws://localhost:8080');
    const alerts = document.getElementById('alerts');

    ws.onmessage = (e) => {
      const msg = JSON.parse(e.data);
      const d = msg.data || {};
      const user = d.user?.uniqueId || '';

      switch (msg.event) {
        case 'chat':
          addAlert(`@${user}: ${d.comment}`);
          break;
        case 'gift':
          addAlert(`@${user} sent ${d.giftName} (${d.diamondCount} 💎)`, 'gift');
          break;
        case 'follow':
          addAlert(`@${user} followed! ➕`);
          break;
        case 'roomUserSeq':
          document.getElementById('viewers').textContent = `👀 ${d.viewerCount}`;
          break;
      }
    };

    function addAlert(html, type = '') {
      const div = document.createElement('div');
      div.className = `alert ${type}`;
      div.innerHTML = html;
      alerts.prepend(div);
      setTimeout(() => div.remove(), 5000);
      while (alerts.children.length > 5) alerts.lastChild.remove();
    }
  </script>
</body>
</html>

在浏览器中打开 http://localhost:3000,以验证警报是否出现以及观众计数是否更新。

添加覆盖层到 OBS

  1. 添加浏览器源

    • URL: http://localhost:3000
    • Size: 1920×1080 (或匹配你的画布)
    • 勾选 在不可见时关闭源
  2. 背景是透明的,因此提醒会直接叠加在你的流上。

    • 聊天消息显示为红色边框的提醒。
    • 礼物显示为金色边框的提醒,并带有钻石价值。
    • 观众计数保持在右下角。

工作原理

  • tiktok-live-api 维持与 TikTok 的 WebSocket 连接并发出已定义类型的 JSON 事件。
  • Node.js 服务器将每个事件转发给所有已连接的本地 WebSocket 客户端(覆盖层页面)。
  • 浏览器源接收这些事件,更新 DOM,并使用 CSS 动画提供平滑的视觉反馈。

资源

免费层:50 次请求/天,1 个 WebSocket 连接 — 足以用于开发和测试。

0 浏览
Back to Blog

相关文章

阅读更多 »

关于 JavaScript 的简介

介绍 在今天的课堂上,我学习了 JavaScript 的简短介绍,所以我将在这篇博客中分享一些关于 JavaScript 的事实。什么是 JavaScript?JavaScr...

现代 JavaScript:理解 ES6 类

封面图片:Modern JavaScript:Understanding ES6 Classes https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%...

你的设计系统存在耦合问题

介绍 我直截了当地写作,我珍惜你的时间——少废话,多价值。挑选一个流行的组件库,找到 Button 组件。你会看到:结构……