Tutoriel

Crée un overlay de stream TikTok LIVE

Crée un overlay en source navigateur, compatible OBS, qui affiche en temps réel le chat, les alertes de cadeaux et le nombre de spectateurs de n'importe quel stream TikTok LIVE.

Ce que tu vas créer

Un overlay de stream dans le navigateur qui fonctionne avec OBS, Streamlabs ou tout logiciel qui gère les sources navigateur. Il affiche :

  • Les messages du chat en temps réel
  • Des alertes de cadeaux animées avec leur valeur en diamants
  • Le nombre de spectateurs actuel
  • Un flux de chat défilant avec les avatars des utilisateurs

Prérequis

  • Node.js 18+ installé
  • Une clé API TikTools gratuite - obtiens-la ici
  • OBS Studio (ou tout logiciel de streaming avec Source navigateur)

Étape 1 : configurer le projet

mkdir tiktok-overlay && cd tiktok-overlay
npm init -y
npm install @tiktool/live express

Étape 2 : créer le serveur

Crée server.mjs - il se connecte à TikTok et diffuse les événements vers l'overlay du navigateur via Server-Sent Events (SSE) :

import express from 'express'
import { TikTokLive } from '@tiktool/live'

const app = express()
const clients = new Set()

// Serve the overlay HTML
app.get('/', (req, res) => {
  res.sendFile('overlay.html', { root: '.' })
})

// SSE endpoint for real-time events
app.get('/events', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    Connection: 'keep-alive',
  })
  clients.add(res)
  req.on('close', () => clients.delete(res))
})

function broadcast(event, data) {
  for (const client of clients) {
    client.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`)
  }
}

// Connect to TikTok LIVE
const tiktok = new TikTokLive({
  uniqueId: process.env.STREAMER || 'tv_asahi_news',
  apiKey: process.env.TIKTOOL_API_KEY
})

tiktok.on('chat', (e) => broadcast('chat', {
  user: e.nickname, comment: e.comment, avatar: e.profilePictureUrl
}))

tiktok.on('gift', (e) => broadcast('gift', {
  user: e.nickname, gift: e.giftName, diamonds: e.diamondCount
}))

tiktok.on('viewer_count', (e) => broadcast('viewers', {
  count: e.viewerCount
}))

await tiktok.connect()
app.listen(3333, () => console.log('Overlay: http://localhost:3333'))

Étape 3 : créer le HTML de l'overlay

Crée overlay.html - c'est ce qu'OBS affichera comme source navigateur :

<!DOCTYPE html>
<html>
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: 'Inter', sans-serif;
      background: transparent;
      overflow: hidden;
    }

    .chat-feed {
      position: fixed; bottom: 20px; left: 20px;
      width: 360px; max-height: 400px;
      display: flex; flex-direction: column-reverse;
      gap: 6px; overflow: hidden;
    }

    .chat-msg {
      background: rgba(0, 0, 0, 0.6);
      border-radius: 8px; padding: 8px 12px;
      color: #fff; font-size: 14px;
      animation: slideIn 0.3s ease;
    }

    .chat-msg .user { color: #fff; font-weight: 600; }

    .gift-alert {
      position: fixed; top: 50%; left: 50%;
      transform: translate(-50%, -50%);
      background: rgba(0, 0, 0, 0.8);
      border: 2px solid var(--border-primary);
      border-radius: 16px; padding: 24px 40px;
      text-align: center; color: #fff;
      animation: popIn 0.5s ease;
      display: none;
    }

    .gift-alert.show { display: block; }
    .gift-alert .gift-name { font-size: 28px; font-weight: 800; }
    .gift-alert .gift-user { font-size: 16px; color: #94a3b8; }
    .gift-alert .gift-diamonds { font-size: 18px; color: #fff; }

    .viewer-count {
      position: fixed; top: 20px; right: 20px;
      background: rgba(0, 0, 0, 0.6);
      border-radius: 8px; padding: 8px 16px;
      color: #fff; font-size: 14px; font-weight: 600;
    }

    @keyframes slideIn {
      from { opacity: 0; transform: translateY(10px); }
      to { opacity: 1; transform: translateY(0); }
    }

    @keyframes popIn {
      0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
      100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    }
  </style>
</head>
<body>
  <div class="chat-feed" id="chat"></div>
  <div class="gift-alert" id="gift">
    <div class="gift-name" id="gift-name"></div>
    <div class="gift-user" id="gift-user"></div>
    <div class="gift-diamonds" id="gift-diamonds"></div>
  </div>
  <div class="viewer-count" id="viewers">👁 0</div>

  <script>
    const chat = document.getElementById('chat')
    const gift = document.getElementById('gift')
    const src = new EventSource('/events')

    src.addEventListener('chat', (e) => {
      const d = JSON.parse(e.data)
      const el = document.createElement('div')
      el.className = 'chat-msg'
      el.innerHTML = `<span class="user">${d.user}</span> ${d.comment}`
      chat.prepend(el)
      if (chat.children.length > 50) chat.lastChild.remove()
    })

    src.addEventListener('gift', (e) => {
      const d = JSON.parse(e.data)
      document.getElementById('gift-name').textContent = `🎁 ${d.gift}`
      document.getElementById('gift-user').textContent = `from ${d.user}`
      document.getElementById('gift-diamonds').textContent = `${d.diamonds} 💎`
      gift.classList.add('show')
      setTimeout(() => gift.classList.remove('show'), 4000)
    })

    src.addEventListener('viewers', (e) => {
      const d = JSON.parse(e.data)
      document.getElementById('viewers').textContent = `👁 ${d.count.toLocaleString()}`
    })
  </script>
</body>
</html>

Étape 4 : lancer et ajouter à OBS

TIKTOOL_API_KEY=your_key STREAMER=target_username node server.mjs

Puis dans OBS :

  • Ajoute une nouvelle Source navigateur
  • Définis l'URL sur http://localhost:3333
  • Définis la largeur sur 1920 et la hauteur sur 1080
  • Coche "Désactiver la source lorsqu'elle n'est pas visible"

Idées de personnalisation

  • Thèmes personnalisés - change les couleurs, les polices et la mise en page pour coller à l'identité de ton stream
  • Effets sonores - joue des sons à l'arrivée des cadeaux avec la Web Audio API
  • Animations GIF - affiche des GIF animés pour certains cadeaux
  • Barres d'objectif - ajoute des barres de progression d'objectif de dons/cadeaux
  • Podium des top donateurs - affiche les 3 meilleurs donateurs en temps réel