@tiktool/live 2.6.6 โ†’ 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ <div align="center">
2
+
1
3
  # @tiktool/live
2
4
 
3
5
  ### Connect to any TikTok LIVE stream in 4 lines of code.
@@ -9,9 +11,9 @@
9
11
 
10
12
  Real-time chat, gifts, viewers, battles, follows & 18+ event types from any TikTok livestream.
11
13
 
12
- **NEW:** ๐ŸŽค [Real-Time Live Captions](#-real-time-live-captions) โ€” AI-powered speech-to-text transcription & translation with speaker diarization and sub-second latency.
14
+ [Quick Start](#-quick-start) ยท [Events](#-events) ยท [API](#-api-reference) ยท [Rate Limits](#-rate-limits) ยท [Get API Key](https://tik.tools)
13
15
 
14
- [Quick Start](#-quick-start) ยท [Events](#-events) ยท [Live Captions](#-real-time-live-captions) ยท [API](#-api-reference) ยท [Rate Limits](#-rate-limits) ยท [Get API Key](https://tik.tools)
16
+ </div>
15
17
 
16
18
  ---
17
19
 
@@ -41,87 +43,12 @@ await live.connect();
41
43
 
42
44
  ---
43
45
 
44
- ## ๐Ÿš€ Try It Now โ€” 60-Second Live Demo
45
-
46
- Copy-paste this into a file and run it. Connects to a live TikTok stream, prints every event for 60 seconds, then exits. Works on the free Sandbox tier.
47
-
48
- **Save as `demo.mjs` and run with `node demo.mjs`:**
49
-
50
- ```javascript
51
- // demo.mjs โ€” TikTok LIVE in 60 seconds
52
- // npm install @tiktool/live
53
- import { TikTokLive } from '@tiktool/live';
54
-
55
- const API_KEY = 'YOUR_API_KEY'; // Get free key โ†’ https://tik.tools
56
- const LIVE_USERNAME = 'tv_asahi_news'; // Any live TikTok username
57
-
58
- const live = new TikTokLive({ uniqueId: LIVE_USERNAME, apiKey: API_KEY });
59
- let events = 0;
60
-
61
- live.on('chat', e => { events++; console.log(`๐Ÿ’ฌ ${e.user.uniqueId}: ${e.comment}`); });
62
- live.on('gift', e => { events++; console.log(`๐ŸŽ ${e.user.uniqueId} sent ${e.giftName} (${e.diamondCount}๐Ÿ’Ž)`); });
63
- live.on('like', e => { events++; console.log(`โค๏ธ ${e.user.uniqueId} liked ร— ${e.likeCount}`); });
64
- live.on('member', e => { events++; console.log(`๐Ÿ‘‹ ${e.user.uniqueId} joined`); });
65
- live.on('follow', e => { events++; console.log(`โž• ${e.user.uniqueId} followed`); });
66
- live.on('share', e => { events++; console.log(`๐Ÿ”— ${e.user.uniqueId} shared`); });
67
- live.on('roomUserSeq', e => { events++; console.log(`๐Ÿ‘€ Viewers: ${e.viewerCount}`); });
68
- live.on('subscribe', e => { events++; console.log(`โญ ${e.user.uniqueId} subscribed`); });
69
- live.on('battle', e => { events++; console.log(`โš”๏ธ Battle update`); });
70
-
71
- live.on('connected', () => console.log(`\nโœ… Connected to @${LIVE_USERNAME} โ€” listening for 60s...\n`));
72
- live.on('disconnected', () => console.log(`\n๐Ÿ“Š Done! Received ${events} events.\n`));
73
-
74
- await live.connect();
75
- setTimeout(() => { live.disconnect(); }, 60_000);
76
- ```
77
-
78
- <details>
79
- <summary><strong>๐Ÿ”Œ Pure WebSocket version (no SDK, any language)</strong></summary>
80
-
81
- Works with any WebSocket client. No dependencies except `ws` (Node.js) or your language's WebSocket library.
82
-
83
- ```javascript
84
- // ws-demo.mjs โ€” Pure WebSocket, zero SDK
85
- // npm install ws
86
- import WebSocket from 'ws';
87
-
88
- const API_KEY = 'YOUR_API_KEY';
89
- const LIVE_USERNAME = 'tv_asahi_news';
90
-
91
- const ws = new WebSocket(`wss://api.tik.tools?uniqueId=${LIVE_USERNAME}&apiKey=${API_KEY}`);
92
- let events = 0;
93
-
94
- ws.on('open', () => console.log(`\nโœ… Connected to @${LIVE_USERNAME} โ€” listening for 60s...\n`));
95
- ws.on('message', (raw) => {
96
- const msg = JSON.parse(raw);
97
- events++;
98
- const d = msg.data || {};
99
- const user = d.user?.uniqueId || d.uniqueId || '';
100
- switch (msg.event) {
101
- case 'chat': console.log(`๐Ÿ’ฌ ${user}: ${d.comment}`); break;
102
- case 'gift': console.log(`๐ŸŽ ${user} sent ${d.giftName} (${d.diamondCount}๐Ÿ’Ž)`); break;
103
- case 'like': console.log(`โค๏ธ ${user} liked ร— ${d.likeCount}`); break;
104
- case 'member': console.log(`๐Ÿ‘‹ ${user} joined`); break;
105
- case 'roomUserSeq': console.log(`๐Ÿ‘€ Viewers: ${d.viewerCount}`); break;
106
- case 'roomInfo': console.log(`๐Ÿ“ก Room: ${msg.roomId}`); break;
107
- default: console.log(`๐Ÿ“ฆ ${msg.event}`); break;
108
- }
109
- });
110
- ws.on('close', () => console.log(`\n๐Ÿ“Š Done! Received ${events} events.\n`));
111
-
112
- setTimeout(() => ws.close(), 60_000);
113
- ```
114
-
115
- </details>
116
-
117
- ---
118
-
119
46
  ## How It Works
120
47
 
121
48
  ```
122
49
  Your App tik.tools TikTok
123
50
  +-----------+ +--------------+ +--------------+
124
- | -+-- sign_url --> Signs URL | | |
51
+ | -+-- sign_url --> Signs URL | | |
125
52
  | Your <-+-- X-Bogus --| with params | | TikTok |
126
53
  | Code | | | | WebSocket |
127
54
  | -+------------ Connect directly ---------->| Server |
@@ -131,7 +58,7 @@ setTimeout(() => ws.close(), 60_000);
131
58
  with our server YOUR IP
132
59
  ```
133
60
 
134
- - Your app connects directly to TikTok โ€” from your IP or through a proxy
61
+ - Your app connects directly to TikTok from your IP address
135
62
  - The sign server only generates cryptographic signatures (requires API key)
136
63
  - TikTok never sees the sign server
137
64
  - Built-in protobuf parser, no external dependencies
@@ -187,110 +114,6 @@ live.on('event', (event) => {
187
114
 
188
115
  ---
189
116
 
190
- ## ๐ŸŽค Real-Time Live Captions
191
-
192
- AI-powered speech-to-text transcription and translation for TikTok LIVE streams. Features include:
193
-
194
- - **Auto-detect language** โ€” Automatically identifies the spoken language
195
- - **Speaker diarization** โ€” Identifies individual speakers in multi-person streams
196
- - **Real-time translation** โ€” Translate to any supported language with sub-second latency
197
- - **Partial + final results** โ€” Get streaming partial transcripts and confirmed final text
198
- - **Credit-based billing** โ€” 1 credit = 1 minute of transcription/translation
199
-
200
- ### Quick Start
201
-
202
- ```typescript
203
- import { TikTokCaptions } from '@tiktool/live';
204
-
205
- const captions = new TikTokCaptions({
206
- uniqueId: 'streamer_name',
207
- apiKey: 'YOUR_API_KEY',
208
- translate: 'en',
209
- diarization: true,
210
- });
211
-
212
- captions.on('caption', (event) => {
213
- const prefix = event.speaker ? `[${event.speaker}] ` : '';
214
- console.log(`${prefix}${event.text}${event.isFinal ? ' โœ“' : '...'}`);
215
- });
216
-
217
- captions.on('translation', (event) => {
218
- console.log(` โ†’ ${event.text}`);
219
- });
220
-
221
- captions.on('credits', (event) => {
222
- console.log(`${event.remaining}/${event.total} min remaining`);
223
- });
224
-
225
- captions.on('credits_low', (event) => {
226
- console.warn(`Low credits! ${event.remaining} min left`);
227
- });
228
-
229
- await captions.start();
230
- ```
231
-
232
- ### `new TikTokCaptions(options)`
233
-
234
- | Option | Type | Default | Description |
235
- |--------|------|---------|-------------|
236
- | `uniqueId` | `string` | โ€” | TikTok username (without @) |
237
- | `apiKey` | `string` | โ€” | **Required.** API key from [tik.tools](https://tik.tools) |
238
- | `language` | `string` | `''` | Source language hint (empty = auto-detect) |
239
- | `translate` | `string` | `''` | Target translation language (e.g. `'en'`, `'es'`, `'fr'`) |
240
- | `diarization` | `boolean` | `true` | Enable speaker identification |
241
- | `maxDurationMinutes` | `number` | `60` | Auto-disconnect after N minutes (max: 300) |
242
- | `autoReconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
243
- | `maxReconnectAttempts` | `number` | `5` | Max reconnect attempts |
244
- | `debug` | `boolean` | `false` | Debug logging |
245
-
246
- ### Caption Events
247
-
248
- | Event | Callback | Description |
249
- |-------|----------|-------------|
250
- | `caption` | `(data: CaptionData) => void` | Real-time transcription (partial + final) |
251
- | `translation` | `(data: TranslationData) => void` | Translated text |
252
- | `status` | `(data: CaptionStatus) => void` | Session status changes |
253
- | `credits` | `(data: CaptionCredits) => void` | Credit balance updates |
254
- | `credits_low` | `(data) => void` | Low credit warning (โ‰ค20%) |
255
- | `connected` | `() => void` | WebSocket connected |
256
- | `disconnected` | `(code, reason) => void` | Disconnected |
257
- | `error` | `(data: CaptionError) => void` | Error |
258
-
259
- ### Methods
260
-
261
- | Method | Returns | Description |
262
- |--------|---------|-------------|
263
- | `start()` | `Promise<void>` | Connect and start transcription |
264
- | `stop()` | `void` | Stop and disconnect |
265
- | `setLanguage(lang)` | `void` | Switch translation language on-the-fly |
266
- | `getCredits()` | `void` | Request credit balance update |
267
- | `connected` | `boolean` | Connection status |
268
- | `language` | `string` | Current target language |
269
-
270
- ### Raw WebSocket
271
-
272
- You can also connect directly via WebSocket without the SDK:
273
-
274
- ```
275
- wss://api.tik.tools/captions?uniqueId=USERNAME&apiKey=YOUR_KEY&translate=en&diarization=true&max_duration_minutes=120
276
- ```
277
-
278
- ### Caption Credits
279
-
280
- Caption credits are **pay-as-you-go add-ons** โ€” no credits are included in the base subscription. Requires Basic tier or higher.
281
-
282
- | Package | Credits | Price | Per Credit |
283
- |---------|---------|-------|------------|
284
- | **Starter** | 1,000 min | $10 | $0.010/min |
285
- | **Creator** | 5,000 min | $35 | $0.007/min |
286
- | **Agency** | 20,000 min | $100 | $0.005/min |
287
-
288
- > **1 credit = 1 minute** of audio transcribed/translated into one language. If translating to 2 languages simultaneously, it burns 2 credits per minute.
289
-
290
- Try the live demo at [tik.tools/captions](https://tik.tools/captions) โ€” see real-time transcription and translation on actual TikTok LIVE streams.
291
-
292
- ---
293
-
294
117
  ## API Reference
295
118
 
296
119
  ### `new TikTokLive(options)`
@@ -300,15 +123,10 @@ Try the live demo at [tik.tools/captions](https://tik.tools/captions) โ€” see re
300
123
  | `uniqueId` | `string` | โ€” | TikTok username (without @) |
301
124
  | `apiKey` | `string` | โ€” | **Required.** API key from [tik.tools](https://tik.tools) |
302
125
  | `signServerUrl` | `string` | `https://api.tik.tools` | Sign server URL |
303
- | `agent` | `http.Agent` | โ€” | HTTP agent for proxying connections |
304
126
  | `autoReconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
305
127
  | `maxReconnectAttempts` | `number` | `5` | Max reconnect attempts |
306
128
  | `heartbeatInterval` | `number` | `10000` | Heartbeat interval (ms) |
307
129
  | `debug` | `boolean` | `false` | Debug logging |
308
- | `sessionId` | `string` | โ€” | TikTok `sessionid` cookie for authenticated features (ranklist, chat) |
309
- | `ttTargetIdc` | `string` | โ€” | TikTok target IDC region (e.g. `useast5`). Required with `sessionId` |
310
- | `roomId` | `string` | โ€” | Pre-known room ID โ€” skips HTML page scrape |
311
- | `ttwid` | `string` | โ€” | Pre-fetched `ttwid` cookie. With `roomId`, skips all HTTP requests |
312
130
 
313
131
  ### Methods
314
132
 
@@ -316,12 +134,9 @@ Try the live demo at [tik.tools/captions](https://tik.tools/captions) โ€” see re
316
134
  |--------|---------|-------------|
317
135
  | `connect()` | `Promise<void>` | Connect to livestream |
318
136
  | `disconnect()` | `void` | Disconnect |
319
- | `setSession(sessionId, ttTargetIdc?)` | `void` | Update session at runtime |
320
- | `buildSessionCookieHeader()` | `string \| undefined` | Build cookie header for auth API requests |
321
137
  | `connected` | `boolean` | Connection status |
322
138
  | `eventCount` | `number` | Total events received |
323
139
  | `roomId` | `string` | Current room ID |
324
- | `sessionId` | `string \| undefined` | Current session ID |
325
140
 
326
141
  ---
327
142
 
@@ -329,117 +144,13 @@ Try the live demo at [tik.tools/captions](https://tik.tools/captions) โ€” see re
329
144
 
330
145
  All API requests require an API key. Get yours at [tik.tools](https://tik.tools).
331
146
 
332
- | Tier | Requests/Day | Rate Limit | WS Connections | WS Duration | WS Connects | Bulk Check | CAPTCHA | Feed Discovery | Price |
333
- |------|-------------|-----------|----------------|-------------|-------------|------------|---------|----------------|-------|
334
- | **Sandbox** | 50 | 5/min | 1 | 60 sec | 10/hr ยท 30/day | 1 | โœ• | โœ• | Free |
335
- | **Basic** | 10,000 | 60/min | 3 | 8 hours | 60/hr ยท 200/day | 10 | โœ• | โœ• | From $7/wk |
336
- | **Pro** | 75,000 | Unlimited | 50 | 8 hours | Unlimited | 50 | 50/day | 100/day | From $15/wk |
337
- | **Ultra** | 300,000 | Unlimited | 500 | 8 hours | Unlimited | 500 | 500/day | 2,000/day | From $45/wk |
338
-
339
- **Caption Credits** are available as pay-as-you-go add-ons (1 credit = 1 min of audio in 1 language):
340
- - **Starter**: 1,000 credits โ€” $10
341
- - **Creator**: 5,000 credits โ€” $35
342
- - **Agency**: 20,000 credits โ€” $100
343
-
344
- The SDK calls the sign server **once per connection**, then stays connected via WebSocket. Sandbox is for API verification only โ€” use Basic or higher for production.
345
-
346
- ---
347
-
348
- ## ๐Ÿ” Feed Discovery
349
-
350
- Discover recommended TikTok LIVE streams. **Requires Pro or Ultra tier.**
351
-
352
- ```typescript
353
- import { getLiveFeed, fetchFeed } from '@tiktool/live';
354
-
355
- // Option 1: Two-step (sign-and-return)
356
- const signed = await getLiveFeed({
357
- apiKey: 'YOUR_PRO_KEY',
358
- sessionId: 'YOUR_TIKTOK_SESSIONID',
359
- region: 'US',
360
- count: 10,
361
- });
362
-
363
- const resp = await fetch(signed.signed_url, {
364
- headers: { ...signed.headers, Cookie: signed.cookies || '' },
365
- });
366
- const data = await resp.json();
367
-
368
- // Option 2: One-step convenience
369
- const feed = await fetchFeed({
370
- apiKey: 'YOUR_PRO_KEY',
371
- sessionId: 'YOUR_TIKTOK_SESSIONID',
372
- count: 10,
373
- });
374
-
375
- for (const entry of feed.data || []) {
376
- const room = entry.data;
377
- console.log(`๐Ÿ”ด @${room.owner.display_id}: "${room.title}" โ€” ${room.user_count} viewers`);
378
- }
379
- ```
380
-
381
- ### Channel Types
147
+ | Tier | Rate Limit | Endpoints | Price |
148
+ |------|-----------|-----------|-------|
149
+ | **Free** | 5/min | `sign_url`, `check_alive` | Free |
150
+ | **Basic** | 30/min | + `fetch`, `room_info`, `bulk_live_check`, WS relay | Free (with key) |
151
+ | **Pro** | 120/min | + `room_video`, all endpoints | Coming soon |
382
152
 
383
- | Value | Channel |
384
- |-------|--------|
385
- | `"87"` | Recommended (default) |
386
- | `"86"` | Suggested |
387
- | `"42"` | Following |
388
- | `"1111006"` | Gaming |
389
-
390
- ### Pagination
391
-
392
- Use `maxTime` from the previous response to load more:
393
-
394
- ```typescript
395
- const page2 = await getLiveFeed({
396
- apiKey: 'YOUR_PRO_KEY',
397
- sessionId: 'YOUR_TIKTOK_SESSIONID',
398
- maxTime: data.extra?.max_time, // cursor from previous response
399
- });
400
- ```
401
-
402
- ---
403
-
404
- ## ๐Ÿ† Regional Leaderboard
405
-
406
- Get daily, hourly, popular, or league LIVE rankings for any streamer. **Requires Pro or Ultra tier.**
407
-
408
- This endpoint uses a **two-step sign-and-return pattern** because TikTok sessions are IP-bound:
409
-
410
- 1. Call `getRegionalRanklist()` to get a signed URL from the server
411
- 2. POST the signed URL from **your own IP** with your TikTok session cookie
412
-
413
- ```typescript
414
- import { getRegionalRanklist } from '@tiktool/live';
415
-
416
- const signed = await getRegionalRanklist({
417
- apiKey: 'YOUR_PRO_KEY',
418
- roomId: '7607695933891218198',
419
- anchorId: '7444599004337652758',
420
- rankType: '8',
421
- });
422
-
423
- const resp = await fetch(signed.signed_url, {
424
- method: signed.method,
425
- headers: { ...signed.headers, Cookie: `sessionid=YOUR_SID; ${signed.cookies}` },
426
- body: signed.body,
427
- });
428
-
429
- const { data } = await resp.json();
430
- data.rank_view.ranks.forEach((r: any, i: number) =>
431
- console.log(`${i+1}. ${r.user.nickname} โ€” ${r.score} pts`)
432
- );
433
- ```
434
-
435
- ### Rank Types
436
-
437
- | Value | Period |
438
- |-------|--------|
439
- | `"1"` | Hourly |
440
- | `"8"` | Daily (default) |
441
- | `"15"` | Popular LIVE |
442
- | `"16"` | League |
153
+ The SDK calls the sign server **once per connection**, then stays connected via WebSocket. A free key is sufficient for most use cases.
443
154
 
444
155
  ---
445
156
 
@@ -494,32 +205,6 @@ console.log('Forwarding events to ws://localhost:8080');
494
205
 
495
206
  ---
496
207
 
497
- ## ๐ŸŒ Proxy Support
498
-
499
- Route all connections through an HTTP proxy. Works with any HTTPS proxy provider (residential, datacenter, etc.).
500
-
501
- ```typescript
502
- import { TikTokLive } from '@tiktool/live';
503
- import { HttpsProxyAgent } from 'https-proxy-agent';
504
-
505
- const agent = new HttpsProxyAgent('http://user:pass@proxy.example.com:1234');
506
-
507
- const live = new TikTokLive({
508
- uniqueId: 'streamer_name',
509
- apiKey: 'YOUR_API_KEY',
510
- agent,
511
- });
512
-
513
- await live.connect();
514
- ```
515
-
516
- Both the initial page request and the WebSocket connection are routed through the proxy. This is useful for:
517
- - Running multiple concurrent connections from different IPs
518
- - Avoiding rate limits
519
- - Geo-targeting specific regions
520
-
521
- ---
522
-
523
208
  ## TypeScript
524
209
 
525
210
  Full TypeScript support with type inference: