Skip to content
This repository was archived by the owner on Jul 14, 2025. It is now read-only.

Repository files navigation

TikTok Live Rust

❤️❤️🎁 Connect to TikTok live in 3 lines 🎁❤️❤️

Introduction

A Rust library. Use it to receive live stream events such as comments and gifts in realtime from TikTok LIVE No credentials are required.

Join the support discord and visit the #rust-support channel for questions, contributions and ideas. Feel free to make pull requests with missing/new features, fixes, etc

Do you prefer other programming languages?

NOTE: This is not an official API. It's a reverse engineering project.

Overview

Getting started

Signing server API key

If you don't have a signing server you can obtain a free API key from EulerStream

Dependencies

[dependencies]
tiktoklive = "0.0.19"tokio = { version = "1.35.1", features = ["full"] }
serde_json = "1.0"log = "0.4"env_logger = "0.10.1"

Usage example

use env_logger::{Builder,Env};// Importing the logger builder and environment configurationuse log::LevelFilter;// Importing log level filteruse log::{error, warn};use std::time::Duration;// Importing Duration for timeout settingsuse tiktoklive::{// Importing necessary modules and structs from tiktoklive crate
core::live_client::TikTokLiveClient,
data::live_common::{ClientData,StreamData,TikTokLiveSettings},
errors::LibError,
generated::events::TikTokLiveEvent,TikTokLive,};use tokio::signal;// Importing signal handling from tokio#[tokio::main]// Main function is asynchronous and uses tokio runtimeasyncfnmain(){init_logger("info");// Initialize logger with "info" levellet user_name = "tragdate";let client = create_client(user_name);// Create a client for the given username// Spawn a new asynchronous task to connect the clientlet handle = tokio::spawn(asyncmove{// Attempt to connect the clientifletErr(e) = client.connect().await{match e {// Match on the error typeLibError::LiveStatusFieldMissing => {// Specific error casewarn!("Failed to get live status (probably needs authenticated client): {}",
e
);let auth_client = create_client_with_cookies(user_name);// Create an authenticated clientifletErr(e) = auth_client.connect().await{// Attempt to connect the authenticated clienterror!("Error connecting to TikTok Live after retry: {}", e);}}LibError::HeaderNotReceived => {error!("Error connecting to TikTok Live: {}", e);}
_ => {// General error caseerror!("Error connecting to TikTok Live: {}", e);}}}});
signal::ctrl_c().await.expect("Failed to listen for Ctrl+C");// Wait for Ctrl+C signal to gracefully shut down
handle.await.expect("The spawned task has panicked");// Await the spawned task to ensure it completes}fnhandle_event(client:&TikTokLiveClient,event:&TikTokLiveEvent){match event {TikTokLiveEvent::OnConnected(..) => {// This is an EXPERIMENTAL and UNSTABLE feature// Get room info from the clientlet room_info = client.get_room_info();// // Parse the room infolet client_data:ClientData = serde_json::from_str(room_info).unwrap();// // Parse the stream datalet stream_data:StreamData = serde_json::from_str(&client_data
.data.stream_url.live_core_sdk_data.unwrap().pull_data.stream_data,).unwrap();// Get the video URL for the low definition stream with fallback to the high definition stream in a flv formatlet video_url = stream_data
.data.ld.map(|ld| ld.main.flv).or_else(|| stream_data.data.sd.map(|sd| sd.main.flv)).or_else(|| stream_data.data.origin.map(|origin| origin.main.flv)).expect("None of the stream types set");println!("room info: {}", video_url);}// Match on the event typeTikTokLiveEvent::OnMember(join_event) => {// Handle member join eventprintln!("user: {} joined", join_event.raw_data.user.nickname);}TikTokLiveEvent::OnChat(chat_event) => {// Handle chat eventprintln!("user: {} -> {}",
chat_event.raw_data.user.nickname, chat_event.raw_data.content
);}TikTokLiveEvent::OnGift(gift_event) => {// Handle gift eventlet nick = &gift_event.raw_data.user.nickname;let gift_name = &gift_event.raw_data.gift.name;let gifts_amount = gift_event.raw_data.gift.combo;println!("user: {} sends gift: {} x {}",
nick, gift_name, gifts_amount
);}TikTokLiveEvent::OnLike(like_event) => {// Handle like eventlet nick = &like_event.raw_data.user.nickname;println!("user: {} likes", nick);}
_ => {}// Ignore other events}}// Function to initialize the logger with a default log levelfninit_logger(default_level:&str){let env = Env::default().filter_or("LOG_LEVEL", default_level);// Set default log level from environment or use provided levelBuilder::from_env(env)// Build the logger from environment settings.filter_module("tiktoklive",LevelFilter::Debug)// Set log level for tiktoklive module.init();// Initialize the logger}// Function to configure the TikTok live settingsfnconfigure(settings:&mutTikTokLiveSettings){
settings.http_data.time_out = Duration::from_secs(12);// Set HTTP timeout to 12 seconds
settings.sign_api_key = "".to_string();// Provide your own api key here}// Function to configure the TikTok live settings with cookies for authenticationfnconfigure_with_cookies(settings:&mutTikTokLiveSettings){
settings.http_data.time_out = Duration::from_secs(12);// Set HTTP timeout to 12 seconds
settings.sign_api_key = "".to_string();// Provide your own api key herelet contents = "";// Placeholder for cookies
settings
.http_data.headers.insert("Cookie".to_string(), contents.to_string());// Insert cookies into HTTP headers}// Function to create a TikTok live client for the given usernamefncreate_client(user_name:&str) -> TikTokLiveClient{TikTokLive::new_client(user_name)// Create a new client.configure(configure)// Configure the client.on_event(handle_event)// Set the event handler.build()// Build the client}// Function to create a TikTok live client with cookies for the given usernamefncreate_client_with_cookies(user_name:&str) -> TikTokLiveClient{TikTokLive::new_client(user_name)// Create a new client.configure(configure_with_cookies)// Configure the client with cookies.on_event(handle_event)// Set the event handler.build()// Build the client}

Library errors table

You can catch errors on events with

use tiktoklive::LibError;ifletErr(e) = client.connect().await{match e {LibError::UserFieldMissing => {println!("User field is missing");}
_ => {eprintln!("Error connecting to TikTok Live: {}", e);}}}
Error typeDescription
RoomIDFieldMissingRoom ID field is missing, contact developer
UserFieldMissingUser field is missing
UserDataFieldMissingUser data field is missing
LiveDataFieldMissingLive data field is missing
JsonParseErrorError parsing JSON
UserMessageFieldMissingUser message field is missing
ParamsErrorParams error
UserStatusFieldMissingUser status field is missing
LiveStatusFieldMissingLive status field is missing
TitleFieldMissingTitle field is missing
UserCountFieldMissingUser count field is missing
StatsFieldMissingStats field is missing
LikeCountFieldMissingLike count is missing
TotalUserFieldMissingTotal user field is missing
LiveRoomFieldMissingLive room field is missing
StartTimeFieldMissingStart time field is missing
UserNotFoundUser not found
HostNotOnlineLive stream for host is not online!, current status HostOffline
InvalidHostInvalid host in WebSocket URL
WebSocketConnectFailedFailed to connect to WebSocket
PushFrameParseErrorUnable to read push frame
WebcastResponseParseErrorUnable to read webcast response
AckPacketSendErrorUnable to send ack packet
HttpRequestFailedHTTP request failed
UrlSigningFailedURL signing failed
HeaderNotReceivedHeader was not received
BytesParseErrorUnable to parse bytes to Push Frame

Contributing

Your improvements are welcome! Feel free to open an issue or pull request.

Contributors

Zmole Cristian

About

Rust implementation of TikTok-Live-Connector library. Receive live stream events (comments, gifts, etc.) in realtime from TikTok LIVE.

Topics

Resources

Stars

45 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages