Skip to main content

bpi_rs/live/
live_stream.rs

1use serde::{ Deserialize, Serialize };
2
3use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
4
5#[derive(Debug, Serialize, Clone, Deserialize)]
6pub struct QualityDescription {
7    /// 画质代码
8    pub qn: i32,
9    /// 该代码对应的画质名称
10    pub desc: String,
11}
12
13#[derive(Debug, Serialize, Clone, Deserialize)]
14pub struct LiveStreamUrl {
15    /// 直播流url
16    pub url: String,
17    /// 服务器线路序号
18    pub order: i32,
19    /// 作用尚不明确
20    pub stream_type: i32,
21    /// 作用尚不明确
22    pub p2p_type: i32,
23}
24
25#[derive(Debug, Serialize, Clone, Deserialize)]
26pub struct LiveStreamData {
27    /// 当前画质代码qn
28    pub current_quality: i32,
29    /// 可选画质数参数
30    pub accept_quality: Vec<String>,
31    /// 当前画质代码quality
32    pub current_qn: i32,
33    /// 可选画质参数quality
34    pub quality_description: Vec<QualityDescription>,
35    /// 直播流url组
36    pub durl: Vec<LiveStreamUrl>,
37}
38
39impl BpiClient {
40    /// 根据真实直播间号获取直播视频流
41    ///
42    /// # 参数
43    /// * `cid` - 目标真实直播间号(必要),直播间的 room_id(非短号)。
44    ///
45    /// * `platform` - 播放平台(非必要,默认 `web` 即 http-flv 方式)。
46    ///   - `"h5"`  → HLS 方式
47    ///   - `"web"` → HTTP-FLV 方式
48    ///
49    /// * `quality` - 画质(非必要,与 `qn` 二选一)。
50    ///   - `2` → 流畅
51    ///   - `3` → 高清
52    ///   - `4` → 原画
53    ///
54    /// * `qn` - 画质(非必要,与 `quality` 二选一)。
55    ///   - `80` → 流畅
56    ///   - `150` → 高清
57    ///   - `250` → 超清
58    ///   - `400` → 蓝光
59    ///   - `10000` → 原画
60    ///   - `20000` → 4K
61    ///   - `25000` → 默认
62    ///   - `30000` → 杜比
63    /// # 文档
64    /// [查看API文档](https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/live)
65    pub async fn live_stream(
66        &self,
67        cid: i64,
68        platform: Option<&str>,
69        quality: Option<i32>,
70        qn: Option<i32>
71    ) -> Result<BpiResponse<LiveStreamData>, BpiError> {
72        let mut query = vec![("cid", cid.to_string())];
73
74        if let Some(platform) = platform {
75            query.push(("platform", platform.to_string()));
76        }
77
78        if let Some(quality) = quality {
79            query.push(("quality", quality.to_string()));
80        }
81
82        if let Some(qn) = qn {
83            query.push(("qn", qn.to_string()));
84        }
85
86        self
87            .get("https://api.live.bilibili.com/room/v1/Room/playUrl")
88            .query(&query)
89            .send_bpi("获取直播视频流").await
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[tokio::test]
98    async fn test_get_live_stream() {
99        let bpi = BpiClient::new();
100        let resp = bpi.live_stream(14073662, Some("web"), None, Some(10000)).await.unwrap();
101        tracing::info!("{:?}", resp);
102    }
103}