TypeError: issubclass() arg 1 must be a class
Closed this issue · 25 comments
Traceback (most recent call last):
File "...\test.py", line 24, in
client.run()
File "...\test.py", line 21, in run
return self._client.run()
^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\TikTokLive\client\client.py", line 170, in run
return self._asyncio_loop.run_until_complete(self.connect(**kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "...\Lib\site-packages\TikTokLive\client\client.py", line 155, in connect
await task
File "...\Lib\site-packages\TikTokLive\client\client.py", line 203, in _client_loop
async for event in self._ws_loop(initial_response):
File "...\Lib\site-packages\TikTokLive\client\client.py", line 240, in _ws_loop
for event in self.parse_webcast_response(response_message):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\TikTokLive\client\client.py", line 322, in parse_webcast_response
proto_event: ProtoEvent = event_type().parse(response.payload)
^^^^^^^^^^^^
File "", line 16, in init
File "...\Lib\site-packages\betterproto_init.py", line 631, in post_init
for field_name, meta in self.betterproto.meta_by_field_name.items():
^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\betterproto_init.py", line 698, in getattribute
value = super().getattribute(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\betterproto_init.py", line 754, in betterproto
meta = ProtoClassMetadata(self.class)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\betterproto_init.py", line 568, in init
self.default_gen = self.get_default_gen(cls, fields)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\betterproto_init.py", line 575, in _get_default_gen
return {field.name: cls.get_field_default_gen(field) for field in fields}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\betterproto_init.py", line 575, in
return {field.name: cls.get_field_default_gen(field) for field in fields}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...\Lib\site-packages\betterproto_init.py", line 910, in _get_field_default_gen
elif issubclass(t, Enum):
^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 1 must be a class
I'm getting the exactly same error. Any fix for this ?
OS: Win 11
Python version: 3.10.10
Last version of TikTokLive
I need debug...or code...or anything...
This one might be occurring in Windows only, as I'm also using it.
It is pretty straight forward, after you start the client, after some seconds, it crashes with this error.
It might happen with any example code on this platform, I was using the client just to print the comments, while testing
This happened to me too. Windows. With Example codes.
Even exemples codes trigger this error, it might be due to some gifts I think... but not sure. If i'm starting this on a Live Stream with 1-2 people that doens't have activity it doesn't throw this error, but if i start it on a stream with a higher amount of people into the Live Stream it throws very quickly.
And also along that error is one more that is quickly throwed and randomly:
Traceback (most recent call last):
File "D:\BibFullTikTok\main.py", line 172, in
asyncio.run(check_loop())
File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
return future.result()
File "D:\BibFullTikTok\main.py", line 166, in check_loop
await client.connect()
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 155, in connect
await task
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 203, in _client_loop
async for event in self._ws_loop(initial_response):
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 240, in _ws_loop
for event in self.parse_webcast_response(response_message):
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 322, in parse_webcast_response
proto_event: ProtoEvent = event_type().parse(response.payload)
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto_init.py", line 1015, in parse
value = self.postprocess_single(
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto_init.py", line 955, in postprocess_single
value = cls().parse(value)
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto_init.py", line 1015, in parse
value = self.postprocess_single(
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto_init.py", line 955, in postprocess_single
value = cls().parse(value)
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto_init.py", line 1008, in parse
decoded, pos = decode_varint(parsed.value, pos)
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto_init.py", line 487, in decode_varint
raise ValueError("Too many bytes when decoding varint.")
ValueError: Too many bytes when decoding varint.
Process finished with exit code 1
someone give me some code i can reproduce this with please
import aiohttp
import re
import datetime
from TikTokLive import TikTokLiveClient
from TikTokLive.client.logger import LogLevel
from TikTokLive.events import ConnectEvent, CommentEvent, GiftEvent, JoinEvent, LikeEvent
client: TikTokLiveClient = TikTokLiveClient(
unique_id="@biancabiiiiib"
)
async def reg_db(user, nickname, avatar, level, following, followers, last_seen):
url = 'http://localhost:5000/add_user'
data = {
'user': user,
'nickname': nickname,
'avatar': avatar,
'level': level,
'following_count': following,
'follower_count': followers,
'song_credits': 0,
'last_seen': last_seen,
'creation_date': datetime.datetime.now().isoformat()
}
async with aiohttp.ClientSession() as session:
async with session.post(url, json=data) as response:
return await response.text()
async def taptap(user, nickname, count):
url = 'http://localhost:5000/add_taptap'
data = {
'user': user,
'nickname': nickname,
'count': count
}
async with aiohttp.ClientSession() as session:
async with session.post(url, json=data) as response:
return await response.text()
async def giftz(user, nickname, gift_name, count):
url = 'http://localhost:5000/add_gift'
data = {
'user': user,
'nickname': nickname,
'gift_name': gift_name,
'count': count
}
async with aiohttp.ClientSession() as session:
async with session.post(url, json=data) as response:
return await response.text()
async def play(user, video):
url = f'http://localhost:5000/play/{user}/{video}'
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
client.logger.info(f"Connected to @{event.unique_id}!")
async def on_comment(event: CommentEvent) -> None:
video_id_pattern = r"(?:v=|\/)([0-9A-Za-z_-]{10,12})(?:&|\/|$)"
match = re.search(video_id_pattern, event.comment)
if match:
video_id = match.group(1)
await play(event.user.unique_id, video_id)
@client.on(JoinEvent)
async def on_join(event: JoinEvent):
#client.logger.info(f"Joined the live @{event.user.unique_id}!")
badge_list = event.user.badge_list
str_value = ""
if badge_list and len(badge_list) > 0:
str_value = badge_list[0].combine.str
await reg_db(event.user.unique_id, event.user.nickname, event.user.avatar_thumb.url_list[2], str_value,
event.user.follow_info.following_count, event.user.follow_info.follower_count,
datetime.datetime.now().isoformat())
@client.on(LikeEvent)
async def on_like(event: LikeEvent):
#client.logger.info(f"TapTap @{event.user.unique_id} -> {event.count}!")
await taptap(event.user.unique_id, event.user.nickname, event.count)
@client.on(GiftEvent)
async def on_gift(event: GiftEvent):
if event.gift.streakable and not event.streaking:
await giftz(event.user.unique_id, event.user.nickname, event.gift.name, event.gift.count)
# Non-streakable gift
elif not event.gift.streakable:
await giftz(event.user.unique_id, event.user.nickname, event.gift.name, event.gift.diamond_count)
badge_list = event.user.badge_list
str_value = ""
if badge_list and len(badge_list) > 0:
str_value = badge_list[0].combine.str
await reg_db(event.user.unique_id, event.user.nickname, event.user.avatar_thumb.url_list[2], str_value,
event.user.follow_info.following_count, event.user.follow_info.follower_count,
datetime.datetime.now().isoformat())
async def check_loop():
# Run 24/7
while True:
# Check if they're live
while not await client.is_live():
client.logger.info("Client is currently not live. Checking again in 60 seconds.")
await asyncio.sleep(120) # Spamming the endpoint will get you blocked
# Connect once they become live
client.logger.info("Requested client is live!")
await client.connect()
client.add_listener(CommentEvent, on_comment)
if __name__ == '__main__':
client.logger.setLevel(LogLevel.INFO.value)
asyncio.run(check_loop())
And also the API :
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, timedelta
import subprocess
app = Flask(__name__)
ytcast_path = r"C:\Users\twiff\Downloads\ytcast-v1.4.0-windows-amd64\ytcast.exe"
# Configure your MySQL database; replace USERNAME, PASSWORD, SERVER, and DBNAME with your actual database credentials
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:@127.0.0.1/bib_live?charset=utf8mb4'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {
'connect_args': {
'init_command': "SET time_zone='+03:00';", # Bucharest timezone offset
}
}
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(80), nullable=False)
nickname = db.Column(db.String(80), nullable=True)
avatar = db.Column(db.String(200), nullable=True)
level = db.Column(db.String(200), nullable=True, default=0)
following_count = db.Column(db.Integer, default=0, nullable=True)
follower_count = db.Column(db.Integer, default=0, nullable=True)
song_credits = db.Column(db.Integer, default=0)
last_seen = db.Column(db.DateTime, default=datetime.utcnow)
creation_date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<User %r>' % self.nickname
class TapTap(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(80), nullable=False)
nickname = db.Column(db.String(80), nullable=True)
count = db.Column(db.Integer, nullable=True)
creation_date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<User %r>' % self.nickname
class Gifts(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(80), nullable=False)
nickname = db.Column(db.String(80), nullable=True)
gift_name = db.Column(db.String(200), nullable=True)
count = db.Column(db.Integer, nullable=True)
creation_date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<User %r>' % self.nickname
class Play(db.Model):
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(80), nullable=False)
nickname = db.Column(db.String(80), nullable=True)
creation_date = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<User %r>' % self.nickname
#with app.app_context():
# db.create_all()
@app.route('/add_user', methods=['POST'])
def add_or_update_user():
data = request.json
user_identifier = data.get('user') # Assuming 'user' is a unique identifier
# Query the database for the user
existing_user = User.query.filter_by(user=user_identifier).first()
if existing_user:
# If the user exists, update the last_seen time
existing_user.last_seen = datetime.utcnow()
db.session.commit()
return jsonify({'message': 'User last_seen updated successfully!'}), 200
else:
# If the user does not exist, add a new user
new_user = User(
user=data.get('user'),
nickname=data.get('nickname'),
avatar=data.get('avatar'),
level=data.get('level', 1),
following_count=data.get('following_count', 0),
follower_count=data.get('follower_count', 0),
song_credits=data.get('song_credits', 0),
last_seen=data.get('last_seen', datetime.utcnow()),
creation_date=data.get('creation_date', datetime.utcnow())
)
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'User added successfully!'}), 201
@app.route('/add_taptap', methods=['POST'])
def add_taptapz():
data = request.json
new_taptap = TapTap(
user=data.get('user'),
nickname=data.get('nickname'),
count=data.get('count'),
creation_date=data.get('creation_date', datetime.utcnow())
)
db.session.add(new_taptap)
db.session.commit()
return jsonify({'message': 'User added successfully!'}), 201
@app.route('/add_gift', methods=['POST'])
def add_giftz():
data = request.json
new_gift = Gifts(
user=data.get('user'),
nickname=data.get('nickname'),
gift_name=data.get('gift_name'),
count=data.get('count'),
creation_date=data.get('creation_date', datetime.utcnow())
)
db.session.add(new_gift)
db.session.commit()
return jsonify({'message': 'User added successfully!'}), 201
@app.route('/update_play/<int:play_id>', methods=['POST'])
def update_play(play_id):
play_to_update = Play.query.get(play_id)
if play_to_update:
# Update the creation_date field to the current date and time
play_to_update.creation_date = datetime.utcnow()
db.session.commit()
return jsonify({'message': 'Play creation date updated successfully!'}), 200
else:
return jsonify({'message': 'Play record not found.'}), 404
@app.route('/play/<user_identifier>/<video>', methods=['GET'])
def check_song_credits_and_play(user_identifier, video):
# Query the database for the user by the unique identifier
user = User.query.filter_by(user=user_identifier).first()
print(user)
if user:
# Check if the user has song credits
if user.song_credits <= 0:
return jsonify({
'message': 'User has no song credits.',
'song_credits': user.song_credits,
'allow_play': False
}), 200
# Get the most recent item from the Play table for the user
last_play = Play.query.filter_by(id=1).order_by(Play.creation_date.desc()).first()
print(last_play)
if last_play:
da = datetime.utcnow() + timedelta(hours=2)
time_diff = da - last_play.creation_date
# Check if the time difference is less than 60 seconds
print(time_diff)
print(time_diff.total_seconds())
if time_diff.total_seconds() < 60:
return jsonify({
'message': 'Cannot play the song. Wait until 60 seconds have passed since the last play.',
'allow_play': False
}), 200
# Deduct one song credit because the user is allowed to play the song
user.song_credits -= 1
command = [ytcast_path, "-d", "e4e54d33", "https://youtu.be/"+ video]
try:
result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
print("Output:", result.stdout)
except subprocess.CalledProcessError as e:
print("Error:", e.stderr)
last_play.creation_date = datetime.utcnow() + timedelta(hours=2)
db.session.commit()
return jsonify({
'message': 'Song played successfully. One credit deducted.',
'song_credits': user.song_credits,
'allow_play': True
}), 200
else:
return jsonify({'message': 'User not found.'}), 404
if __name__ == '__main__':
app.run(debug=True)
I commented out:
#client.add_listener(GiftEvent, on_gift)
and still got the error. so its not something with gifts..
Python code:
https://pastebin.com/xY3SNN6S
Error logged:
https://pastebin.com/WtWguwaU
With how much stuff was added to proto in this latest update, I wouldn't be surprised if there's data types returned by tiktok that are being improperly handled from the webcast response.
The following code will crash within seconds if you insert a unique id of a live user that has a lot of events being passed:
from TikTokLive.client.client import TikTokLiveClient
from TikTokLive.client.logger import LogLevel
from TikTokLive.events import ConnectEvent
client: TikTokLiveClient = TikTokLiveClient(
unique_id="@" # Insert a unique id of a live user that has a lot of events being passed
)
@client.on(ConnectEvent)
async def on_connect(event: ConnectEvent):
client.logger.info(f"Connected to @{event.unique_id}!")
if __name__ == '__main__':
# Enable debug info
client.logger.setLevel(LogLevel.INFO.value)
# Connect
client.run()
The interim solution is there should be a proper error handler that doesn't crash the client LOL...then we can fix this specific proto error
The interim solution is there should be a proper error handler that doesn't crash the client LOL...then we can fix this specific proto error
You should probably add exception handling that captures the payload so it's easier to find which ones the schema fails to parse properly at the very least.
Unfortunately I will internally combust it if I have to add another thing onto my plate right now. Waaaay too stressed for this. PRs welcome or I'll get to it when I have a sec.
Any update on this error ? :<
Yes,
I am embarassed. This was a stupid issue.
The internal Type I created "MessageType" shadowed a TikTok proto field also called "MessageType". This caused an instance of the TypeVar to be passed to an is_subclass
in the proto type-checker, throwing the familiar and horrifying error.
Release: https://github.com/isaackogan/TikTokLive/releases/tag/v6.0.1-post1
Commit: 5faa492
Install: pip install TikTokLive==6.0.1.post1
Will close this in 2 days if the issue is resolved.
Thank you for the fix. I'm running it now, it looks like it was fixed and it does work. I'll keep an eye on it and if theres any other bug i'll report it.
Also check the error with "AttributeError: 'GiftEvent' object has no attribute 'streakable'"
Exception in callback AsyncIOEventEmitter._emit_run.<locals>.callback(<Task finishe...streakable'")>) at D:\BibFullTikTok\venv\lib\site-packages\pyee\asyncio.py:69
handle: <Handle AsyncIOEventEmitter._emit_run.<locals>.callback(<Task finishe...streakable'")>) at D:\BibFullTikTok\venv\lib\site-packages\pyee\asyncio.py:69>
Traceback (most recent call last):
File "C:\Program Files\Python310\lib\asyncio\events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "D:\BibFullTikTok\venv\lib\site-packages\pyee\asyncio.py", line 77, in callback
self.emit("error", exc)
File "D:\BibFullTikTok\venv\lib\site-packages\pyee\base.py", line 211, in emit
self._emit_handle_potential_error(event, args[0] if args else None)
File "D:\BibFullTikTok\venv\lib\site-packages\pyee\base.py", line 169, in _emit_handle_potential_error
raise error
File "D:\BibFullTikTok\main.py", line 111, in on_gift
if event.gift.streakable and not event.streaking:
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto\__init__.py", line 698, in __getattribute__
value = super().__getattribute__(name)
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\events\proto_events.py", line 99, in streaking
if not self.streakable:
File "D:\BibFullTikTok\venv\lib\site-packages\betterproto\__init__.py", line 698, in __getattribute__
value = super().__getattribute__(name)
AttributeError: 'GiftEvent' object has no attribute 'streakable'
Also check the error with "AttributeError: 'GiftEvent' object has no attribute 'streakable'"
Way ahead of you.
pip install TikTokLive==6.0.1.post2
Found another one after 13 minutes of running it
Traceback (most recent call last):
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 963, in transfer_data
message = await self.read_message()
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 1033, in read_message
frame = await self.read_data_frame(max_size=self.max_size)
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 1108, in read_data_frame
frame = await self.read_frame(max_size)
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 1165, in read_frame
frame = await Frame.read(
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\framing.py", line 68, in read
data = await reader(2)
File "C:\Program Files\Python310\lib\asyncio\streams.py", line 705, in readexactly
raise exceptions.IncompleteReadError(incomplete, n)
asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 2 expected bytes
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\BibFullTikTok\main.py", line 147, in <module>
asyncio.run(check_loop())
File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
return future.result()
File "D:\BibFullTikTok\main.py", line 141, in check_loop
await client.connect()
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 156, in connect
await task
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 204, in _client_loop
async for event in self._ws_loop(initial_response):
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 228, in _ws_loop
async for response_message in self._ws.connect(*self._build_connect_info(initial_response)):
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\ws\ws_client.py", line 145, in connect
async for webcast_message in self.connect_loop(uri, headers):
File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\ws\ws_client.py", line 181, in connect_loop
async for message in websocket:
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 498, in __aiter__
yield await self.recv()
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 568, in recv
await self.ensure_open()
File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 939, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: no close frame received or sent
Process finished with exit code 1
(venv) D:\BibFullTikTok>pip install TikTokLive==6.0.1.post2
ERROR: Ignored the following yanked versions: 4.3.2
ERROR: Could not find a version that satisfies the requirement TikTokLive==6.0.1.post2 (from versions: 0.0.1, 0.6.9, 0.7.0, 0.7.5, 0.8.0, 0.8.2, 0.8.5, 0.8.6, 0.8.9, 4.2.0, 4.2.5, 4.2.6, 4.3.0, 4.3.3, 4.3.5, 4.3.6, 4.3.7, 4.3.8, 4.5.0, 4.5.1, 4.5.2, 5.0.0, 5.0.1, 5.0.5, 5.0.6, 5.0.7, 5.0.8, 6.0.0rc1, 6.0.0, 6.0.0.post1, 6.0.1, 6.0.1.post1, 6.0.2.post1)
ERROR: No matching distribution found for TikTokLive==6.0.1.post2
My dumb-ass self named it 6.0.2.post1
...
Found another one after 13 minutes of running it
Traceback (most recent call last): File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 963, in transfer_data message = await self.read_message() File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 1033, in read_message frame = await self.read_data_frame(max_size=self.max_size) File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 1108, in read_data_frame frame = await self.read_frame(max_size) File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 1165, in read_frame frame = await Frame.read( File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\framing.py", line 68, in read data = await reader(2) File "C:\Program Files\Python310\lib\asyncio\streams.py", line 705, in readexactly raise exceptions.IncompleteReadError(incomplete, n) asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 2 expected bytes The above exception was the direct cause of the following exception: Traceback (most recent call last): File "D:\BibFullTikTok\main.py", line 147, in <module> asyncio.run(check_loop()) File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run return loop.run_until_complete(main) File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete return future.result() File "D:\BibFullTikTok\main.py", line 141, in check_loop await client.connect() File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 156, in connect await task File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 204, in _client_loop async for event in self._ws_loop(initial_response): File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\client.py", line 228, in _ws_loop async for response_message in self._ws.connect(*self._build_connect_info(initial_response)): File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\ws\ws_client.py", line 145, in connect async for webcast_message in self.connect_loop(uri, headers): File "D:\BibFullTikTok\venv\lib\site-packages\TikTokLive\client\ws\ws_client.py", line 181, in connect_loop async for message in websocket: File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 498, in __aiter__ yield await self.recv() File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 568, in recv await self.ensure_open() File "D:\BibFullTikTok\venv\lib\site-packages\websockets\legacy\protocol.py", line 939, in ensure_open raise self.connection_closed_exc() websockets.exceptions.ConnectionClosedError: no close frame received or sent Process finished with exit code 1
Did the stream stop perhaps? This error suggests the connection was closed by TikTok "suddenly".
Nope the stream was still active, watching it.
Welp, sorry to say I have put in all the time I have today. I will float this by the folks at TikTokLiveJava and see if they've seen this...that's all I can do.
Reading up on it, what you are describing seems like a client issue, not a TikTokLive issue.
I'm going to close this as resolved. Please open another issue @Unchangeable if you continue to face your separate issue, so I can fix it.