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    /// 文档: https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/live
64    pub async fn live_stream(
65        &self,
66        cid: i64,
67        platform: Option<&str>,
68        quality: Option<i32>,
69        qn: Option<i32>,
70    ) -> Result<BpiResponse<LiveStreamData>, BpiError> {
71        let mut query = vec![("cid", cid.to_string())];
72
73        if let Some(platform) = platform {
74            query.push(("platform", platform.to_string()));
75        }
76
77        if let Some(quality) = quality {
78            query.push(("quality", quality.to_string()));
79        }
80
81        if let Some(qn) = qn {
82            query.push(("qn", qn.to_string()));
83        }
84
85        self.get("https://api.live.bilibili.com/room/v1/Room/playUrl")
86            .query(&query)
87            .send_bpi("获取直播视频流")
88            .await
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    #[tokio::test]
97    async fn test_get_live_stream() {
98        let bpi = BpiClient::new();
99        let resp = bpi
100            .live_stream(14073662, Some("web"), None, Some(10000))
101            .await
102            .unwrap();
103        tracing::info!("{:?}", resp);
104    }
105}