TikTok Live Connection Client Clone
Project description
TikTokLiveClone
Original Details:
A Python library to connect to and read events from TikTok's LIVE service.
A Python library to receive and decode livestream events such as comments and gifts in real-time from TikTok's LIVE service by connecting to TikTok's internal Webcast service. This library includes a wrapper that
connects to the Webcast service using only a user's unique_id
and allows you to join your livestream as well as that of other streamers. No credentials are required to use TikTokLive.
This library was originally based off of the TikTok-Live-Connector by @zerodytrash, but has since taken on its own identity as it has added more features & changed much of its core functionality.
Join the support discord and visit the #py-support
channel for questions, contributions and ideas. Feel free to make pull requests with missing/new features, fixes, etc.
UPDATE:
Due to a change on the part of TikTok, versions prior to v4.3.8 are no longer functional. If you are using an unsupported version, upgrade to the latest version using thepip install TikTokLive --upgrade
command.
Other Languages
TikTok LIVE is available in several alternative languages with only slight differences between the versions:
- Node.JS: https://github.com/zerodytrash/TikTok-Live-Connector
- Go: https://github.com/Davincible/gotiktoklive
- C#/Unity: https://github.com/frankvHoof93/TikTokLiveSharp
Table of Contents
Primary Information
Resources & Guides
- David's Intro Tutorial
- Getting Started
- Params & Options
- Client Methods
- Client Attributes
- TikTok Events
TikTokLive Intro Tutorial
I cannot recommend this tutorial enough for people trying to get started. It is succinct, informative and easy to understand, created by David Teather, the creator of the Python TikTok-Api package. Click the thumbnail to warp.
Getting Started
- Install the module via pip
> pip install TikTokLive
- Create your first chat connection
from TikTokLive import TikTokLiveClient
from TikTokLive.types.events import CommentEvent, ConnectEvent
# Instantiate the client with the user's username
client: TikTokLiveClient = TikTokLiveClient(unique_id="@isaackogz")
# Define how you want to handle specific events via decorator
@client.on("connect")
async def on_connect(_: ConnectEvent):
print("Connected to Room ID:", client.room_id)
# Notice no decorator?
async def on_comment(event: CommentEvent):
print(f"{event.user.nickname} -> {event.comment}")
# Define handling an event via a "callback"
client.add_listener("comment", on_comment)
if __name__ == '__main__':
# Run the client and block the main thread
# await client.start() to run non-blocking
client.run()
For more examples, see the examples folder provided in the tree.
Params & Options
To create a new TikTokLiveClient
object the following parameter is required. You can optionally add configuration options to this via kwargs.
TikTokLiveClient(unique_id, **options)
Param Name | Required | Description |
---|---|---|
unique_id | Yes | The unique username of the broadcaster. You can find this name in the URL. Example: https://www.tiktok.com/@isaackogz => isaackogz |
**options | No | Here you can set the following optional connection properties. If you do not specify a value, the default value will be used.process_initial_data (default: True ) Define if you want to process initial data upon connecting (e.g. first 1-10 messages from BEFORE you connected). fetch_room_info_on_connect (default: True ) Define if you want to fetch all room information on start. If this option is enabled, connection to offline rooms will be prevented. If enabled, the connect result contains the room info via the room_info attribute. You can also manually retrieve the room info (even in an unconnected state) using the retrieve_room_info() method.enable_detailed_gifts (default: False ) Define if you want to receive extended information about gifts like gift name, cost and images which you can retrieve via the available_gifts attribute. When enabled, the details attribute in a Gift object will be populated.ws_ping_interval (default: 10.0 ) The interval between keepalive pings on the websocket connection (in seconds). ws_timeout (default: 10.0 )How long to wait before the websocket connection is considered timed out (in seconds). http_timeout (default: 10.0 ) How long to wait before considering an HTTP request in the http client timed out (in seconds). http_headers (default: {} ) Additional HTTP client headers to include when making requests to the Webcast API AND connecting to the websocket server. http_params (default: {} ) Additional HTTP client parameters to include when making requests to the Webcast API AND connecting to the websocket. loop (default: None )Optionally supply your own asyncio event loop for usage by the client. When set to None, the client pulls the current active loop or creates a new one. This option is mostly useful for people trying to nest asyncio. trust_env (default: False )Whether to trust environment variables that provide proxies in httpx requests proxies (default: None )Enable proxied requests by turning on forwarding for the HTTP "proxies" argument. Websocket connections will NOT be proxied lang (default: en-US )Change the language. Payloads will be in English, but front-end content will be in the desired language! sign_api_key (default: None )Parameter to increase the amount of connections allowed to be made per minute via a Sign Server API key. If you need this, contact the project maintainer. ssl_context (default: None )Providing an SSLContext object overrides the default context used in HTTP requests made to TikTok. This is useful if TikTok sends invalid SSL signatures, as you can provide a "no verify" context. |
Methods
A TikTokLiveClient
object contains the following methods:
Method Name | Description |
---|---|
run | Starts a connection to the live chat while blocking the main thread |
start | (async) Connects to the live chat without blocking the main thread |
stop | Turns off the connection to the live chat. |
retrieve_room_info | (async) Gets the current room info from TikTok API |
retrieve_available_gifts | (async) Retrieves a list of the available gifts for the room and adds it to the extended_gift attribute of the Gift object on the gift event, when enabled. |
add_listener | Adds an asynchronous listener function (or, you can decorate a function with @client.on("<event>") ) and takes two parameters, an event name and the payload, an AbstractEvent |
download | Start downloading the livestream video for a given duration or until stopped via the stop_download method. Supports the ability to add different flags, like -c copy which may reduce CPU usage by disabling transcoding. |
stop_download | Stop downloading the livestream video if currently downloading, otherwise throws an error |
Attributes
A TikTokLiveClient
object contains the following attributes:
Attribute Name | Description |
---|---|
room_id | The Room ID of the livestream room the client is currently connected to |
room_info | Information about the given livestream room |
unique_id | The TikTok username of the person whose livestream the client is currently connected to (e.g. @charlidamelio) |
connected | Whether the client is currently connected to a livestream |
connecting | Whether the client is currently connecting to a livestream |
available_gifts | A dictionary containing K:V pairs of Dict[int, GiftDetailed] , where the int is the internal TikTok gift id |
proxies | Get the current proxies being used for HTTP requests. Note: To set the active proxies, set the value of this attribute |
loop | The asyncio event loop the client is running off of |
http | The HTTP client TikTokLive uses to make all HTTP-based requests |
websocket | The WebcastWebsocketConnection websocket client TikTokLive uses to manage its websocket connection |
ffmpeg | The ffmpeg wrapper TikTokLive uses to manage ffmpeg-based stream downloads |
viewer_count | The number of people currently watching the livestream broadcast. Updated automatically on a viewer_update event |
top_viewers | The top N (usually ~1-20) users, ranked by coins gifted to the streamer, for the broadcast. Updated automatically on a viewer_update event |
Events
A TikTokLiveClient
object has the following events. You can add events either by doing client.add_listener("event_name", callable)
or by decorating a function with @client.on("event_name")
that includes an event
payload parameter.
connect
Triggered when the websocket connection is successfully established.
@client.on("connect")
async def on_connect(event: ConnectEvent):
print("Connected")
disconnect
Triggered when the connection is terminated. You can call start()
to reconnect . Note that you should wait a little bit before attempting a reconnect to to avoid being rate-limited.
@client.on("disconnect")
async def on_disconnect(event: DisconnectEvent):
print("Disconnected")
like
Triggered every time someone likes the stream.
@client.on("like")
async def on_like(event: LikeEvent):
print(f"@{event.user.unique_id} liked the stream!")
join
Triggered every time a new person joins the stream.
@client.on("join")
async def on_join(event: JoinEvent):
print(f"@{event.user.unique_id} joined the stream!")
gift
Triggered every time a gift arrives. Extra information can be gleamed off the available_gifts
client attribute.
NOTE: Users have the capability to send gifts in a streak. This increases the
event.gift.count
value until the user terminates the streak. During this time new gift events are triggered again and again with an increasedevent.gift.count
value. It should be noted that after the end of the streak, another gift event is triggered, which signals the end of the streak viaevent.gift.is_repeating
:1
. This applies only to gifts withevent.gift.info.type
:1
. This means that even if the user sends anevent.gift.info.type
:1
gift only once, you may receive the event twice. Once withevent.gift.is_repeating
:0
and once withevent.gift.is_repeating
:1
. Therefore, the event should be handled as follows in one of TWO ways. These are the same, except the second is a 'higher level' implementation using TikTokLive API features:
@client.on("gift")
async def on_gift(event: GiftEvent):
# If it's type 1 and the streak is over
if event.gift.info.type == 1:
if event.gift.is_repeating == 1:
print(f"{event.user.unique_id} sent {event.gift.count}x \"{event.gift.info.name}\"")
# It's not type 1, which means it can't have a streak & is automatically over
elif event.gift.info.type != 1:
print(f"{event.user.unique_id} sent \"{event.gift.info.name}\"")
@client.on("gift")
async def on_gift(event: GiftEvent):
# Streakable gift & streak is over
if event.gift.streakable and not event.gift.streaking:
print(f"{event.user.unique_id} sent {event.gift.count}x \"{event.gift.info.name}\"")
# Non-streakable gift
elif not event.gift.streakable:
print(f"{event.user.unique_id} sent \"{event.gift.info.name}\"")
follow
Triggered every time someone follows the streamer.
@client.on("follow")
async def on_follow(event: FollowEvent):
print(f"@{event.user.unique_id} followed the streamer!")
share
Triggered every time someone shares the stream.
@client.on("share")
async def on_share(event: ShareEvent):
print(f"@{event.user.unique_id} shared the stream!")
more_share
Triggered when 5 or 10 users join from a viewer's share link.
@client.on("more_share")
async def on_connect(event: MoreShareEvent):
print(f"More than {event.amount} users have joined from {event.user.unique_id}'s share link!")
viewer_update
Triggered every time the viewer count is updated. This event also updates the cached viewer count by default.
@client.on("viewer_update")
async def on_connect(event: ViewerUpdateEvent):
# Viewer Count
print("Received a new viewer count:", event.viewer_count)
print("The client automatically sets the count as an attribute too:", client.viewer_count)
# Top VIewers
print("You can even get the top viewers (by coins gifted)!:", event.top_viewers)
print("The client automatically sets the top viewers as an attribute too:", client.top_viewers)
comment
Triggered every time someone comments on the live.
@client.on("comment")
async def on_connect(event: CommentEvent):
print(f"{event.user.nickname} -> {event.comment}")
emote
Triggered when someone sends a subscription emote comment to the live chat.
@client.on("emote")
async def on_connect(event: EmoteEvent):
print(f"{event.user.nickname} -> {event.emote.image.url}")
envelope
Triggered when someone sends an envelope (treasure box) to the TikTok streamer.
@client.on("envelope")
async def on_connect(event: EnvelopeEvent):
print(f"{event.treasure_box_user.unique_id} -> {event.treasure_box_data}")
ranking_update
Triggered when a stream rank update is sent out. Can be Weekly Ranking
or Rising Star
!
@client.on("ranking_update")
async def on_connect(event: RankingUpdateEvent):
print(f"{event.user.unique_id} has the rank #{event.rank} for the {event.type} leaderboard.")
user_ranking_update
Triggered when a user rank update is sent out. Can be Top Viewer
status.
@client.on("user_ranking_update")
async def on_connect(event: UserRankingUpdateEvent):
print(f"{event.user.unique_id} just became a #{event.rank} top viewer!")
mic_battle_start
Triggered when a Mic Battle starts!
@client.on("mic_battle_start")
async def on_connect(event: MicBattleStartEvent):
print(f"A Mic battle has started!")
mic_battle_update
Triggered when information is received about a mic battle's progress.
@client.on("mic_battle_update")
async def on_connect(event: MicBattleUpdateEvent):
print(f"An army in the mic battle has received points, or the status of the battle has changed!")
live_end
Triggered when the live stream gets terminated by the host.
@client.on("live_end")
async def on_connect(event: LiveEndEvent):
print(f"Livestream ended :(")
intro_message
Triggered when an intro message is sent to the live room. An intro message is basically a pinned message at the top of chat when you join a room.
This event only fires if "process_initial_data" is enabled and the streamer has an intro message configured.
@client.on("intro_message")
async def on_connect(event: IntroMessageEvent):
print(f"Message: {event.message}")
unknown
Triggered when ANY unknown event is received that is not yet handled by this client.
This includes both events where the protobuf has NOT been decoded, as well as events where it has been decoded, but no event object has been created (e.g. it's useless data).
Use this event to debug and find new events to add to TikTokLive. Mention them here when you do.
This event is very advanced and handles both types of cases, an API to help you decode including offering the binary as base64. You can plug base64 into https://protobuf-decoder.netlify.app/ to reverse-engineer the protobuf schema.
@client.on("unknown")
async def on_connect(event: UnknownEvent):
print(f"Event Type: {event.type}")
print(f"Event Base64: {event.base64}")
error
Triggered when there is an error in the client or error handlers.
If this handler is not present in the code, an internal default handler will log errors in the console. If a handler is added, all error handling (including logging) is up to the individual.
Warning: If you listen for the error event and do not log errors, you will not see when an error occurs. This expected behaviour, listening to the error event overrides & disables the built-in one.
@client.on("error")
async def on_connect(error: Exception):
# Handle the error
if isinstance(error, SomeRandomError):
print("Handle some error!")
return
# Otherwise, log the error
# You can use the internal method, but ideally your own
client._log_error(error)
Contributors
- Isaac Kogan - Creator, Primary Maintainer, and Reverse-Engineering - isaackogan
- Zerody - Initial Reverse-Engineering Protobuf & Support - Zerody
- Davincible - Reverse-Engineering Stream Downloads - davincible
- David Teather - TikTokLive Introduction Tutorial - davidteather
See also the full list of contributors who have participated in this project.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file TikTokLiveClone-1.0.1.tar.gz
.
File metadata
- Download URL: TikTokLiveClone-1.0.1.tar.gz
- Upload date:
- Size: 44.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5de677afa7f26d1fbc5dcb291b08b97ff729cf60d98f622de727f822dba0d436 |
|
MD5 | 3320185ca7d6ceabf5dc8c710d2b4ff6 |
|
BLAKE2b-256 | 9caf63eb144dffb923318affbb7917d8a48ce2cb8c2dab1d7dc09b4e77381eea |
File details
Details for the file TikTokLiveClone-1.0.1-py3-none-any.whl
.
File metadata
- Download URL: TikTokLiveClone-1.0.1-py3-none-any.whl
- Upload date:
- Size: 74.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.10.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cd72851792cd6b3b7ca9e80d20563a8ec3466ea1432805551c210ec6ee7d7bf1 |
|
MD5 | 7d9b31ed55cbc3e40b20dd9c4a3cd615 |
|
BLAKE2b-256 | 434d1eac8878be1544764cd57bbb72b00428c72f2887bbe238352a02c689cb07 |