A Multi-Platform Live Stream Parser Library — Rust port of streamget
streamget-rs is a Rust library for fetching and parsing live stream information across multiple platforms. It provides a unified interface (LiveStream trait) that each platform implements, returning a consistent StreamData output model.
This crate is designed to be used as a dependency for video stream recording tools (e.g. dy-rec-rs).
| Platform | Struct | URL Example |
|---|---|---|
| 抖音 (Douyin) | DouyinLiveStream |
https://live.douyin.com/123456 |
| 哔哩哔哩 (Bilibili) | BilibiliLiveStream |
https://live.bilibili.com/26066074 |
| Twitch | TwitchLiveStream |
https://www.twitch.tv/streamer |
| Youtube | YoutubeLiveStream |
https://www.youtube.com/watch?v=xxxx |
| 虎牙直播 (Huya) | HuyaLiveStream |
https://www.huya.com/123456 |
| 快手直播 (Kuaishou) | KwaiLiveStream |
https://live.kuaishou.com/u/xxx |
| 斗鱼直播 (Douyu) | DouyuLiveStream |
https://www.douyu.com/123456 |
| TikTok | TikTokLiveStream |
https://www.tiktok.com/@user/live |
| 小红书 (RedNote) | RedNoteLiveStream |
https://www.xiaohongshu.com/... |
Add to your Cargo.toml:
[dependencies]
streamget = { path = "../streamget-rs" }
tokio = { version = "1", features = ["full"] }use streamget::base::LiveStream;
use streamget::platforms::DouyinLiveStream;
#[tokio::main]
async fn main() -> streamget::Result<()> {
// Create a stream fetcher (optional: proxy, cookies)
let stream = DouyinLiveStream::new(None, None, None);
// Step 1: Fetch room metadata
let url = "https://live.douyin.com/123456";
let room_data = stream.fetch_web_stream_data(url, true).await?;
// Step 2: Fetch stream URL by quality
let result = stream.fetch_stream_url(&room_data, None).await?;
if result.is_live() {
println!("Anchor: {}", result.anchor_name.as_deref().unwrap_or(""));
println!("Title: {}", result.title.as_deref().unwrap_or(""));
if let Some(url) = &result.record_url {
println!("Stream URL: {}", url);
}
} else {
println!("Not live.");
}
Ok(())
}use streamget::base::LiveStream;
use streamget::platforms::*;
// Bilibili
let bilibili = BilibiliLiveStream::new(None, None);
// Twitch (with optional access token)
let twitch = TwitchLiveStream::new(Some("127.0.0.1:7890"), None, None);
// TikTok (with HEVC preference)
let tiktok = TikTokLiveStream::new(None, None, true);
// All platforms implement the same LiveStream trait
let platforms: Vec<Box<dyn LiveStream>> = vec![
Box::new(bilibili),
Box::new(twitch),
Box::new(tiktok),
];Quality levels are unified across all platforms:
| Code | Name | Index |
|---|---|---|
| OD | Original | 0 |
| UHD | Ultra HD | 1 |
| HD | High Definition | 2 |
| SD | Standard Definition | 3 |
| LD | Low Definition | 4 |
// Use quality string
stream.fetch_stream_url(&data, Some("HD")).await?;
// Use quality index
stream.fetch_stream_url(&data, Some("2")).await?;
// Default (highest quality)
stream.fetch_stream_url(&data, None).await?;The examples/ directory contains runnable examples for each platform:
| Example | Platform | Description |
|---|---|---|
fetch_douyin_stream |
抖音 | Basic two-step fetch with OD quality |
fetch_bilibili_stream |
哔哩哔哩 | Room data + stream URL with UHD quality |
fetch_twitch_stream |
Twitch | Proxy usage + HD quality selection |
fetch_youtube_stream |
YouTube | Video data fetch + default quality |
fetch_huya_stream |
虎牙 | Room data + OD quality |
fetch_kuaishou_stream |
快手 | Room data + OD quality |
fetch_douyu_stream |
斗鱼 | Multi-step MD5 auth + HD quality |
fetch_tiktok_stream |
TikTok | HEVC support + OD quality |
fetch_rednote_stream |
小红书 | Profile URL + default quality |
fetch_with_proxy |
Twitch (advanced) | Proxy + cookies + detailed field access |
fetch_all_platforms |
All 9 platforms | Trait dispatch across all platforms |
Run any example with:
cargo run --example fetch_douyin_stream
cargo run --example fetch_bilibili_stream
cargo run --example fetch_all_platforms
# ... etcstreamget-rs/
├── Cargo.toml
├── src/
│ ├── lib.rs # Library entry point
│ ├── base.rs # LiveStream trait + BaseLiveStream
│ ├── data.rs # StreamData unified model
│ ├── error.rs # StreamError error types
│ ├── http.rs # HTTP client (reqwest-based)
│ ├── utils.rs # Utility functions
│ └── platforms/
│ ├── mod.rs # Platform module aggregator
│ ├── douyin/ # 抖音 (with SM3/RC4 a_bogus signing)
│ ├── bilibili/ # 哔哩哔哩
│ ├── twitch/ # Twitch (GraphQL API)
│ ├── youtube/ # Youtube
│ ├── huya/ # 虎牙直播
│ ├── kuaishou/ # 快手直播
│ ├── douyu/ # 斗鱼直播
│ ├── tiktok/ # TikTok
│ └── rednote/ # 小红书
-
LiveStreamtrait — The interface all platforms implement. Two methods:fetch_web_stream_data(url, process_data)— Fetch room metadata (anchor name, live status, title)fetch_stream_url(json_data, video_quality)— Select and return the stream URL by quality
-
BaseLiveStreamstruct — Shared utility methods (headers, request options, M3U8 parsing, quality mapping) -
StreamDatastruct — Unified output model with fields:platform,anchor_name,is_live,title,quality,m3u8_url,flv_url,record_url,live_url,extra -
StreamErrorenum — Unified error type covering HTTP, JSON, URL, regex, IO, platform-specific, risk control, and not-live errors
All platforms follow a two-phase design:
-
Phase 1 —
fetch_web_stream_data: Fetch room metadata from the platform's web API. Returns JSON with anchor name, live status, title, and (optionally) available stream URLs. -
Phase 2 —
fetch_stream_url: Based on the metadata from phase 1 and the requested quality, select and return the final stream URL wrapped in aStreamData.
This separation allows the caller to inspect room metadata before deciding which quality to request.
The Douyin platform requires an a_bogus signature parameter for API requests. This is implemented in pure Rust (ab_sign.rs) using:
- SM3 national cryptography hash algorithm
- RC4 stream cipher (character-level implementation)
- Custom Base64 encoding with 5 custom alphabets (s0-s4)
- Uses
reqwestwith HTTP/2 support - SSL verification disabled by default (for compatibility with various platforms)
- Proxy support via
RequestOptions - Cookie support for authenticated requests
- Uses
thiserrorfor ergonomic error derivation - All fallible operations return
Result<T>(alias forstd::result::Result<T, StreamError>) - Platform-specific errors (risk control, not live, unsupported URL) are explicitly typed
MIT
特别感谢以下开源项目和技术的支持: