@tiktool/live 2.7.1 → 2.8.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 +426 -235
- package/dist/index.d.mts +75 -4
- package/dist/index.d.ts +75 -4
- package/dist/index.js +272 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +272 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -3
package/dist/index.mjs
CHANGED
|
@@ -396,27 +396,41 @@ function parseWebcastMessage(method, payload) {
|
|
|
396
396
|
// Proto: WebcastLinkMicBattle { repeated WebcastLinkMicBattleItems battleUsers=10 }
|
|
397
397
|
// battleUsers → { battleGroup=2 → { LinkUser user=1 } }
|
|
398
398
|
case "WebcastLinkMicBattle": {
|
|
399
|
-
const battleId = String(getInt(f, 1) || "");
|
|
400
|
-
|
|
399
|
+
const battleId = String(getInt(f, 4) || getInt(f, 1) || "");
|
|
400
|
+
let status = getInt(f, 7);
|
|
401
|
+
if (!status) {
|
|
402
|
+
const fallback = getInt(f, 2);
|
|
403
|
+
status = fallback > 0 && fallback < 100 ? fallback : 1;
|
|
404
|
+
}
|
|
401
405
|
const battleDuration = getInt(f, 3);
|
|
402
406
|
const teams = [];
|
|
403
|
-
const
|
|
404
|
-
for (const
|
|
407
|
+
const hostBufs = getAllBytes(f, 14);
|
|
408
|
+
for (const hb of hostBufs) {
|
|
405
409
|
try {
|
|
406
|
-
const
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
410
|
+
const hf = decodeProto(hb);
|
|
411
|
+
const hostUserId = String(getInt(hf, 1) || "");
|
|
412
|
+
const teamTotalScore = getInt(hf, 3);
|
|
413
|
+
const users = [];
|
|
414
|
+
const containerBuf = getBytes(hf, 4);
|
|
415
|
+
if (containerBuf) {
|
|
416
|
+
const cf = decodeProto(containerBuf);
|
|
417
|
+
const userBufs = getAllBytes(cf, 1);
|
|
418
|
+
for (const ub of userBufs) {
|
|
419
|
+
try {
|
|
420
|
+
const uf = decodeProto(ub);
|
|
421
|
+
users.push({
|
|
422
|
+
user: {
|
|
423
|
+
id: String(getInt(uf, 1) || ""),
|
|
424
|
+
nickname: getStr(uf, 3) || "",
|
|
425
|
+
uniqueId: getStr(uf, 3) || ""
|
|
426
|
+
},
|
|
427
|
+
score: getInt(uf, 2)
|
|
428
|
+
});
|
|
429
|
+
} catch {
|
|
430
|
+
}
|
|
418
431
|
}
|
|
419
432
|
}
|
|
433
|
+
teams.push({ hostUserId, score: teamTotalScore, users });
|
|
420
434
|
} catch {
|
|
421
435
|
}
|
|
422
436
|
}
|
|
@@ -429,15 +443,42 @@ function parseWebcastMessage(method, payload) {
|
|
|
429
443
|
}
|
|
430
444
|
}
|
|
431
445
|
}
|
|
446
|
+
if (teams.length === 0) {
|
|
447
|
+
const battleUserBufs = getAllBytes(f, 10);
|
|
448
|
+
for (const bub of battleUserBufs) {
|
|
449
|
+
try {
|
|
450
|
+
const bf = decodeProto(bub);
|
|
451
|
+
const groupBuf = getBytes(bf, 2);
|
|
452
|
+
if (groupBuf) {
|
|
453
|
+
const gf = decodeProto(groupBuf);
|
|
454
|
+
const linkUserBuf = getBytes(gf, 1);
|
|
455
|
+
if (linkUserBuf) {
|
|
456
|
+
const user = parseUser(linkUserBuf);
|
|
457
|
+
teams.push({
|
|
458
|
+
hostUserId: user.id,
|
|
459
|
+
score: 0,
|
|
460
|
+
users: [{ user, score: 0 }]
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
} catch {
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
432
468
|
return { ...base, type: "battle", battleId, status, battleDuration, teams };
|
|
433
469
|
}
|
|
434
|
-
// Proto: WebcastLinkMicArmies { msg_header=1,
|
|
435
|
-
//
|
|
436
|
-
//
|
|
437
|
-
//
|
|
470
|
+
// Proto: WebcastLinkMicArmies { msg_header=1, matchId=2, session_id=4, startedAtMs=5,
|
|
471
|
+
// serverTsMs=6, repeated battleItems=3, status=7, sessionTag=17,
|
|
472
|
+
// battle_config=18 { session_id=1, start_time_ms=2, duration_s=3 },
|
|
473
|
+
// repeated hosts=14 { hostUserId=1, teamTotalScore=3, teamIdx=5,
|
|
474
|
+
// userContainer=4 { repeated users=1 { userId=1, score=2, nickname=3 } } }
|
|
438
475
|
case "WebcastLinkMicArmies": {
|
|
439
|
-
const
|
|
476
|
+
const sessionTag = getStr(f, 17);
|
|
477
|
+
const matchId = getIntStr(f, 2);
|
|
478
|
+
const sessionId = getIntStr(f, 4);
|
|
479
|
+
const battleId = sessionTag || matchId;
|
|
440
480
|
const battleStatus = getInt(f, 7);
|
|
481
|
+
const serverTsMs = getInt(f, 6);
|
|
441
482
|
const teams = [];
|
|
442
483
|
const itemBufs = getAllBytes(f, 3);
|
|
443
484
|
for (const ib of itemBufs) {
|
|
@@ -457,6 +498,10 @@ function parseWebcastMessage(method, payload) {
|
|
|
457
498
|
} catch {
|
|
458
499
|
}
|
|
459
500
|
}
|
|
501
|
+
let secsRemaining = 0;
|
|
502
|
+
if (battleStartMs > 0 && battleDurationSeconds > 0 && serverTsMs > 0) {
|
|
503
|
+
secsRemaining = Math.max(0, battleDurationSeconds - Math.floor((serverTsMs - battleStartMs) / 1e3));
|
|
504
|
+
}
|
|
460
505
|
let endTimeMs = 0;
|
|
461
506
|
let timeLeftSeconds = 0;
|
|
462
507
|
if (battleStartMs > 0 && battleDurationSeconds > 0) {
|
|
@@ -464,6 +509,36 @@ function parseWebcastMessage(method, payload) {
|
|
|
464
509
|
const elapsedMs = Date.now() - battleStartMs;
|
|
465
510
|
timeLeftSeconds = Math.max(0, battleDurationSeconds - Math.floor(elapsedMs / 1e3));
|
|
466
511
|
}
|
|
512
|
+
const hosts = [];
|
|
513
|
+
const hostBufs = getAllBytes(f, 14);
|
|
514
|
+
for (const hb of hostBufs) {
|
|
515
|
+
try {
|
|
516
|
+
const hf = decodeProto(hb);
|
|
517
|
+
const hostUserId = getIntStr(hf, 1);
|
|
518
|
+
const teamTotalScore = getInt(hf, 3);
|
|
519
|
+
const teamIdx = getInt(hf, 5);
|
|
520
|
+
const contributors = [];
|
|
521
|
+
const containerBuf = getBytes(hf, 4);
|
|
522
|
+
if (containerBuf) {
|
|
523
|
+
const cf = decodeProto(containerBuf);
|
|
524
|
+
const userBufs = getAllBytes(cf, 1);
|
|
525
|
+
for (const ub of userBufs) {
|
|
526
|
+
try {
|
|
527
|
+
const uf = decodeProto(ub);
|
|
528
|
+
contributors.push({
|
|
529
|
+
userId: getIntStr(uf, 1),
|
|
530
|
+
score: getInt(uf, 2),
|
|
531
|
+
nickname: getStr(uf, 3) || ""
|
|
532
|
+
});
|
|
533
|
+
} catch {
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
contributors.sort((a, b) => b.score - a.score);
|
|
537
|
+
}
|
|
538
|
+
hosts.push({ hostUserId, teamTotalScore, teamIdx, contributors });
|
|
539
|
+
} catch {
|
|
540
|
+
}
|
|
541
|
+
}
|
|
467
542
|
return {
|
|
468
543
|
...base,
|
|
469
544
|
type: "battleArmies",
|
|
@@ -473,7 +548,162 @@ function parseWebcastMessage(method, payload) {
|
|
|
473
548
|
battleStartMs,
|
|
474
549
|
battleDurationSeconds,
|
|
475
550
|
timeLeftSeconds,
|
|
476
|
-
endTimeMs
|
|
551
|
+
endTimeMs,
|
|
552
|
+
matchId,
|
|
553
|
+
sessionId,
|
|
554
|
+
serverTsMs,
|
|
555
|
+
sessionTag,
|
|
556
|
+
durationSec: battleDurationSeconds,
|
|
557
|
+
secsRemaining,
|
|
558
|
+
hosts
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
// Proto: WebcastLinkMicBattleItemCard
|
|
562
|
+
// #2 battleId
|
|
563
|
+
// #3 cardType (2=gloves/crit, 3=mist, 4=match_guide, 10=x2?, 11=x3, ...)
|
|
564
|
+
// #5/#6/#7/#14 inner (location varies with cardType — scan numerically):
|
|
565
|
+
// #1.{
|
|
566
|
+
// #1 effectKey
|
|
567
|
+
// #2 icon block { #1 repeated CDN urls, #2 iconKey, #5 accentColor }
|
|
568
|
+
// #3 activatedAtSec (unix seconds)
|
|
569
|
+
// #4 sender block: #1 sub { #1 userId, #2 nickname, #3 avatar block, #4 uniqueId }
|
|
570
|
+
// #5 durationSec
|
|
571
|
+
// #8 senderUserId (new boosters)
|
|
572
|
+
// #11 endsAtSec
|
|
573
|
+
// #12 senderUserId (old gloves/mist)
|
|
574
|
+
// }
|
|
575
|
+
// #3 comment template msg → #2 commentText
|
|
576
|
+
case "WebcastLinkMicBattleItemCard": {
|
|
577
|
+
const battleId = getIntStr(f, 2);
|
|
578
|
+
const cardType = getInt(f, 3);
|
|
579
|
+
let inner = null;
|
|
580
|
+
for (const fn of [5, 6, 7, 14, 15, 16, 8, 9, 10, 11, 12, 13]) {
|
|
581
|
+
const buf = getBytes(f, fn);
|
|
582
|
+
if (buf) {
|
|
583
|
+
inner = decodeProto(buf);
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
let effectKey = "";
|
|
588
|
+
let effect = "unknown";
|
|
589
|
+
let multiplier = 0;
|
|
590
|
+
let activatedAtSec = 0;
|
|
591
|
+
let durationSec = 0;
|
|
592
|
+
let endsAtSec = 0;
|
|
593
|
+
let senderUserId = "";
|
|
594
|
+
let senderNickname = "";
|
|
595
|
+
let senderUniqueId = "";
|
|
596
|
+
let senderAvatarUrl = "";
|
|
597
|
+
let commentTemplate = "";
|
|
598
|
+
let iconUrl = "";
|
|
599
|
+
let iconKey = "";
|
|
600
|
+
let accentColor = "";
|
|
601
|
+
if (inner) {
|
|
602
|
+
let nameBuf = getBytes(inner, 1);
|
|
603
|
+
let nf = nameBuf ? decodeProto(nameBuf) : [];
|
|
604
|
+
let probedKey = nf.length ? getStr(nf, 1) || "" : "";
|
|
605
|
+
if (!probedKey) {
|
|
606
|
+
const altBuf = getBytes(inner, 3);
|
|
607
|
+
if (altBuf) {
|
|
608
|
+
const altFields = decodeProto(altBuf);
|
|
609
|
+
const altKey = getStr(altFields, 1) || "";
|
|
610
|
+
if (altKey) {
|
|
611
|
+
nameBuf = altBuf;
|
|
612
|
+
nf = altFields;
|
|
613
|
+
probedKey = altKey;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
if (nameBuf && nf.length) {
|
|
618
|
+
effectKey = probedKey;
|
|
619
|
+
if (effectKey === "pm_mt_boost_crit_name") effect = "hammer";
|
|
620
|
+
else if (effectKey === "pm_mt_boost_glove_name" || effectKey === "pm_mt_boost_gloves_name") effect = "gloves";
|
|
621
|
+
else if (effectKey === "pm_mt_boost_mist_name") effect = "mist";
|
|
622
|
+
else if (effectKey === "pm_mt_match_guide_gotPowerUps") effect = "match_guide";
|
|
623
|
+
else if (effectKey.includes("userSentBooster_no2") || effectKey.includes("gotPowerUp_panel_no2")) {
|
|
624
|
+
effect = "booster_x2";
|
|
625
|
+
multiplier = 2;
|
|
626
|
+
} else if (effectKey.includes("userSentBooster_no3") || effectKey.includes("gotPowerUp_panel_no3")) {
|
|
627
|
+
effect = "booster_x3";
|
|
628
|
+
multiplier = 3;
|
|
629
|
+
} else if (effectKey.includes("thunder")) effect = "thunder";
|
|
630
|
+
else if (effectKey.includes("extra_time") || effectKey.includes("extra_round")) effect = "extra_time";
|
|
631
|
+
else if (effectKey) effect = effectKey;
|
|
632
|
+
activatedAtSec = getInt(nf, 3);
|
|
633
|
+
durationSec = getInt(nf, 5);
|
|
634
|
+
endsAtSec = getInt(nf, 11) || getInt(nf, 7);
|
|
635
|
+
senderUserId = getIntStr(nf, 12);
|
|
636
|
+
if (senderUserId === "0") senderUserId = getIntStr(nf, 8);
|
|
637
|
+
if (senderUserId === "0") senderUserId = getStr(nf, 13) || getStr(nf, 9) || "";
|
|
638
|
+
const iconBuf = getBytes(nf, 2);
|
|
639
|
+
if (iconBuf) {
|
|
640
|
+
const icf = decodeProto(iconBuf);
|
|
641
|
+
const urlBufs = getAllBytes(icf, 1);
|
|
642
|
+
for (const ub of urlBufs) {
|
|
643
|
+
const candidate = ub.toString("utf-8");
|
|
644
|
+
if (candidate.includes("://")) {
|
|
645
|
+
iconUrl = candidate;
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
iconKey = getStr(icf, 2) || "";
|
|
650
|
+
accentColor = getStr(icf, 5) || "";
|
|
651
|
+
}
|
|
652
|
+
const senderOuter = getBytes(nf, 4);
|
|
653
|
+
if (senderOuter) {
|
|
654
|
+
const sf = decodeProto(senderOuter);
|
|
655
|
+
const sub = getBytes(sf, 1);
|
|
656
|
+
if (sub) {
|
|
657
|
+
const su = decodeProto(sub);
|
|
658
|
+
const nickBuf = getBytes(su, 2);
|
|
659
|
+
if (nickBuf) {
|
|
660
|
+
try {
|
|
661
|
+
senderNickname = nickBuf.toString("utf-8");
|
|
662
|
+
} catch {
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
senderUniqueId = getStr(su, 4) || "";
|
|
666
|
+
if (!senderUserId || senderUserId === "0") senderUserId = getIntStr(su, 1);
|
|
667
|
+
const avBuf = getBytes(su, 3);
|
|
668
|
+
if (avBuf) {
|
|
669
|
+
const af = decodeProto(avBuf);
|
|
670
|
+
const urlBufs = getAllBytes(af, 1);
|
|
671
|
+
for (const ub of urlBufs) {
|
|
672
|
+
const candidate = ub.toString("utf-8");
|
|
673
|
+
if (candidate.includes("://")) {
|
|
674
|
+
senderAvatarUrl = candidate;
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
const commentBuf = getBytes(inner, 3);
|
|
683
|
+
if (commentBuf) {
|
|
684
|
+
const cf = decodeProto(commentBuf);
|
|
685
|
+
commentTemplate = getStr(cf, 2) || "";
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return {
|
|
689
|
+
...base,
|
|
690
|
+
type: "battleItemCard",
|
|
691
|
+
battleId,
|
|
692
|
+
cardType,
|
|
693
|
+
effect,
|
|
694
|
+
effectKey,
|
|
695
|
+
multiplier,
|
|
696
|
+
senderUserId,
|
|
697
|
+
senderNickname,
|
|
698
|
+
senderUniqueId,
|
|
699
|
+
senderAvatarUrl,
|
|
700
|
+
activatedAtSec,
|
|
701
|
+
durationSec,
|
|
702
|
+
endsAtSec,
|
|
703
|
+
commentTemplate,
|
|
704
|
+
iconUrl,
|
|
705
|
+
iconKey,
|
|
706
|
+
accentColor
|
|
477
707
|
};
|
|
478
708
|
}
|
|
479
709
|
// Proto: WebcastSubNotifyMessage { User user=2, ... subMonth=3 }
|
|
@@ -676,13 +906,13 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
676
906
|
preSignedCookies = credData.data.cookies || "";
|
|
677
907
|
preSignedUA = credData.data.user_agent || DEFAULT_UA;
|
|
678
908
|
ttwid = "__presigned__";
|
|
679
|
-
console.log(`[TikTokLive] \
|
|
909
|
+
console.log(`[TikTokLive] \xE2\u0153\u2026 Got pre-signed URL from sign server`);
|
|
680
910
|
} else {
|
|
681
|
-
console.log(`[TikTokLive] \
|
|
911
|
+
console.log(`[TikTokLive] \xE2\u0161\xA0\xEF\xB8\x8F ws_credentials bad response: ${JSON.stringify(credData).substring(0, 120)}`);
|
|
682
912
|
}
|
|
683
913
|
}
|
|
684
914
|
} catch (e) {
|
|
685
|
-
console.log(`[TikTokLive] \
|
|
915
|
+
console.log(`[TikTokLive] \xE2\x9D\u0152 ws_credentials failed: ${e.message}`);
|
|
686
916
|
}
|
|
687
917
|
if (!ttwid) {
|
|
688
918
|
console.log(`[TikTokLive] Fallback: direct TikTok fetch for ttwid...`);
|
|
@@ -697,9 +927,9 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
697
927
|
break;
|
|
698
928
|
}
|
|
699
929
|
}
|
|
700
|
-
console.log(`[TikTokLive] Direct fetch ttwid: ${ttwid ? "\
|
|
930
|
+
console.log(`[TikTokLive] Direct fetch ttwid: ${ttwid ? "\xE2\u0153\u2026" : "\xE2\x9D\u0152 none"}`);
|
|
701
931
|
} catch (e) {
|
|
702
|
-
console.log(`[TikTokLive] \
|
|
932
|
+
console.log(`[TikTokLive] \xE2\x9D\u0152 Direct TikTok fetch failed: ${e.message}`);
|
|
703
933
|
}
|
|
704
934
|
}
|
|
705
935
|
} else {
|
|
@@ -715,13 +945,13 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
715
945
|
const roomData = await roomResp.json();
|
|
716
946
|
if (roomData.status_code === 0 && roomData.data?.room_id) {
|
|
717
947
|
roomId = roomData.data.room_id;
|
|
718
|
-
console.log(`[TikTokLive] \
|
|
948
|
+
console.log(`[TikTokLive] \xE2\u0153\u2026 Got roomId from sign server: ${roomId}`);
|
|
719
949
|
} else {
|
|
720
|
-
console.log(`[TikTokLive] \
|
|
950
|
+
console.log(`[TikTokLive] \xE2\u0161\xA0\xEF\xB8\x8F room_id response: ${JSON.stringify(roomData).substring(0, 120)}`);
|
|
721
951
|
}
|
|
722
952
|
}
|
|
723
953
|
} catch (e) {
|
|
724
|
-
console.log(`[TikTokLive] \
|
|
954
|
+
console.log(`[TikTokLive] \xE2\x9D\u0152 room_id request failed: ${e.message}`);
|
|
725
955
|
}
|
|
726
956
|
if (roomId) {
|
|
727
957
|
try {
|
|
@@ -737,14 +967,14 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
737
967
|
const m = credData.data.cookies.match(/ttwid=([^;]+)/);
|
|
738
968
|
if (m) {
|
|
739
969
|
ttwid = m[1];
|
|
740
|
-
console.log(`[TikTokLive] \
|
|
741
|
-
} else console.log(`[TikTokLive] \
|
|
970
|
+
console.log(`[TikTokLive] \xE2\u0153\u2026 Got ttwid from sign server`);
|
|
971
|
+
} else console.log(`[TikTokLive] \xE2\u0161\xA0\xEF\xB8\x8F No ttwid in cookies: ${credData.data.cookies.substring(0, 60)}`);
|
|
742
972
|
} else {
|
|
743
|
-
console.log(`[TikTokLive] \
|
|
973
|
+
console.log(`[TikTokLive] \xE2\u0161\xA0\xEF\xB8\x8F No cookies in ws_credentials: ${JSON.stringify(credData).substring(0, 120)}`);
|
|
744
974
|
}
|
|
745
975
|
}
|
|
746
976
|
} catch (e) {
|
|
747
|
-
console.log(`[TikTokLive] \
|
|
977
|
+
console.log(`[TikTokLive] \xE2\x9D\u0152 ws_credentials failed: ${e.message}`);
|
|
748
978
|
}
|
|
749
979
|
}
|
|
750
980
|
if (!roomId || !ttwid) {
|
|
@@ -781,7 +1011,7 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
781
1011
|
}
|
|
782
1012
|
console.log(`[TikTokLive] Direct fetch result: roomId=${roomId || "none"}, ttwid=${ttwid ? "yes" : "none"}`);
|
|
783
1013
|
} catch (e) {
|
|
784
|
-
console.log(`[TikTokLive] \
|
|
1014
|
+
console.log(`[TikTokLive] \xE2\x9D\u0152 Direct TikTok fetch failed: ${e.message}`);
|
|
785
1015
|
}
|
|
786
1016
|
}
|
|
787
1017
|
}
|
|
@@ -867,18 +1097,21 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
867
1097
|
this.handleFrame(Buffer.from(rawData));
|
|
868
1098
|
});
|
|
869
1099
|
this.ws.on("close", (code, reason) => {
|
|
1100
|
+
const wasConnected = this._connected;
|
|
870
1101
|
this._connected = false;
|
|
871
1102
|
this.stopHeartbeat();
|
|
872
1103
|
const reasonStr = reason?.toString() || "";
|
|
873
1104
|
this.emit("disconnected", code, reasonStr);
|
|
874
|
-
if (!this.intentionalClose && this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
1105
|
+
if (wasConnected && !this.intentionalClose && this.autoReconnect && this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
875
1106
|
this.reconnectAttempts++;
|
|
876
1107
|
const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts - 1), 3e4);
|
|
877
1108
|
setTimeout(() => this.connect().catch((e) => this.emit("error", e)), delay);
|
|
878
1109
|
}
|
|
879
1110
|
});
|
|
880
1111
|
this.ws.on("error", (err) => {
|
|
881
|
-
this.
|
|
1112
|
+
if (this._connected) {
|
|
1113
|
+
this.emit("error", err);
|
|
1114
|
+
}
|
|
882
1115
|
if (!this._connected) reject(err);
|
|
883
1116
|
});
|
|
884
1117
|
});
|
|
@@ -895,7 +1128,7 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
895
1128
|
}
|
|
896
1129
|
/**
|
|
897
1130
|
* Fully destroy the client, releasing all resources and listeners.
|
|
898
|
-
* After calling destroy(), the instance cannot be reused
|
|
1131
|
+
* After calling destroy(), the instance cannot be reused — create a new one.
|
|
899
1132
|
*/
|
|
900
1133
|
destroy() {
|
|
901
1134
|
this.disconnect();
|
|
@@ -920,7 +1153,7 @@ var TikTokLive = class _TikTokLive extends EventEmitter {
|
|
|
920
1153
|
/**
|
|
921
1154
|
* Get live stream video URLs for a TikTok user.
|
|
922
1155
|
* Returns FLV & HLS URLs segmented by quality (FULL_HD1, HD1, SD1, SD2).
|
|
923
|
-
* This is a standalone method
|
|
1156
|
+
* This is a standalone method — no WebSocket connection required.
|
|
924
1157
|
*
|
|
925
1158
|
* @example
|
|
926
1159
|
* ```ts
|