Skip to main content

bpi_rs/video/
online.rs

1//! 视频在线人数相关接口
2//!
3//! [查看 API 文档](https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/video)
4use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
5use serde::{ Deserialize, Serialize };
6
7// --- 响应数据结构体 ---
8
9/// 在线人数数据控制
10#[derive(Debug, Clone, Deserialize, Serialize)]
11pub struct OnlineTotalShowSwitch {
12    /// 展示所有终端总计人数
13    pub total: bool,
14    /// 展示web端实时在线人数
15    pub count: bool,
16}
17
18/// 视频在线人数响应数据
19#[derive(Debug, Clone, Deserialize, Serialize)]
20pub struct OnlineTotalResponseData {
21    /// 所有终端总计人数
22    pub total: String,
23    /// web端实时在线人数
24    pub count: String,
25    /// 数据显示控制
26    pub show_switch: OnlineTotalShowSwitch,
27}
28
29impl BpiClient {
30    /// 获取视频在线人数(web端)
31    ///
32    /// # 文档
33    /// [查看API文档](https://github.com/Yuelioi/bilibili-API-collect/tree/cfc5fddcc8a94b74d91970bb5b4eaeb349addc47/docs/video/online.md)
34    ///
35    /// # 参数
36    /// | 名称    | 类型         | 说明                 |
37    /// | ------- | ------------| -------------------- |
38    /// | `aid`   | `Option<u64>` | 稿件 avid,可选      |
39    /// | `bvid`  | `Option<&str>`| 稿件 bvid,可选      |
40    /// | `cid`   | u64         | 视频 cid             |
41    ///
42    /// `aid` 和 `bvid` 必须提供一个。
43    pub async fn video_online_total(
44        &self,
45        aid: Option<u64>,
46        bvid: Option<&str>,
47        cid: u64
48    ) -> Result<BpiResponse<OnlineTotalResponseData>, BpiError> {
49        if aid.is_none() && bvid.is_none() {
50            return Err(BpiError::parse("必须提供 aid 或 bvid"));
51        }
52
53        let mut req = self
54            .get("https://api.bilibili.com/x/player/online/total")
55            .query(&[("cid", &cid.to_string())]);
56
57        if let Some(a) = aid {
58            req = req.query(&[("aid", &a.to_string())]);
59        }
60        if let Some(b) = bvid {
61            req = req.query(&[("bvid", b)]);
62        }
63
64        req.send_bpi("获取视频在线人数").await
65    }
66}
67
68// --- 测试模块 ---
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use tracing::info;
74
75    // 假设这是一个已知的视频
76    const TEST_AID: u64 = 759949922;
77    const TEST_CID: u64 = 392402545;
78    const TEST_BVID: &str = "BV1y64y1q757";
79
80    #[tokio::test]
81    async fn test_video_online_total_by_aid() -> Result<(), BpiError> {
82        let bpi = BpiClient::new();
83        let resp = bpi.video_online_total(Some(TEST_AID), None, TEST_CID).await?;
84
85        let data = resp.into_data()?;
86
87        info!("视频在线人数: {:?}", data);
88        assert!(!data.count.is_empty());
89        assert!(!data.total.is_empty());
90
91        Ok(())
92    }
93
94    #[tokio::test]
95    async fn test_video_online_total_by_bvid() -> Result<(), BpiError> {
96        let bpi = BpiClient::new();
97        let resp = bpi.video_online_total(None, Some(TEST_BVID), TEST_CID).await?;
98
99        let data = resp.into_data()?;
100
101        info!("视频在线人数: {:?}", data);
102
103        assert!(!data.count.is_empty());
104        assert!(!data.total.is_empty());
105
106        Ok(())
107    }
108}