{"id":20397628,"url":"https://github.com/jwdeveloper/tiktokliverust","last_synced_at":"2025-03-03T05:02:53.156Z","repository":{"id":215795883,"uuid":"738670444","full_name":"jwdeveloper/TikTokLiveRust","owner":"jwdeveloper","description":"Rust implementation of TikTok-Live-Connector library.  Receive live stream events (comments, gifts, etc.) in realtime from TikTok LIVE.","archived":false,"fork":false,"pushed_at":"2024-08-31T17:28:20.000Z","size":678,"stargazers_count":29,"open_issues_count":0,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-02T19:54:38.568Z","etag":null,"topics":["api","chat","live","tiktok-api","tiktok-client","tiktok-live","tiktok-live-client"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jwdeveloper.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":"FUNDING.yml","license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"jwdeveloper","custom":["https://www.buymeacoffee.com/jwdev"]}},"created_at":"2024-01-03T19:11:13.000Z","updated_at":"2025-02-25T14:32:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"f5d7a98f-1238-4f63-8f87-290b759dc9ec","html_url":"https://github.com/jwdeveloper/TikTokLiveRust","commit_stats":null,"previous_names":["jwdeveloper/tiktokliverust"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwdeveloper%2FTikTokLiveRust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwdeveloper%2FTikTokLiveRust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwdeveloper%2FTikTokLiveRust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwdeveloper%2FTikTokLiveRust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwdeveloper","download_url":"https://codeload.github.com/jwdeveloper/TikTokLiveRust/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241605819,"owners_count":19989612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","chat","live","tiktok-api","tiktok-client","tiktok-live","tiktok-live-client"],"created_at":"2024-11-15T04:15:51.026Z","updated_at":"2025-03-03T05:02:53.137Z","avatar_url":"https://github.com/jwdeveloper.png","language":"Rust","funding_links":["https://patreon.com/jwdeveloper","https://www.buymeacoffee.com/jwdev"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\" \u003e\n\u003ca target=\"blank\" \u003e\n\u003cimg src=\"https://github.com/jwdeveloper/TikTokLiveRust/assets/79764581/5ae5385c-d31a-40d9-aa5c-9c8b06aae161\" width=\"15%\" \u003e\n\u003c/a\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\" \u003e\n\u003ch1\u003eTikTok Live Rust\u003c/h1\u003e\n\n❤️❤️🎁 _Connect to TikTok live in 3 lines_ 🎁❤️❤️\n\n\u003cdiv align=\"center\" \u003e\n\n\u003ca href=\"https://crates.io/crates/tiktoklive\" target=\"blank\" \u003e\n\u003cimg src=\"https://img.shields.io/crates/v/tiktoklive.svg\" \u003e\n\u003c/a\u003e\n\n\u003ca href=\"https://discord.gg/e2XwPNTBBr\" target=\"blank\" \u003e\n\u003cimg src=\"https://img.shields.io/discord/977648006063091742.svg?color=7289da\u0026logo=discord\u0026style=flat-square\" \u003e\n\u003c/a\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\n# Introduction\n\nA Rust library. Use it to receive live stream events such as comments and gifts in realtime from [TikTok LIVE](https://www.tiktok.com/live) No credentials are required.\n\nJoin the support [discord](https://discord.gg/e2XwPNTBBr) and visit the `#rust-support` channel for questions, contributions and ideas. Feel free to make pull requests with missing/new features, fixes, etc\n\nDo you prefer other programming languages?\n\n- **Java** [TikTokLiveJava](https://github.com/jwdeveloper/TikTokLiveJava)\n- **Node** [TikTok-Live-Connector](https://github.com/zerodytrash/TikTok-Live-Connector) by [@zerodytrash](https://github.com/zerodytrash)\n- **Python** [TikTokLive](https://github.com/isaackogan/TikTokLive) by [@isaackogan](https://github.com/isaackogan)\n- **C#** [TikTokLiveSharp](https://github.com/frankvHoof93/TikTokLiveSharp) by [@frankvHoof93](https://github.com/frankvHoof93)\n\n**NOTE:** This is not an official API. It's a reverse engineering project.\n\n#### Overview\n\n- [Getting started](#getting-started)\n- [Documentation](https://docs.rs/tiktoklive/latest/tiktoklive/)\n- [Contributing](#contributing)\n\n## Getting started\n\n### Signing server API key\n\nIf you don't have a signing server you can obtain a free API key from [EulerStream](https://www.eulerstream.com/) \n\n### Dependencies\n\n```toml\n[dependencies]\ntiktoklive = \"0.0.19\"\ntokio = { version = \"1.35.1\", features = [\"full\"] }\nserde_json = \"1.0\"\nlog = \"0.4\"\nenv_logger = \"0.10.1\"\n```\n\n### Usage example\n\n```rust\nuse env_logger::{Builder, Env}; // Importing the logger builder and environment configuration\nuse log::LevelFilter; // Importing log level filter\nuse log::{error, warn};\nuse std::time::Duration; // Importing Duration for timeout settings\nuse tiktoklive::{\n    // Importing necessary modules and structs from tiktoklive crate\n    core::live_client::TikTokLiveClient,\n    data::live_common::{ClientData, StreamData, TikTokLiveSettings},\n    errors::LibError,\n    generated::events::TikTokLiveEvent,\n    TikTokLive,\n};\nuse tokio::signal; // Importing signal handling from tokio\n\n#[tokio::main] // Main function is asynchronous and uses tokio runtime\nasync fn main() {\n    init_logger(\"info\"); // Initialize logger with \"info\" level\n    let user_name = \"tragdate\";\n\n    let client = create_client(user_name); // Create a client for the given username\n\n    // Spawn a new asynchronous task to connect the client\n    let handle = tokio::spawn(async move {\n        // Attempt to connect the client\n        if let Err(e) = client.connect().await {\n            match e {\n                // Match on the error type\n                LibError::LiveStatusFieldMissing =\u003e {\n                    // Specific error case\n                    warn!(\n                        \"Failed to get live status (probably needs authenticated client): {}\",\n                        e\n                    );\n                    let auth_client = create_client_with_cookies(user_name); // Create an authenticated client\n                    if let Err(e) = auth_client.connect().await {\n                        // Attempt to connect the authenticated client\n                        error!(\"Error connecting to TikTok Live after retry: {}\", e);\n                    }\n                }\n                LibError::HeaderNotReceived =\u003e {\n                    error!(\"Error connecting to TikTok Live: {}\", e);\n                }\n\n                _ =\u003e {\n                    // General error case\n                    error!(\"Error connecting to TikTok Live: {}\", e);\n                }\n            }\n        }\n    });\n\n    signal::ctrl_c().await.expect(\"Failed to listen for Ctrl+C\"); // Wait for Ctrl+C signal to gracefully shut down\n\n    handle.await.expect(\"The spawned task has panicked\"); // Await the spawned task to ensure it completes\n}\n\nfn handle_event(client: \u0026TikTokLiveClient, event: \u0026TikTokLiveEvent) {\n    match event {\n        TikTokLiveEvent::OnConnected(..) =\u003e {\n            // This is an EXPERIMENTAL and UNSTABLE feature\n            // Get room info from the client\n            let room_info = client.get_room_info();\n            // // Parse the room info\n            let client_data: ClientData = serde_json::from_str(room_info).unwrap();\n            // // Parse the stream data\n            let stream_data: StreamData = serde_json::from_str(\n                \u0026client_data\n                    .data\n                    .stream_url\n                    .live_core_sdk_data\n                    .unwrap()\n                    .pull_data\n                    .stream_data,\n            )\n            .unwrap();\n            // Get the video URL for the low definition stream with fallback to the high definition stream in a flv format\n            let video_url = stream_data\n                .data\n                .ld\n                .map(|ld| ld.main.flv)\n                .or_else(|| stream_data.data.sd.map(|sd| sd.main.flv))\n                .or_else(|| stream_data.data.origin.map(|origin| origin.main.flv))\n                .expect(\"None of the stream types set\");\n            println!(\"room info: {}\", video_url);\n        }\n\n        // Match on the event type\n        TikTokLiveEvent::OnMember(join_event) =\u003e {\n            // Handle member join event\n            println!(\"user: {} joined\", join_event.raw_data.user.nickname);\n        }\n        TikTokLiveEvent::OnChat(chat_event) =\u003e {\n            // Handle chat event\n            println!(\n                \"user: {} -\u003e {}\",\n                chat_event.raw_data.user.nickname, chat_event.raw_data.content\n            );\n        }\n        TikTokLiveEvent::OnGift(gift_event) =\u003e {\n            // Handle gift event\n            let nick = \u0026gift_event.raw_data.user.nickname;\n            let gift_name = \u0026gift_event.raw_data.gift.name;\n            let gifts_amount = gift_event.raw_data.gift.combo;\n            println!(\n                \"user: {} sends gift: {} x {}\",\n                nick, gift_name, gifts_amount\n            );\n        }\n        TikTokLiveEvent::OnLike(like_event) =\u003e {\n            // Handle like event\n            let nick = \u0026like_event.raw_data.user.nickname;\n            println!(\"user: {} likes\", nick);\n        }\n        _ =\u003e {} // Ignore other events\n    }\n}\n\n// Function to initialize the logger with a default log level\nfn init_logger(default_level: \u0026str) {\n    let env = Env::default().filter_or(\"LOG_LEVEL\", default_level); // Set default log level from environment or use provided level\n    Builder::from_env(env) // Build the logger from environment settings\n        .filter_module(\"tiktoklive\", LevelFilter::Debug) // Set log level for tiktoklive module\n        .init(); // Initialize the logger\n}\n\n// Function to configure the TikTok live settings\nfn configure(settings: \u0026mut TikTokLiveSettings) {\n    settings.http_data.time_out = Duration::from_secs(12); // Set HTTP timeout to 12 seconds\n    settings.sign_api_key = \"\".to_string(); // Provide your own api key here\n}\n\n// Function to configure the TikTok live settings with cookies for authentication\nfn configure_with_cookies(settings: \u0026mut TikTokLiveSettings) {\n    settings.http_data.time_out = Duration::from_secs(12); // Set HTTP timeout to 12 seconds\n    settings.sign_api_key = \"\".to_string(); // Provide your own api key here\n    let contents = \"\"; // Placeholder for cookies\n    settings\n        .http_data\n        .headers\n        .insert(\"Cookie\".to_string(), contents.to_string());\n    // Insert cookies into HTTP headers\n}\n\n// Function to create a TikTok live client for the given username\nfn create_client(user_name: \u0026str) -\u003e TikTokLiveClient {\n    TikTokLive::new_client(user_name) // Create a new client\n        .configure(configure) // Configure the client\n        .on_event(handle_event) // Set the event handler\n        .build() // Build the client\n}\n\n// Function to create a TikTok live client with cookies for the given username\nfn create_client_with_cookies(user_name: \u0026str) -\u003e TikTokLiveClient {\n    TikTokLive::new_client(user_name) // Create a new client\n        .configure(configure_with_cookies) // Configure the client with cookies\n        .on_event(handle_event) // Set the event handler\n        .build() // Build the client\n}\n```\n\n## Library errors table\n\nYou can catch errors on events with\n\n```rust\nuse tiktoklive::LibError;\n\nif let Err(e) = client.connect().await {\n    match e {\n        LibError::UserFieldMissing =\u003e {\n            println!(\"User field is missing\");\n        }\n        _ =\u003e {\n            eprintln!(\"Error connecting to TikTok Live: {}\", e);\n        }\n    }\n}\n```\n\n| Error type                | Description                                                     |\n| ------------------------- | --------------------------------------------------------------- |\n| RoomIDFieldMissing        | Room ID field is missing, contact developer                     |\n| UserFieldMissing          | User field is missing                                           |\n| UserDataFieldMissing      | User data field is missing                                      |\n| LiveDataFieldMissing      | Live data field is missing                                      |\n| JsonParseError            | Error parsing JSON                                              |\n| UserMessageFieldMissing   | User message field is missing                                   |\n| ParamsError               | Params error                                                    |\n| UserStatusFieldMissing    | User status field is missing                                    |\n| LiveStatusFieldMissing    | Live status field is missing                                    |\n| TitleFieldMissing         | Title field is missing                                          |\n| UserCountFieldMissing     | User count field is missing                                     |\n| StatsFieldMissing         | Stats field is missing                                          |\n| LikeCountFieldMissing     | Like count is missing                                           |\n| TotalUserFieldMissing     | Total user field is missing                                     |\n| LiveRoomFieldMissing      | Live room field is missing                                      |\n| StartTimeFieldMissing     | Start time field is missing                                     |\n| UserNotFound              | User not found                                                  |\n| HostNotOnline             | Live stream for host is not online!, current status HostOffline |\n| InvalidHost               | Invalid host in WebSocket URL                                   |\n| WebSocketConnectFailed    | Failed to connect to WebSocket                                  |\n| PushFrameParseError       | Unable to read push frame                                       |\n| WebcastResponseParseError | Unable to read webcast response                                 |\n| AckPacketSendError        | Unable to send ack packet                                       |\n| HttpRequestFailed         | HTTP request failed                                             |\n| UrlSigningFailed          | URL signing failed                                              |\n| HeaderNotReceived         | Header was not received                                         |\n| BytesParseError           | Unable to parse bytes to Push Frame                             |\n\n## Contributing\n\nYour improvements are welcome! Feel free to open an \u003ca href=\"https://github.com/jwdeveloper/TikTok-Live-Java/issues\"\u003eissue\u003c/a\u003e or \u003ca href=\"https://github.com/jwdeveloper/TikTok-Live-Java/pulls\"\u003epull request\u003c/a\u003e.\n\n## Contributors\n\n[Zmole Cristian](https://github.com/ZmoleCristian)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwdeveloper%2Ftiktokliverust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwdeveloper%2Ftiktokliverust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwdeveloper%2Ftiktokliverust/lists"}